diff --git a/Gopkg.lock b/Gopkg.lock index d7e39752628439460aa8c3a026c00903ffe5de30..ab8a14a5b6a15522ff240dea6a783264b227c6ed 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -124,6 +124,12 @@ revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" version = "v1.2.0" +[[projects]] + branch = "master" + name = "github.com/howeyc/gopass" + packages = ["."] + revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8" + [[projects]] name = "github.com/imdario/mergo" packages = ["."] @@ -349,22 +355,6 @@ revision = "b4c50a2b199d93b13dc15e78929cfb23bfdf21ab" version = "v1.1.1" -[[projects]] - name = "github.com/wayn3h0/go-uuid" - packages = [ - ".", - "internal/dcesecurity", - "internal/layout", - "internal/namebased", - "internal/namebased/md5", - "internal/namebased/sha1", - "internal/random", - "internal/timebased", - "internal/version" - ] - revision = "1622016a49b50139b1ac263e6ef2804226b3dec6" - version = "v2.2.1" - [[projects]] branch = "master" name = "golang.org/x/crypto" @@ -376,9 +366,12 @@ "nacl/secretbox", "openpgp/armor", "openpgp/errors", + "pbkdf2", "poly1305", "ripemd160", - "salsa20/salsa" + "salsa20/salsa", + "scrypt", + "ssh/terminal" ] revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e" @@ -399,7 +392,10 @@ [[projects]] branch = "master" name = "golang.org/x/sys" - packages = ["unix"] + packages = [ + "unix", + "windows" + ] revision = "3b87a42e500a6dc65dae1a55d0b641295971163e" [[projects]] @@ -474,6 +470,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "a434dee26127011ec236d80b300051d321f012ce49cd77b1112034c15e54ac3e" + inputs-digest = "2a58c6e6ec7d2792452873c5cb57032cc6d1a4750345647f562a8c9e8bc1e0b4" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Makefile b/Makefile index 87ea9c00f2fc86a3c0d90ef1f44cd900512008c1..649eb0996a05b3c240751e5e99f8da386b1a8a18 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,9 @@ megacheck: @go get honnef.co/go/tools/cmd/megacheck @for pkg in ${PACKAGES_NOVENDOR}; do megacheck "$$pkg"; done +keys/pbkeys/keys.pb.go: keys/pbkeys/keys.proto + @protoc -I ./keys/pbkeys keys/pbkeys/keys.proto --go_out=plugins=grpc:keys/pbkeys + ### Dependency management for github.com/hyperledger/burrow # erase vendor wipes the full vendor directory @@ -153,10 +156,12 @@ docker_build: check commit_hash test: check @go test ${PACKAGES_NOVENDOR} +.PHONY: test_keys +test_keys: build_db + burrow_bin="${REPO}/bin/burrow" keys/test.sh + .PHONY: test_integration -test_integration: - @go get github.com/monax/bosmarmot/keys/cmd/monax-keys - @go test -tags integration ./keys/integration +test_integration: test_keys @go test -tags integration ./rpc/v0/integration @go test -tags integration ./rpc/tm/integration diff --git a/README.md b/README.md index 1ff2670552b7e9bd5b9c16073e18b0d17eab619e..5fc0fc853096d703d8ad6445a1c7a2fe15a78163 100644 --- a/README.md +++ b/README.md @@ -42,18 +42,6 @@ The end result will be a `burrow.toml` that will be read in from your current wo ### Configuration -#### Install monax-keys -Monax-keys is our key-signing daemon. In a future release this will be merged with Burrow and will support a GPG backend -in addition to the development mode that monax-keys currently supplies. - -We need to run monax-keys so that `burrow configure` can generate keys for us in the following step. -```shell -# Install monax-keys -go get -u github.com/monax/bosmarmot/keys/cmd/monax-keys -# run monax-keys server in background -monax-keys server & -``` - #### Configure Burrow The quick-and-dirty one-liner looks like: diff --git a/account/account.go b/account/account.go index 725eda71a79ebc99cbf849ece47cee5f22f877a1..0985f38d77905b3c4280b1529f4106678ce80251 100644 --- a/account/account.go +++ b/account/account.go @@ -18,36 +18,20 @@ import ( "bytes" "encoding/json" "fmt" - "io" "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" ptypes "github.com/hyperledger/burrow/permission/types" "github.com/tendermint/go-wire" ) -var GlobalPermissionsAddress = Address(binary.Zero160) - -// Signable is an interface for all signable things. -// It typically removes signatures before serializing. -type Signable interface { - WriteSignBytes(chainID string, w io.Writer, n *int, err *error) -} - -// SignBytes is a convenience method for getting the bytes to sign of a Signable. -func SignBytes(chainID string, o Signable) []byte { - buf, n, err := new(bytes.Buffer), new(int), new(error) - o.WriteSignBytes(chainID, buf, n, err) - if *err != nil { - panic(fmt.Sprintf("could not write sign bytes for a signable: %s", *err)) - } - return buf.Bytes() -} +var GlobalPermissionsAddress = crypto.Address(binary.Zero160) type Addressable interface { // Get the 20 byte EVM address of this account - Address() Address + Address() crypto.Address // Public key from which the Address is derived - PublicKey() PublicKey + PublicKey() crypto.PublicKey } // The default immutable interface to an account @@ -75,7 +59,7 @@ type Account interface { type MutableAccount interface { Account // Set public key (needed for lazy initialisation), should also set the dependent address - SetPublicKey(pubKey PublicKey) MutableAccount + SetPublicKey(pubKey crypto.PublicKey) MutableAccount // Subtract amount from account balance (will panic if amount is greater than balance) SubtractFromBalance(amount uint64) (MutableAccount, error) // Add amount to balance (will panic if amount plus balance is a uint64 overflow) @@ -99,8 +83,8 @@ type MutableAccount interface { // ConcreteAccount is the canonical serialisation and bash-in-place object for an Account type ConcreteAccount struct { - Address Address - PublicKey PublicKey + Address crypto.Address + PublicKey crypto.PublicKey Sequence uint64 Balance uint64 Code Bytecode @@ -108,7 +92,7 @@ type ConcreteAccount struct { Permissions ptypes.AccountPermissions } -func NewConcreteAccount(pubKey PublicKey) ConcreteAccount { +func NewConcreteAccount(pubKey crypto.PublicKey) ConcreteAccount { return ConcreteAccount{ Address: pubKey.Address(), PublicKey: pubKey, @@ -122,7 +106,7 @@ func NewConcreteAccount(pubKey PublicKey) ConcreteAccount { } func NewConcreteAccountFromSecret(secret string) ConcreteAccount { - return NewConcreteAccount(PrivateKeyFromSecret(secret).PublicKey()) + return NewConcreteAccount(crypto.PrivateKeyFromSecret(secret, crypto.CurveTypeEd25519).GetPublicKey()) } // Return as immutable Account @@ -230,11 +214,11 @@ type concreteAccountWrapper struct { var _ Account = concreteAccountWrapper{} -func (caw concreteAccountWrapper) Address() Address { +func (caw concreteAccountWrapper) Address() crypto.Address { return caw.ConcreteAccount.Address } -func (caw concreteAccountWrapper) PublicKey() PublicKey { +func (caw concreteAccountWrapper) PublicKey() crypto.PublicKey { return caw.ConcreteAccount.PublicKey } @@ -273,7 +257,7 @@ func (caw concreteAccountWrapper) MarshalJSON() ([]byte, error) { // Account mutation via MutableAccount interface var _ MutableAccount = concreteAccountWrapper{} -func (caw concreteAccountWrapper) SetPublicKey(pubKey PublicKey) MutableAccount { +func (caw concreteAccountWrapper) SetPublicKey(pubKey crypto.PublicKey) MutableAccount { caw.ConcreteAccount.PublicKey = pubKey addressFromPubKey := pubKey.Address() // We don't want the wrong public key to take control of an account so we panic here diff --git a/account/account_test.go b/account/account_test.go index aaffb2ff882fb8b60a85e2160e40138f2cf8ce19..ca3e41fdba161931d24a8610ded01aee33301110 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -21,11 +21,11 @@ import ( "fmt" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/permission" "github.com/hyperledger/burrow/permission/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" ) @@ -36,7 +36,7 @@ func TestAddress(t *testing.T) { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, } - addr, err := AddressFromBytes(bs) + addr, err := crypto.AddressFromBytes(bs) assert.NoError(t, err) word256 := addr.Word256() leadingZeroes := []byte{ @@ -45,7 +45,7 @@ func TestAddress(t *testing.T) { 0, 0, 0, 0, } assert.Equal(t, leadingZeroes, word256[:12]) - addrFromWord256 := AddressFromWord256(word256) + addrFromWord256 := crypto.AddressFromWord256(word256) assert.Equal(t, bs, addrFromWord256[:]) assert.Equal(t, addr, addrFromWord256) } @@ -118,11 +118,10 @@ func TestMarshalJSON(t *testing.T) { acc := concreteAcc.Account() bs, err := json.Marshal(acc) - pubKeyEd25519 := concreteAcc.PublicKey.PubKey.Unwrap().(crypto.PubKeyEd25519) - expected := fmt.Sprintf(`{"Address":"%s","PublicKey":{"type":"ed25519","data":"%X"},`+ + expected := fmt.Sprintf(`{"Address":"%s","PublicKey":{"CurveType":"ed25519","PublicKey":"%s"},`+ `"Sequence":0,"Balance":0,"Code":"3C172D","StorageRoot":"",`+ `"Permissions":{"Base":{"Perms":0,"SetBit":0},"Roles":[]}}`, - concreteAcc.Address, pubKeyEd25519[:]) + concreteAcc.Address, concreteAcc.PublicKey) assert.Equal(t, expected, string(bs)) assert.NoError(t, err) } diff --git a/account/crypto.go b/account/crypto.go deleted file mode 100644 index 942901a39c65cf55b970e91aba8cf5f82cba8977..0000000000000000000000000000000000000000 --- a/account/crypto.go +++ /dev/null @@ -1,251 +0,0 @@ -package account - -import ( - "bytes" - "crypto/rand" - "crypto/sha256" - "fmt" - "io" - - "github.com/tendermint/go-crypto" - "golang.org/x/crypto/ed25519" -) - -// The types in this file allow us to control serialisation of keys and signatures, as well as the interface -// exposed regardless of crypto library - -type Signer interface { - Sign(msg []byte) (Signature, error) -} - -// PublicKey -type PublicKey struct { - crypto.PubKey `json:"unwrap"` -} - -func PublicKeyFromGoCryptoPubKey(pubKey crypto.PubKey) (PublicKey, error) { - _, err := AddressFromBytes(pubKey.Address()) - if err != nil { - return PublicKey{}, fmt.Errorf("could not make valid address from public key %v: %v", pubKey, err) - } - return PublicKey{ - PubKey: pubKey, - }, nil -} - -// Currently this is a stub that reads the raw bytes returned by key_client and returns -// an ed25519 public key. -func PublicKeyFromBytes(bs []byte) (PublicKey, error) { - //TODO: read a typed representation (most likely JSON) and do the right thing here - // Only supports ed25519 currently so no switch on signature scheme - pubKeyEd25519 := crypto.PubKeyEd25519{} - if len(bs) != len(pubKeyEd25519) { - return PublicKey{}, fmt.Errorf("bytes passed have length %v by ed25519 public keys have %v bytes", - len(bs), len(pubKeyEd25519)) - } - copy(pubKeyEd25519[:], bs) - return PublicKeyFromGoCryptoPubKey(pubKeyEd25519.Wrap()) -} - -// Returns a copy of the raw untyped public key bytes -func (pk PublicKey) RawBytes() []byte { - switch pubKey := pk.PubKey.Unwrap().(type) { - case crypto.PubKeyEd25519: - pubKeyCopy := crypto.PubKeyEd25519{} - copy(pubKeyCopy[:], pubKey[:]) - return pubKeyCopy[:] - case crypto.PubKeySecp256k1: - pubKeyCopy := crypto.PubKeySecp256k1{} - copy(pubKeyCopy[:], pubKey[:]) - return pubKeyCopy[:] - default: - return nil - } -} - -func (pk PublicKey) VerifyBytes(msg []byte, signature Signature) bool { - return pk.PubKey.VerifyBytes(msg, signature.Signature) -} - -func (pk PublicKey) Address() Address { - // We check this on initialisation to avoid this panic, but returning an error here is ugly and caching - // the address on PublicKey initialisation breaks go-wire serialisation since with unwrap we can only have one field. - // We can do something better with better serialisation - return MustAddressFromBytes(pk.PubKey.Address()) -} - -func (pk PublicKey) MarshalJSON() ([]byte, error) { - return pk.PubKey.MarshalJSON() -} - -func (pk *PublicKey) UnmarshalJSON(data []byte) error { - return pk.PubKey.UnmarshalJSON(data) -} - -func (pk PublicKey) MarshalText() ([]byte, error) { - return pk.MarshalJSON() -} - -func (pk *PublicKey) UnmarshalText(text []byte) error { - return pk.UnmarshalJSON(text) -} - -// PrivateKey - -type PrivateKey struct { - crypto.PrivKey `json:"unwrap"` -} - -func PrivateKeyFromGoCryptoPrivKey(privKey crypto.PrivKey) (PrivateKey, error) { - _, err := PublicKeyFromGoCryptoPubKey(privKey.PubKey()) - if err != nil { - return PrivateKey{}, fmt.Errorf("could not create public key from private key: %v", err) - } - return PrivateKey{ - PrivKey: privKey, - }, nil -} - -func PrivateKeyFromSecret(secret string) PrivateKey { - hasher := sha256.New() - hasher.Write(([]byte)(secret)) - // No error from a buffer - privateKey, _ := GeneratePrivateKey(bytes.NewBuffer(hasher.Sum(nil))) - return privateKey -} - -// Generates private key from a source of random bytes, if randomReader is nil crypto/rand.Reader is useds -func GeneratePrivateKey(randomReader io.Reader) (PrivateKey, error) { - if randomReader == nil { - randomReader = rand.Reader - } - _, ed25519PrivateKey, err := ed25519.GenerateKey(randomReader) - if err != nil { - return PrivateKey{}, err - } - return Ed25519PrivateKeyFromRawBytes(ed25519PrivateKey) -} - -// Creates an ed25519 key from the raw private key bytes -func Ed25519PrivateKeyFromRawBytes(privKeyBytes []byte) (PrivateKey, error) { - privKeyEd25519 := crypto.PrivKeyEd25519{} - if len(privKeyBytes) != len(privKeyEd25519) { - return PrivateKey{}, fmt.Errorf("bytes passed have length %v by ed25519 private keys have %v bytes", - len(privKeyBytes), len(privKeyEd25519)) - } - err := EnsureEd25519PrivateKeyCorrect(privKeyBytes) - if err != nil { - return PrivateKey{}, err - } - copy(privKeyEd25519[:], privKeyBytes) - return PrivateKeyFromGoCryptoPrivKey(privKeyEd25519.Wrap()) -} - -// Ensures the last 32 bytes of the ed25519 private key is the public key derived from the first 32 private bytes -func EnsureEd25519PrivateKeyCorrect(candidatePrivateKey ed25519.PrivateKey) error { - if len(candidatePrivateKey) != ed25519.PrivateKeySize { - return fmt.Errorf("ed25519 key has size %v but %v bytes passed as key", ed25519.PrivateKeySize, - len(candidatePrivateKey)) - } - _, derivedPrivateKey, err := ed25519.GenerateKey(bytes.NewBuffer(candidatePrivateKey)) - if err != nil { - return err - } - if !bytes.Equal(derivedPrivateKey, candidatePrivateKey) { - return fmt.Errorf("ed25519 key generated from prefix of %X should equal %X, but is %X", - candidatePrivateKey, candidatePrivateKey, derivedPrivateKey) - } - return nil -} - -func (pk PrivateKey) PublicKey() PublicKey { - publicKey, err := PublicKeyFromGoCryptoPubKey(pk.PrivKey.PubKey()) - if err != nil { - // We check this on initialisation to avoid this panic, but returning an error here is ugly and caching - // the public key on PrivateKey on initialisation breaks go-wire. We can do something better with better serialisation - panic(fmt.Errorf("error making public key from private key: %v", publicKey)) - } - return publicKey -} - -// Returns a copy of the raw untyped private key bytes -func (pk PrivateKey) RawBytes() []byte { - switch privKey := pk.PrivKey.Unwrap().(type) { - case crypto.PrivKeyEd25519: - privKeyCopy := crypto.PrivKeyEd25519{} - copy(privKeyCopy[:], privKey[:]) - return privKeyCopy[:] - case crypto.PrivKeySecp256k1: - privKeyCopy := crypto.PrivKeySecp256k1{} - copy(privKeyCopy[:], privKey[:]) - return privKeyCopy[:] - default: - return nil - } -} - -func (pk PrivateKey) Sign(msg []byte) (Signature, error) { - return Signature{Signature: pk.PrivKey.Sign(msg)}, nil -} - -func (pk PrivateKey) MarshalJSON() ([]byte, error) { - return pk.PrivKey.MarshalJSON() -} - -func (pk *PrivateKey) UnmarshalJSON(data []byte) error { - return pk.PrivKey.UnmarshalJSON(data) -} - -func (pk PrivateKey) MarshalText() ([]byte, error) { - return pk.MarshalJSON() -} - -func (pk *PrivateKey) UnmarshalText(text []byte) error { - return pk.UnmarshalJSON(text) -} - -// Signature - -type Signature struct { - crypto.Signature `json:"unwrap"` -} - -func SignatureFromGoCryptoSignature(signature crypto.Signature) Signature { - return Signature{Signature: signature} -} - -// Currently this is a stub that reads the raw bytes returned by key_client and returns -// an ed25519 signature. -func SignatureFromBytes(bs []byte) (Signature, error) { - //TODO: read a typed representation (most likely JSON) and do the right thing here - // Only supports ed25519 currently so no switch on signature scheme - signatureEd25519 := crypto.SignatureEd25519{} - if len(bs) != len(signatureEd25519) { - return Signature{}, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes", - len(bs), len(signatureEd25519)) - } - copy(signatureEd25519[:], bs) - return Signature{ - Signature: signatureEd25519.Wrap(), - }, nil -} - -func (s Signature) GoCryptoSignature() crypto.Signature { - return s.Signature -} - -func (s Signature) MarshalJSON() ([]byte, error) { - return s.Signature.MarshalJSON() -} - -func (s *Signature) UnmarshalJSON(data []byte) error { - return s.Signature.UnmarshalJSON(data) -} - -func (s Signature) MarshalText() ([]byte, error) { - return s.MarshalJSON() -} - -func (s *Signature) UnmarshalText(text []byte) error { - return s.UnmarshalJSON(text) -} diff --git a/account/private_account.go b/account/private_account.go index 3ca56cd7f0852ed348c08f10b972c23557090790..8f76a5c41c049b8de1761e1ea9c5aca53b34cc96 100644 --- a/account/private_account.go +++ b/account/private_account.go @@ -17,24 +17,25 @@ package account import ( "fmt" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) type AddressableSigner interface { Addressable - Signer + crypto.Signer } type PrivateAccount interface { AddressableSigner - PrivateKey() PrivateKey + PrivateKey() crypto.PrivateKey } // type ConcretePrivateAccount struct { - Address Address - PublicKey PublicKey - PrivateKey PrivateKey + Address crypto.Address + PublicKey crypto.PublicKey + PrivateKey crypto.PrivateKey } type concretePrivateAccountWrapper struct { @@ -60,15 +61,15 @@ func AsConcretePrivateAccount(privateAccount PrivateAccount) *ConcretePrivateAcc } } -func (cpaw concretePrivateAccountWrapper) Address() Address { +func (cpaw concretePrivateAccountWrapper) Address() crypto.Address { return cpaw.ConcretePrivateAccount.Address } -func (cpaw concretePrivateAccountWrapper) PublicKey() PublicKey { +func (cpaw concretePrivateAccountWrapper) PublicKey() crypto.PublicKey { return cpaw.ConcretePrivateAccount.PublicKey } -func (cpaw concretePrivateAccountWrapper) PrivateKey() PrivateKey { +func (cpaw concretePrivateAccountWrapper) PrivateKey() crypto.PrivateKey { return cpaw.ConcretePrivateAccount.PrivateKey } @@ -82,18 +83,10 @@ func (pa ConcretePrivateAccount) PrivateAccount() PrivateAccount { return concretePrivateAccountWrapper{ConcretePrivateAccount: &pa} } -func (pa ConcretePrivateAccount) Sign(msg []byte) (Signature, error) { +func (pa ConcretePrivateAccount) Sign(msg []byte) (crypto.Signature, error) { return pa.PrivateKey.Sign(msg) } -func ChainSign(signer Signer, chainID string, o Signable) (Signature, error) { - sig, err := signer.Sign(SignBytes(chainID, o)) - if err != nil { - return Signature{}, err - } - return sig, nil -} - func (pa *ConcretePrivateAccount) String() string { return fmt.Sprintf("ConcretePrivateAccount{%s}", pa.Address) } @@ -109,11 +102,11 @@ func SigningAccounts(concretePrivateAccounts []*ConcretePrivateAccount) []Addres // Generates a new account with private key. func GeneratePrivateAccount() (PrivateAccount, error) { - privateKey, err := GeneratePrivateKey(nil) + privateKey, err := crypto.GeneratePrivateKey(nil, crypto.CurveTypeEd25519) if err != nil { return nil, err } - publicKey := privateKey.PublicKey() + publicKey := privateKey.GetPublicKey() return ConcretePrivateAccount{ Address: publicKey.Address(), PublicKey: publicKey, @@ -123,8 +116,8 @@ func GeneratePrivateAccount() (PrivateAccount, error) { // Generates a new account with private key from SHA256 hash of a secret func GeneratePrivateAccountFromSecret(secret string) PrivateAccount { - privateKey := PrivateKeyFromSecret(secret) - publicKey := privateKey.PublicKey() + privateKey := crypto.PrivateKeyFromSecret(secret, crypto.CurveTypeEd25519) + publicKey := privateKey.GetPublicKey() return ConcretePrivateAccount{ Address: publicKey.Address(), PublicKey: publicKey, @@ -133,11 +126,11 @@ func GeneratePrivateAccountFromSecret(secret string) PrivateAccount { } func GeneratePrivateAccountFromPrivateKeyBytes(privKeyBytes []byte) (PrivateAccount, error) { - privateKey, err := Ed25519PrivateKeyFromRawBytes(privKeyBytes) + privateKey, err := crypto.PrivateKeyFromRawBytes(privKeyBytes, crypto.CurveTypeEd25519) if err != nil { return nil, err } - publicKey := privateKey.PublicKey() + publicKey := privateKey.GetPublicKey() return ConcretePrivateAccount{ Address: publicKey.Address(), PublicKey: publicKey, diff --git a/account/state/memory_state.go b/account/state/memory_state.go index 35f1ad696e5e4820c751f973e1148a120980caed..368c4fa3bf849a0c4d5eaf13f7ac3ea73d0a2719 100644 --- a/account/state/memory_state.go +++ b/account/state/memory_state.go @@ -5,11 +5,12 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" ) type MemoryState struct { - Accounts map[acm.Address]acm.Account - Storage map[acm.Address]map[binary.Word256]binary.Word256 + Accounts map[crypto.Address]acm.Account + Storage map[crypto.Address]map[binary.Word256]binary.Word256 } var _ IterableWriter = &MemoryState{} @@ -17,12 +18,12 @@ var _ IterableWriter = &MemoryState{} // Get an in-memory state Iterable func NewMemoryState() *MemoryState { return &MemoryState{ - Accounts: make(map[acm.Address]acm.Account), - Storage: make(map[acm.Address]map[binary.Word256]binary.Word256), + Accounts: make(map[crypto.Address]acm.Account), + Storage: make(map[crypto.Address]map[binary.Word256]binary.Word256), } } -func (ms *MemoryState) GetAccount(address acm.Address) (acm.Account, error) { +func (ms *MemoryState) GetAccount(address crypto.Address) (acm.Account, error) { return ms.Accounts[address], nil } @@ -34,12 +35,12 @@ func (ms *MemoryState) UpdateAccount(updatedAccount acm.Account) error { return nil } -func (ms *MemoryState) RemoveAccount(address acm.Address) error { +func (ms *MemoryState) RemoveAccount(address crypto.Address) error { delete(ms.Accounts, address) return nil } -func (ms *MemoryState) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) { +func (ms *MemoryState) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { storage, ok := ms.Storage[address] if !ok { return binary.Zero256, fmt.Errorf("could not find storage for account %s", address) @@ -51,7 +52,7 @@ func (ms *MemoryState) GetStorage(address acm.Address, key binary.Word256) (bina return value, nil } -func (ms *MemoryState) SetStorage(address acm.Address, key, value binary.Word256) error { +func (ms *MemoryState) SetStorage(address crypto.Address, key, value binary.Word256) error { storage, ok := ms.Storage[address] if !ok { storage = make(map[binary.Word256]binary.Word256) @@ -70,7 +71,7 @@ func (ms *MemoryState) IterateAccounts(consumer func(acm.Account) (stop bool)) ( return false, nil } -func (ms *MemoryState) IterateStorage(address acm.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) { +func (ms *MemoryState) IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) { for key, value := range ms.Storage[address] { if consumer(key, value) { return true, nil diff --git a/account/state/state.go b/account/state/state.go index d175f6e8e8742ea649814a3ee24cfa2152820311..645462abde6c325fdf9fe7c547683eb258d34dd5 100644 --- a/account/state/state.go +++ b/account/state/state.go @@ -3,12 +3,13 @@ package state import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" ptypes "github.com/hyperledger/burrow/permission/types" ) type AccountGetter interface { // Get an account by its address return nil if it does not exist (which should not be an error) - GetAccount(address acm.Address) (acm.Account, error) + GetAccount(address crypto.Address) (acm.Account, error) } type AccountIterable interface { @@ -23,25 +24,25 @@ type AccountUpdater interface { // if it does not exist UpdateAccount(updatedAccount acm.Account) error // Remove the account at address - RemoveAccount(address acm.Address) error + RemoveAccount(address crypto.Address) error } type StorageGetter interface { // Retrieve a 32-byte value stored at key for the account at address, return Zero256 if key does not exist but // error if address does not - GetStorage(address acm.Address, key binary.Word256) (value binary.Word256, err error) + GetStorage(address crypto.Address, key binary.Word256) (value binary.Word256, err error) } type StorageSetter interface { // Store a 32-byte value at key for the account at address, setting to Zero256 removes the key - SetStorage(address acm.Address, key, value binary.Word256) error + SetStorage(address crypto.Address, key, value binary.Word256) error } type StorageIterable interface { // Iterates through the storage of account ad address calling the passed function once per account, // if the iterator function returns true the iteration breaks and returns true to indicate it iteration // was escaped - IterateStorage(address acm.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) + IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) } // Compositions @@ -74,7 +75,7 @@ type IterableWriter interface { StorageIterable } -func GetMutableAccount(getter AccountGetter, address acm.Address) (acm.MutableAccount, error) { +func GetMutableAccount(getter AccountGetter, address crypto.Address) (acm.MutableAccount, error) { acc, err := getter.GetAccount(address) if err != nil { return nil, err diff --git a/account/state/state_cache.go b/account/state/state_cache.go index 81b0dcd2c24469968be0db44f3d82b4ec7d9e559..75dd70b1cf33be132d2685990a2ade2d302fb466 100644 --- a/account/state/state_cache.go +++ b/account/state/state_cache.go @@ -21,6 +21,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" ) type Cache interface { @@ -34,7 +35,7 @@ type stateCache struct { sync.RWMutex name string backend Reader - accounts map[acm.Address]*accountInfo + accounts map[crypto.Address]*accountInfo } type accountInfo struct { @@ -52,7 +53,7 @@ type CacheOption func(*stateCache) func NewCache(backend Reader, options ...CacheOption) Cache { cache := &stateCache{ backend: backend, - accounts: make(map[acm.Address]*accountInfo), + accounts: make(map[crypto.Address]*accountInfo), } for _, option := range options { option(cache) @@ -66,7 +67,7 @@ func Name(name string) CacheOption { } } -func (cache *stateCache) GetAccount(address acm.Address) (acm.Account, error) { +func (cache *stateCache) GetAccount(address crypto.Address) (acm.Account, error) { accInfo, err := cache.get(address) if err != nil { return nil, err @@ -94,7 +95,7 @@ func (cache *stateCache) UpdateAccount(account acm.Account) error { return nil } -func (cache *stateCache) RemoveAccount(address acm.Address) error { +func (cache *stateCache) RemoveAccount(address crypto.Address) error { accInfo, err := cache.get(address) if err != nil { return err @@ -122,7 +123,7 @@ func (cache *stateCache) IterateCachedAccount(consumer func(acm.Account) (stop b return false, nil } -func (cache *stateCache) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) { +func (cache *stateCache) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { accInfo, err := cache.get(address) if err != nil { return binary.Zero256, err @@ -148,7 +149,7 @@ func (cache *stateCache) GetStorage(address acm.Address, key binary.Word256) (bi } // NOTE: Set value to zero to remove. -func (cache *stateCache) SetStorage(address acm.Address, key binary.Word256, value binary.Word256) error { +func (cache *stateCache) SetStorage(address crypto.Address, key binary.Word256, value binary.Word256) error { accInfo, err := cache.get(address) accInfo.Lock() defer accInfo.Unlock() @@ -164,7 +165,7 @@ func (cache *stateCache) SetStorage(address acm.Address, key binary.Word256, val } // Iterates over all cached storage items first in cache and then in backend until consumer returns true for 'stop' -func (cache *stateCache) IterateCachedStorage(address acm.Address, +func (cache *stateCache) IterateCachedStorage(address crypto.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) { accInfo, err := cache.get(address) if err != nil { @@ -187,7 +188,7 @@ func (cache *stateCache) IterateCachedStorage(address acm.Address, func (cache *stateCache) Sync(state Writer) error { cache.Lock() defer cache.Unlock() - var addresses acm.Addresses + var addresses crypto.Addresses for address := range cache.accounts { addresses = append(addresses, address) } @@ -232,7 +233,7 @@ func (cache *stateCache) Reset(backend Iterable) { cache.Lock() defer cache.Unlock() cache.backend = backend - cache.accounts = make(map[acm.Address]*accountInfo, len(cache.accounts)) + cache.accounts = make(map[crypto.Address]*accountInfo, len(cache.accounts)) } // Syncs the Cache and Resets it to use as the backend Reader @@ -253,7 +254,7 @@ func (cache *stateCache) String() string { } // Get the cache accountInfo item creating it if necessary -func (cache *stateCache) get(address acm.Address) (*accountInfo, error) { +func (cache *stateCache) get(address crypto.Address) (*accountInfo, error) { cache.RLock() accInfo := cache.accounts[address] cache.RUnlock() diff --git a/account/state/state_cache_test.go b/account/state/state_cache_test.go index 76ffee5cb17ef90844103853d4a2669cca1f366d..92171155cf68cf2d796a83159c6d1fcb0ee14bb9 100644 --- a/account/state/state_cache_test.go +++ b/account/state/state_cache_test.go @@ -7,6 +7,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/evm/asm" "github.com/hyperledger/burrow/permission" "github.com/stretchr/testify/assert" @@ -305,7 +306,7 @@ func testAccounts() *MemoryState { return cache } -func addressOf(secret string) acm.Address { +func addressOf(secret string) crypto.Address { return acm.NewConcreteAccountFromSecret(secret).Address } diff --git a/account/validator.go b/account/validator.go index 5271a2f4a01cdba71280175ff4fde479fb80576e..017b1eb2a180036f22665aaac2b8ff5fd6750ba6 100644 --- a/account/validator.go +++ b/account/validator.go @@ -2,6 +2,8 @@ package account import ( "encoding/json" + + "github.com/hyperledger/burrow/crypto" ) type Validator interface { @@ -15,8 +17,8 @@ type Validator interface { // Neither abci_types or tm_types has quite the representation we want type ConcreteValidator struct { - Address Address - PublicKey PublicKey + Address crypto.Address + PublicKey crypto.PublicKey Power uint64 } @@ -48,11 +50,11 @@ func AsConcreteValidator(validator Validator) *ConcreteValidator { } } -func (cvw concreteValidatorWrapper) Address() Address { +func (cvw concreteValidatorWrapper) Address() crypto.Address { return cvw.ConcreteValidator.Address } -func (cvw concreteValidatorWrapper) PublicKey() PublicKey { +func (cvw concreteValidatorWrapper) PublicKey() crypto.PublicKey { return cvw.ConcreteValidator.PublicKey } diff --git a/client/methods/call.go b/client/methods/call.go index c613ff489f089c14d0a8286127ad47c2abecea3b..38271439ae27955983272440f640df28c6eeebde 100644 --- a/client/methods/call.go +++ b/client/methods/call.go @@ -29,7 +29,10 @@ func Call(do *client.Do) error { if err != nil { return fmt.Errorf("Could not generate logging config from Do: %s", err) } - burrowKeyClient := keys.NewKeyClient(do.SignAddrFlag, logger) + burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger) + if err != nil { + return fmt.Errorf("Could not create remote key client: %s", err) + } burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger) // form the call transaction callTransaction, err := rpc.Call(burrowNodeClient, burrowKeyClient, diff --git a/client/methods/send.go b/client/methods/send.go index b9736d5065816f1ec43a69c9479288c99a0cffcf..e04771e185b358a22c0e8fcb53b99adb47504bc9 100644 --- a/client/methods/send.go +++ b/client/methods/send.go @@ -29,7 +29,10 @@ func Send(do *client.Do) error { if err != nil { return fmt.Errorf("Could not generate logging config from Do: %s", err) } - burrowKeyClient := keys.NewKeyClient(do.SignAddrFlag, logger) + burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger) + if err != nil { + return fmt.Errorf("Could not create remote key client: %s", err) + } burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger) // form the send transaction sendTransaction, err := rpc.Send(burrowNodeClient, burrowKeyClient, diff --git a/client/mock/client_mock.go b/client/mock/client_mock.go index 0fb53896ffb2284a7e9d754d75577afae03627b8..c683cc4ee3ed6b4dc1e702adc34387ffd789e72b 100644 --- a/client/mock/client_mock.go +++ b/client/mock/client_mock.go @@ -17,10 +17,11 @@ package mock import ( acm "github.com/hyperledger/burrow/account" . "github.com/hyperledger/burrow/client" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/rpc" "github.com/hyperledger/burrow/txs" - "github.com/tendermint/go-crypto" + tm_crypto "github.com/tendermint/go-crypto" ) var _ NodeClient = (*MockNodeClient)(nil) @@ -48,7 +49,7 @@ func (mock *MockNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketC return nil, nil } -func (mock *MockNodeClient) GetAccount(address acm.Address) (acm.Account, error) { +func (mock *MockNodeClient) GetAccount(address crypto.Address) (acm.Account, error) { // make zero account return acm.FromAddressable(acm.GeneratePrivateAccountFromSecret("mock-node-client-account")), nil } @@ -63,14 +64,14 @@ func (mock *MockNodeClient) Status() (ChainId []byte, ValidatorPublicKey []byte, // fill return values ChainId = make([]byte, 64) LatestBlockHash = make([]byte, 64) - ValidatorPublicKey = crypto.PubKeyEd25519{}.Wrap().Bytes() + ValidatorPublicKey = tm_crypto.PubKeyEd25519{}.Wrap().Bytes() BlockHeight = 0 LatestBlockTime = 0 return } // QueryContract executes the contract code at address with the given data -func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress acm.Address, +func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address, data []byte) (ret []byte, gasUsed uint64, err error) { // return zero @@ -79,18 +80,18 @@ func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress acm.Addre } // QueryContractCode executes the contract code at address with the given data but with provided code -func (mock *MockNodeClient) QueryContractCode(address acm.Address, code, +func (mock *MockNodeClient) QueryContractCode(address crypto.Address, code, data []byte) (ret []byte, gasUsed uint64, err error) { // return zero ret = make([]byte, 0) return } -func (mock *MockNodeClient) DumpStorage(address acm.Address) (storage *rpc.ResultDumpStorage, err error) { +func (mock *MockNodeClient) DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error) { return } -func (mock *MockNodeClient) GetName(name string) (owner acm.Address, data string, expirationBlock uint64, err error) { +func (mock *MockNodeClient) GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error) { return } diff --git a/client/node_client.go b/client/node_client.go index 6e19231a2405c1edced4b45d713a968c61851a9c..c98ff55086e0dfb2fedab79e6916fce0b0dce167 100644 --- a/client/node_client.go +++ b/client/node_client.go @@ -18,6 +18,7 @@ import ( "fmt" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/rpc" tendermint_client "github.com/hyperledger/burrow/rpc/tm/client" @@ -31,12 +32,12 @@ type NodeClient interface { Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte, LatestBlockHeight uint64, LatestBlockTime int64, err error) - GetAccount(address acm.Address) (acm.Account, error) - QueryContract(callerAddress, calleeAddress acm.Address, data []byte) (ret []byte, gasUsed uint64, err error) - QueryContractCode(address acm.Address, code, data []byte) (ret []byte, gasUsed uint64, err error) + GetAccount(address crypto.Address) (acm.Account, error) + QueryContract(callerAddress, calleeAddress crypto.Address, data []byte) (ret []byte, gasUsed uint64, err error) + QueryContractCode(address crypto.Address, code, data []byte) (ret []byte, gasUsed uint64, err error) - DumpStorage(address acm.Address) (storage *rpc.ResultDumpStorage, err error) - GetName(name string) (owner acm.Address, data string, expirationBlock uint64, err error) + DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error) + GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error) ListValidators() (blockHeight uint64, bondedValidators, unbondingValidators []acm.Validator, err error) // Logging context for this NodeClient @@ -47,7 +48,7 @@ type NodeWebsocketClient interface { Subscribe(eventId string) error Unsubscribe(eventId string) error - WaitForConfirmation(tx txs.Tx, chainId string, inputAddr acm.Address) (chan Confirmation, error) + WaitForConfirmation(tx txs.Tx, chainId string, inputAddr crypto.Address) (chan Confirmation, error) Close() } @@ -133,7 +134,7 @@ func (burrowNodeClient *burrowNodeClient) Status() (GenesisHash []byte, Validato // unwrap return results GenesisHash = res.GenesisHash - ValidatorPublicKey = res.PubKey.Bytes() + ValidatorPublicKey = res.PubKey.RawBytes() LatestBlockHash = res.LatestBlockHash LatestBlockHeight = res.LatestBlockHeight LatestBlockTime = res.LatestBlockTime @@ -158,7 +159,7 @@ func (burrowNodeClient *burrowNodeClient) ChainId() (ChainName, ChainId string, // QueryContract executes the contract code at address with the given data // NOTE: there is no check on the caller; -func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress acm.Address, +func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address, data []byte) (ret []byte, gasUsed uint64, err error) { client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) @@ -172,7 +173,7 @@ func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAdd } // QueryContractCode executes the contract code at address with the given data but with provided code -func (burrowNodeClient *burrowNodeClient) QueryContractCode(address acm.Address, code, +func (burrowNodeClient *burrowNodeClient) QueryContractCode(address crypto.Address, code, data []byte) (ret []byte, gasUsed uint64, err error) { client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) @@ -188,7 +189,7 @@ func (burrowNodeClient *burrowNodeClient) QueryContractCode(address acm.Address, } // GetAccount returns a copy of the account -func (burrowNodeClient *burrowNodeClient) GetAccount(address acm.Address) (acm.Account, error) { +func (burrowNodeClient *burrowNodeClient) GetAccount(address crypto.Address) (acm.Account, error) { client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) account, err := tendermint_client.GetAccount(client, address) if err != nil { @@ -205,7 +206,7 @@ func (burrowNodeClient *burrowNodeClient) GetAccount(address acm.Address) (acm.A } // DumpStorage returns the full storage for an acm. -func (burrowNodeClient *burrowNodeClient) DumpStorage(address acm.Address) (*rpc.ResultDumpStorage, error) { +func (burrowNodeClient *burrowNodeClient) DumpStorage(address crypto.Address) (*rpc.ResultDumpStorage, error) { client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) resultStorage, err := tendermint_client.DumpStorage(client, address) if err != nil { @@ -218,7 +219,7 @@ func (burrowNodeClient *burrowNodeClient) DumpStorage(address acm.Address) (*rpc //-------------------------------------------------------------------------------------------- // Name registry -func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner acm.Address, data string, +func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error) { client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) @@ -226,7 +227,7 @@ func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner acm.Addres if err != nil { err = fmt.Errorf("error connecting to node (%s) to get name registrar entry for name (%s)", burrowNodeClient.broadcastRPC, name) - return acm.ZeroAddress, "", 0, err + return crypto.ZeroAddress, "", 0, err } // unwrap return results owner = entryResult.Owner diff --git a/client/rpc/client.go b/client/rpc/client.go index 3a76948c2638df2e4589c5e5188dc8bf75635c7d..b2afaec4a55ba75d1ff2bf2ec94f323459ca040a 100644 --- a/client/rpc/client.go +++ b/client/rpc/client.go @@ -19,9 +19,9 @@ import ( "fmt" "strconv" + "github.com/hyperledger/burrow/crypto" ptypes "github.com/hyperledger/burrow/permission" - acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/client" "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/permission/snatives" @@ -60,7 +60,7 @@ func Call(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, return nil, err } - var toAddress *acm.Address + var toAddress *crypto.Address if toAddr != "" { address, err := addressFromHexString(toAddr) @@ -121,7 +121,7 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, // Try and set each PermArg field for which a string has been provided we'll validate afterwards if target != "" { - address, err := acm.AddressFromHexString(target) + address, err := crypto.AddressFromHexString(target) if err != nil { return nil, err } @@ -238,7 +238,7 @@ type TxResult struct { Hash []byte // all txs get a hash // only CallTx - Address *acm.Address // only for new contracts + Address *crypto.Address // only for new contracts Return []byte Exception string @@ -250,7 +250,7 @@ type TxResult struct { func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient keys.KeyClient, tx txs.Tx, sign, broadcast, wait bool) (txResult *TxResult, err error) { - var inputAddr acm.Address + var inputAddr crypto.Address if sign { inputAddr, tx, err = signTx(keyClient, chainID, tx) if err != nil { @@ -312,7 +312,7 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke // the benefit is that the we don't need to trust the chain node if tx_, ok := tx.(*txs.CallTx); ok { if tx_.Address == nil { - address := acm.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence) + address := crypto.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence) txResult.Address = &address } } @@ -320,10 +320,10 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke return } -func addressFromHexString(addrString string) (acm.Address, error) { +func addressFromHexString(addrString string) (crypto.Address, error) { addrBytes, err := hex.DecodeString(addrString) if err != nil { - return acm.Address{}, err + return crypto.Address{}, err } - return acm.AddressFromBytes(addrBytes) + return crypto.AddressFromBytes(addrBytes) } diff --git a/client/rpc/client_util.go b/client/rpc/client_util.go index 914ba28f6387d87305d11c694c9f96c416092253..b904a4f0901bc2b53f319804a6834a13df85e118 100644 --- a/client/rpc/client_util.go +++ b/client/rpc/client_util.go @@ -19,8 +19,8 @@ import ( "fmt" "strconv" - acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/client" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/txs" ) @@ -30,8 +30,8 @@ import ( // tx has either one input or we default to the first one (ie for send/bond) // TODO: better support for multisig and bonding -func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) (acm.Address, txs.Tx, error) { - signBytes := acm.SignBytes(chainID, tx_) +func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) (crypto.Address, txs.Tx, error) { + signBytes := crypto.SignBytes(chainID, tx_) var err error switch tx := tx_.(type) { case *txs.SendTx: @@ -71,12 +71,12 @@ func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) (acm.Address, return signAddress, tx, err default: - return acm.ZeroAddress, nil, fmt.Errorf("unknown transaction type for signTx: %#v", tx_) + return crypto.ZeroAddress, nil, fmt.Errorf("unknown transaction type for signTx: %#v", tx_) } } func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS, - sequenceS string) (pub acm.PublicKey, amt uint64, sequence uint64, err error) { + sequenceS string) (pub crypto.PublicKey, amt uint64, sequence uint64, err error) { if amtS == "" { err = fmt.Errorf("input must specify an amount with the --amt flag") @@ -99,7 +99,7 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, err = fmt.Errorf("pubkey is bad hex: %v", err) return } - pub, err = acm.PublicKeyFromBytes(pubKeyBytes) + pub, err = crypto.PublicKeyFromBytes(pubKeyBytes, crypto.CurveTypeEd25519) if err != nil { return } @@ -110,7 +110,7 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, err = fmt.Errorf("Bad hex string for address (%s): %v", addr, err) return } - address, err2 := acm.AddressFromBytes(addressBytes) + address, err2 := crypto.AddressFromBytes(addressBytes) if err2 != nil { err = fmt.Errorf("Could not convert bytes (%X) to address: %v", addressBytes, err2) } @@ -121,7 +121,7 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, } } - var address acm.Address + var address crypto.Address address = pub.Address() amt, err = strconv.ParseUint(amtS, 10, 64) diff --git a/client/websocket_client.go b/client/websocket_client.go index fe08dde89d912394e422cccd9e1f33f068f938a0..1841cefc4c36de8c026533c133c3551c6f1c5535 100644 --- a/client/websocket_client.go +++ b/client/websocket_client.go @@ -21,7 +21,7 @@ import ( "encoding/json" - "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" exe_events "github.com/hyperledger/burrow/execution/events" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" @@ -69,7 +69,7 @@ func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Unsubscribe(subscrip // Returns a channel that will receive a confirmation with a result or the exception that // has been confirmed; or an error is returned and the confirmation channel is nil. func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(tx txs.Tx, chainId string, - inputAddr account.Address) (chan Confirmation, error) { + inputAddr crypto.Address) (chan Confirmation, error) { // Setup the confirmation channel to be returned confirmationChannel := make(chan Confirmation, 1) diff --git a/cmd/burrow/commands/configure.go b/cmd/burrow/commands/configure.go index 97c64432f120452f7db6e5c8004081e235687f7c..a964e2f9eb86b330eb34327ccfb8d31bbdc43c1b 100644 --- a/cmd/burrow/commands/configure.go +++ b/cmd/burrow/commands/configure.go @@ -12,7 +12,6 @@ import ( "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/genesis/spec" "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/keys/mock" "github.com/hyperledger/burrow/logging" logging_config "github.com/hyperledger/burrow/logging/config" "github.com/hyperledger/burrow/logging/config/presets" @@ -27,8 +26,8 @@ func Configure(output Output) func(cmd *cli.Cmd) { jsonOutOpt := cmd.BoolOpt("j json", false, "Emit config in JSON rather than TOML "+ "suitable for further processing") - keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys URL, default: %s", - keys.DefaultKeysConfig().URL)) + keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys GRPC address, default: %s", + keys.DefaultKeysConfig().RemoteAddress)) configOpt := cmd.StringOpt("c base-config", "", "Use the a specified burrow config file as a base") @@ -85,7 +84,7 @@ func Configure(output Output) func(cmd *cli.Cmd) { } if *keysUrlOpt != "" { - conf.Keys.URL = *keysUrlOpt + conf.Keys.RemoteAddress = *keysUrlOpt } // Genesis Spec @@ -95,14 +94,22 @@ func Configure(output Output) func(cmd *cli.Cmd) { if err != nil { output.Fatalf("Could not read GenesisSpec: %v", err) } + keyStore := keys.NewKeyStore(conf.Keys.KeysDirectory) if *generateKeysOpt != "" { - keyClient := mock.NewKeyClient() + keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger()) conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient) if err != nil { output.Fatalf("Could not generate GenesisDoc from GenesisSpec using MockKeyClient: %v", err) } - pkg := deployment.Package{Keys: keyClient.Keys()} + allKeys, err := keyStore.AllKeys() + if err != nil { + output.Fatalf("could get all keys: %v", err) + } + pkg := deployment.Package{Keys: allKeys} + if err != nil { + output.Fatalf("Could not dump keys: %v", err) + } secretKeysString, err := pkg.Dump(*keysTemplateOpt) if err != nil { output.Fatalf("Could not dump keys: %v", err) @@ -112,8 +119,18 @@ func Configure(output Output) func(cmd *cli.Cmd) { output.Fatalf("Could not write secret keys: %v", err) } } else { - conf.GenesisDoc, err = genesisSpec.GenesisDoc(keys.NewKeyClient(conf.Keys.URL, logging.NewNoopLogger())) + var keyClient keys.KeyClient + if conf.Keys.RemoteAddress != "" { + keyClient, err = keys.NewRemoteKeyClient(conf.Keys.RemoteAddress, logging.NewNoopLogger()) + if err != nil { + output.Fatalf("Could not create remote key client: %v", err) + } + } else { + keyClient = keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger()) + } + conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient) } + if err != nil { output.Fatalf("could not realise GenesisSpec: %v", err) } diff --git a/cmd/burrow/commands/keys.go b/cmd/burrow/commands/keys.go new file mode 100644 index 0000000000000000000000000000000000000000..10b3c4fe240425a8b1fb8d48252af480befe306e --- /dev/null +++ b/cmd/burrow/commands/keys.go @@ -0,0 +1,319 @@ +package commands + +import ( + "context" + "encoding/hex" + "fmt" + "os" + + "time" + + "io/ioutil" + + "github.com/howeyc/gopass" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/keys" + "github.com/hyperledger/burrow/keys/pbkeys" + "github.com/jawher/mow.cli" + "google.golang.org/grpc" +) + +func Keys(output Output) func(cmd *cli.Cmd) { + return func(cmd *cli.Cmd) { + keysHost := cmd.String(cli.StringOpt{ + Name: "host", + Desc: "set the host for talking to the key daemon", + Value: keys.DefaultHost, + EnvVar: "MONAX_KEYS_HOST", + }) + + keysPort := cmd.String(cli.StringOpt{ + Name: "host", + Desc: "set the port for key daemon", + Value: keys.DefaultPort, + EnvVar: "MONAX_KEYS_PORT", + }) + + grpcKeysClient := func(output Output) pbkeys.KeysClient { + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + conn, err := grpc.Dial(*keysHost+":"+*keysPort, opts...) + if err != nil { + output.Fatalf("Failed to connect to grpc server: %v", err) + } + return pbkeys.NewKeysClient(conn) + } + + cmd.Command("server", "run keys server", func(cmd *cli.Cmd) { + keysDir := cmd.StringOpt("dir", keys.DefaultKeysDir, "specify the location of the directory containing key files") + + cmd.Action = func() { + err := keys.StartStandAloneServer(*keysDir, *keysHost, *keysPort) + if err != nil { + output.Fatalf("Failed to start server: %v", err) + } + } + }) + + cmd.Command("gen", "Generates a key using (insert crypto pkgs used)", func(cmd *cli.Cmd) { + noPassword := cmd.BoolOpt("n no-password", false, "don't use a password for this key") + + keyType := cmd.StringOpt("t curvetype", "ed25519", "specify the curve type of key to create. Supports 'secp256k1' (ethereum), 'ed25519' (tendermint)") + + keyName := cmd.StringOpt("name", "", "name of key to use") + + cmd.Action = func() { + curve, err := crypto.CurveTypeFromString(*keyType) + if err != nil { + output.Fatalf("Unrecognised curve type %v", *keyType) + } + + var password string + if !*noPassword { + fmt.Printf("Enter Password:") + pwd, err := gopass.GetPasswdMasked() + if err != nil { + os.Exit(1) + } + password = string(pwd) + } + + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Passphrase: password, Curvetype: curve.String(), Keyname: *keyName}) + if err != nil { + output.Fatalf("failed to generate key: %v", err) + } + + fmt.Printf("%v\n", resp.GetAddress()) + } + }) + + cmd.Command("hash", "hash <some data>", func(cmd *cli.Cmd) { + hashType := cmd.StringOpt("t type", keys.DefaultHashType, "specify the hash function to use") + + hexByte := cmd.BoolOpt("hex", false, "the input should be hex decoded to bytes first") + + msg := cmd.StringArg("MSG", "", "message to hash") + + cmd.Action = func() { + var message []byte + var err error + if *hexByte { + message, err = hex.DecodeString(*msg) + if err != nil { + output.Fatalf("failed to hex decode message: %v", err) + } + } else { + message = []byte(*msg) + } + + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: *hashType, Message: message}) + if err != nil { + output.Fatalf("failed to get public key: %v", err) + } + + fmt.Printf("%v\n", resp.GetHash()) + } + }) + + cmd.Command("export", "Export a key to tendermint format", func(cmd *cli.Cmd) { + keyName := cmd.StringOpt("name", "", "name of key to use") + keyAddr := cmd.StringOpt("addr", "", "address of key to use") + passphrase := cmd.StringOpt("passphrase", "", "passphrase for encrypted key") + + cmd.Action = func() { + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := c.Export(ctx, &pbkeys.ExportRequest{Passphrase: *passphrase, Name: *keyName, Address: *keyAddr}) + if err != nil { + output.Fatalf("failed to export key: %v", err) + } + + fmt.Printf("%s\n", resp.GetExport()) + } + }) + + cmd.Command("import", "import <priv key> | /path/to/keyfile | <key json>", func(cmd *cli.Cmd) { + curveType := cmd.StringOpt("t curvetype", "ed25519", "specify the curve type of key to create. Supports 'secp256k1' (ethereum), 'ed25519' (tendermint)") + noPassword := cmd.BoolOpt("n no-password", false, "don't use a password for this key") + key := cmd.StringArg("KEY", "", "private key, filename, or raw json") + + cmd.Action = func() { + var password string + if !*noPassword { + fmt.Printf("Enter Password:") + pwd, err := gopass.GetPasswdMasked() + if err != nil { + os.Exit(1) + } + password = string(pwd) + } + + var privKeyBytes []byte + fileContents, err := ioutil.ReadFile(*key) + if err == nil { + *key = string(fileContents) + } + + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + if (*key)[:1] == "{" { + resp, err := c.ImportJSON(ctx, &pbkeys.ImportJSONRequest{JSON: *key}) + if err != nil { + output.Fatalf("failed to import json key: %v", err) + } + + fmt.Printf("%s\n", resp.GetAddress()) + } else { + privKeyBytes, err = hex.DecodeString(*key) + if err != nil { + output.Fatalf("failed to hex decode key: %s", *key) + } + resp, err := c.Import(ctx, &pbkeys.ImportRequest{Passphrase: password, Keybytes: privKeyBytes, Curvetype: *curveType}) + if err != nil { + output.Fatalf("failed to import json key: %v", err) + } + + fmt.Printf("%s\n", resp.GetAddress()) + + } + } + }) + + cmd.Command("pub", "public key", func(cmd *cli.Cmd) { + name := cmd.StringOpt("name", "", "name of key to use") + addr := cmd.StringOpt("addr", "", "address of key to use") + + cmd.Action = func() { + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Name: *name, Address: *addr}) + if err != nil { + output.Fatalf("failed to get public key: %v", err) + } + + fmt.Printf("%X\n", resp.GetPub()) + } + }) + + cmd.Command("sign", "sign <some data>", func(cmd *cli.Cmd) { + name := cmd.StringOpt("name", "", "name of key to use") + addr := cmd.StringOpt("addr", "", "address of key to use") + msg := cmd.StringArg("MSG", "", "message to sign") + passphrase := cmd.StringOpt("passphrase", "", "passphrase for encrypted key") + + cmd.Action = func() { + message, err := hex.DecodeString(*msg) + if err != nil { + output.Fatalf("failed to hex decode message: %v", err) + } + + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := c.Sign(ctx, &pbkeys.SignRequest{Passphrase: *passphrase, Name: *name, Address: *addr, Message: message}) + if err != nil { + output.Fatalf("failed to get public key: %v", err) + } + fmt.Printf("%X\n", resp.GetSignature()) + } + }) + + cmd.Command("verify", "verify <some data> <sig> <pubkey>", func(cmd *cli.Cmd) { + curveType := cmd.StringOpt("t curvetype", "ed25519", "specify the curve type of key to create. Supports 'secp256k1' (ethereum), 'ed25519' (tendermint)") + + msg := cmd.StringArg("MSG", "", "hash/message to check") + sig := cmd.StringArg("SIG", "", "signature") + pub := cmd.StringArg("PUBLIC", "", "public key") + + cmd.Action = func() { + message, err := hex.DecodeString(*msg) + if err != nil { + output.Fatalf("failed to hex decode message: %v", err) + } + + signature, err := hex.DecodeString(*sig) + if err != nil { + output.Fatalf("failed to hex decode signature: %v", err) + } + + publickey, err := hex.DecodeString(*pub) + if err != nil { + output.Fatalf("failed to hex decode publickey: %v", err) + } + + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Curvetype: *curveType, Pub: publickey, Signature: signature, Message: message}) + if err != nil { + output.Fatalf("failed to verify: %v", err) + } + output.Printf("true\n") + } + }) + + cmd.Command("name", "add key name to addr", func(cmd *cli.Cmd) { + keyname := cmd.StringArg("NAME", "", "name of key to use") + addr := cmd.StringArg("ADDR", "", "address of key to use") + + cmd.Action = func() { + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + _, err := c.AddName(ctx, &pbkeys.AddNameRequest{Keyname: *keyname, Address: *addr}) + if err != nil { + output.Fatalf("failed to add name to addr: %v", err) + } + } + }) + + cmd.Command("list", "list key names", func(cmd *cli.Cmd) { + name := cmd.StringOpt("name", "", "name of key to use") + + cmd.Action = func() { + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := c.List(ctx, &pbkeys.Name{*name}) + if err != nil { + output.Fatalf("failed to list key names: %v", err) + } + if *name != "" { + for _, k := range resp.Key { + if k.Keyname == *name { + output.Printf("%s\n", k.Address) + } + } + } else { + for _, k := range resp.Key { + fmt.Printf("%v\n", k) + } + } + } + }) + + cmd.Command("rm", "rm key name", func(cmd *cli.Cmd) { + name := cmd.StringArg("NAME", "", "key to remove") + + cmd.Action = func() { + c := grpcKeysClient(output) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + _, err := c.RemoveName(ctx, &pbkeys.Name{*name}) + if err != nil { + output.Fatalf("failed to remove key: %v", err) + } + } + }) + } +} diff --git a/cmd/burrow/commands/start.go b/cmd/burrow/commands/start.go index 7d112ffb2f27e790826ae0ce0309a7166bb06116..67b43bb0e78f9911e93791313435810edcd85b1f 100644 --- a/cmd/burrow/commands/start.go +++ b/cmd/burrow/commands/start.go @@ -3,9 +3,9 @@ package commands import ( "context" - acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/config" "github.com/hyperledger/burrow/config/source" + "github.com/hyperledger/burrow/crypto" logging_config "github.com/hyperledger/burrow/logging/config" "github.com/jawher/mow.cli" ) @@ -71,7 +71,7 @@ func Start(output Output) func(cmd *cli.Cmd) { // Which validator am I? if *validatorAddressOpt != "" { - address, err := acm.AddressFromHexString(*validatorAddressOpt) + address, err := crypto.AddressFromHexString(*validatorAddressOpt) if err != nil { output.Fatalf("could not read address for validator in '%s'", *validatorAddressOpt) } diff --git a/cmd/burrow/main.go b/cmd/burrow/main.go index cddf19edc8d799e63f726b197ee34357adb0a7df..28930dee9825417e16a5ef3d5a7af338fe7f4bd4 100644 --- a/cmd/burrow/main.go +++ b/cmd/burrow/main.go @@ -36,6 +36,9 @@ func burrow(output commands.Output) *cli.Cli { "Create Burrow configuration by consuming a GenesisDoc or GenesisSpec, creating keys, and emitting the config", commands.Configure(output)) + app.Command("keys", "A tool for doing a bunch of cool stuff with keys", + commands.Keys(output)) + return app } diff --git a/config/config.go b/config/config.go index 3ce6d2f83ce83178970ed7e7bd8d7b3a0b845a11..1a73e9faa4b9c8d075e1f5365b46230b0bd694d9 100644 --- a/config/config.go +++ b/config/config.go @@ -5,11 +5,11 @@ import ( "context" - acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/config/source" "github.com/hyperledger/burrow/consensus/tendermint" "github.com/hyperledger/burrow/consensus/tendermint/validator" "github.com/hyperledger/burrow/core" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" @@ -24,8 +24,8 @@ const DefaultGenesisDocJSONFileName = "genesis.json" type BurrowConfig struct { // Set on startup - ValidatorAddress *acm.Address `json:",omitempty" toml:",omitempty"` - ValidatorPassphrase *string `json:",omitempty" toml:",omitempty"` + ValidatorAddress *crypto.Address `json:",omitempty" toml:",omitempty"` + ValidatorPassphrase *string `json:",omitempty" toml:",omitempty"` // From config file GenesisDoc *genesis.GenesisDoc `json:",omitempty" toml:",omitempty"` Tendermint *tendermint.BurrowTendermintConfig `json:",omitempty" toml:",omitempty"` @@ -55,7 +55,18 @@ func (conf *BurrowConfig) Kernel(ctx context.Context) (*core.Kernel, error) { if err != nil { return nil, fmt.Errorf("could not generate logger from logging config: %v", err) } - keyClient := keys.NewKeyClient(conf.Keys.URL, logger) + var keyClient keys.KeyClient + var keyStore keys.KeyStore + if conf.Keys.RemoteAddress != "" { + keyClient, err = keys.NewRemoteKeyClient(conf.Keys.RemoteAddress, logger) + if err != nil { + return nil, err + } + } else { + keyStore = keys.NewKeyStore(conf.Keys.KeysDirectory) + keyClient = keys.NewLocalKeyClient(keyStore, logger) + } + val, err := keys.Addressable(keyClient, *conf.ValidatorAddress) if err != nil { return nil, fmt.Errorf("could not get validator addressable from keys client: %v", err) @@ -70,8 +81,8 @@ func (conf *BurrowConfig) Kernel(ctx context.Context) (*core.Kernel, error) { } } - return core.NewKernel(ctx, keyClient, privValidator, conf.GenesisDoc, conf.Tendermint.TendermintConfig(), conf.RPC, - exeOptions, logger) + return core.NewKernel(ctx, keyClient, privValidator, conf.GenesisDoc, conf.Tendermint.TendermintConfig(), conf.RPC, conf.Keys, + &keyStore, exeOptions, logger) } func (conf *BurrowConfig) JSONString() string { diff --git a/consensus/tendermint/query/node_view.go b/consensus/tendermint/query/node_view.go index 566a93e377e983cc750b8b1cc3270bedf968332a..8f9539956e40233f2cf6e1fe4733e37ab1a18afb 100644 --- a/consensus/tendermint/query/node_view.go +++ b/consensus/tendermint/query/node_view.go @@ -3,8 +3,10 @@ package query import ( "fmt" - acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/consensus/tendermint" + "github.com/hyperledger/burrow/crypto" + tm_crypto "github.com/tendermint/go-crypto" + "github.com/hyperledger/burrow/txs" "github.com/tendermint/tendermint/consensus" ctypes "github.com/tendermint/tendermint/consensus/types" @@ -24,8 +26,10 @@ func NewNodeView(tmNode *tendermint.Node, txDecoder txs.Decoder) *NodeView { } } -func (nv *NodeView) PrivValidatorPublicKey() (acm.PublicKey, error) { - return acm.PublicKeyFromGoCryptoPubKey(nv.tmNode.PrivValidator().GetPubKey()) +func (nv *NodeView) PrivValidatorPublicKey() (crypto.PublicKey, error) { + pub := nv.tmNode.PrivValidator().GetPubKey().Unwrap().(tm_crypto.PubKeyEd25519) + + return crypto.PublicKeyFromBytes(pub[:], crypto.CurveTypeEd25519) } func (nv *NodeView) NodeInfo() p2p.NodeInfo { diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index 261bba24ffd74f66ea78344991caad09a5ebe68f..a83dbfa97b7b5752112a96263ba584e4b43ecbc6 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -17,6 +17,7 @@ import ( "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/txs" abci_types "github.com/tendermint/abci/types" + tm_crypto "github.com/tendermint/go-crypto" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" @@ -101,8 +102,10 @@ func BroadcastTxAsyncFunc(validator *Node, txEncoder txs.Encoder) func(tx txs.Tx func DeriveGenesisDoc(burrowGenesisDoc *genesis.GenesisDoc) *tm_types.GenesisDoc { validators := make([]tm_types.GenesisValidator, len(burrowGenesisDoc.Validators)) for i, validator := range burrowGenesisDoc.Validators { + tm := tm_crypto.PubKeyEd25519{} + copy(tm[:], validator.PublicKey.RawBytes()) validators[i] = tm_types.GenesisValidator{ - PubKey: validator.PublicKey.PubKey, + PubKey: tm_crypto.PubKey{tm}, Name: validator.Name, Power: int64(validator.Amount), } diff --git a/consensus/tendermint/validator/priv_validator_memory.go b/consensus/tendermint/validator/priv_validator_memory.go index 50c6fdd99180c46beeedbb5bcc608895a7aaa926..4126d3d6e4e798dfdaf5dd8e897d47d937090959 100644 --- a/consensus/tendermint/validator/priv_validator_memory.go +++ b/consensus/tendermint/validator/priv_validator_memory.go @@ -2,7 +2,8 @@ package validator import ( acm "github.com/hyperledger/burrow/account" - "github.com/tendermint/go-crypto" + "github.com/hyperledger/burrow/crypto" + tm_crypto "github.com/tendermint/go-crypto" tm_types "github.com/tendermint/tendermint/types" val_types "github.com/tendermint/tendermint/types/priv_validator" ) @@ -17,7 +18,7 @@ var _ tm_types.PrivValidator = &privValidatorMemory{} // Create a PrivValidator with in-memory state that takes an addressable representing the validator identity // and a signer providing private signing for that identity. -func NewPrivValidatorMemory(addressable acm.Addressable, signer acm.Signer) *privValidatorMemory { +func NewPrivValidatorMemory(addressable acm.Addressable, signer crypto.Signer) *privValidatorMemory { return &privValidatorMemory{ Addressable: addressable, Signer: asTendermintSigner(signer), @@ -29,8 +30,10 @@ func (pvm *privValidatorMemory) GetAddress() tm_types.Address { return pvm.Address().Bytes() } -func (pvm *privValidatorMemory) GetPubKey() crypto.PubKey { - return pvm.PublicKey().PubKey +func (pvm *privValidatorMemory) GetPubKey() tm_crypto.PubKey { + tm := tm_crypto.PubKeyEd25519{} + copy(tm[:], pvm.PublicKey().RawBytes()) + return tm_crypto.PubKey{tm} } // TODO: consider persistence to disk/database to avoid double signing after a crash @@ -48,18 +51,20 @@ func (pvm *privValidatorMemory) SignHeartbeat(chainID string, heartbeat *tm_type return err } -func asTendermintSigner(signer acm.Signer) tm_types.Signer { +func asTendermintSigner(signer crypto.Signer) tm_types.Signer { return tendermintSigner{Signer: signer} } type tendermintSigner struct { - acm.Signer + crypto.Signer } -func (tms tendermintSigner) Sign(msg []byte) (crypto.Signature, error) { +func (tms tendermintSigner) Sign(msg []byte) (tm_crypto.Signature, error) { sig, err := tms.Signer.Sign(msg) if err != nil { - return crypto.Signature{}, err + return tm_crypto.Signature{}, err } - return sig.GoCryptoSignature(), nil + tm_sig := tm_crypto.SignatureEd25519{} + copy(tm_sig[:], sig.RawBytes()) + return tm_crypto.Signature{tm_sig}, nil } diff --git a/core/integration/test_wrapper.go b/core/integration/test_wrapper.go index b97c7986d1463c20657b3116ded733f8eb599651..8a0e5a46d47526e632c5903518cab7349b1fc75f 100644 --- a/core/integration/test_wrapper.go +++ b/core/integration/test_wrapper.go @@ -28,6 +28,7 @@ import ( "github.com/hyperledger/burrow/consensus/tendermint/validator" "github.com/hyperledger/burrow/core" "github.com/hyperledger/burrow/genesis" + "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/keys/mock" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/config" @@ -80,8 +81,8 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes validatorAccount := privateAccounts[0] privValidator := validator.NewPrivValidatorMemory(validatorAccount, validatorAccount) keyClient := mock.NewKeyClient(privateAccounts...) - kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(), - nil, logger) + kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), + nil, nil, logger) if err != nil { panic(err) } diff --git a/core/kernel.go b/core/kernel.go index 4f3df68b9d2e60cb391e81492c4d7d1c9ef3b1a8..437c43fcb9f24a07307ac7f186fa1271d6188912 100644 --- a/core/kernel.go +++ b/core/kernel.go @@ -17,6 +17,7 @@ package core import ( "context" "fmt" + "net" "net/http" _ "net/http/pprof" "os" @@ -33,6 +34,7 @@ import ( "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" + "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/process" @@ -44,6 +46,7 @@ import ( tm_config "github.com/tendermint/tendermint/config" tm_types "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tmlibs/db" + "google.golang.org/grpc" ) const ( @@ -65,8 +68,8 @@ type Kernel struct { } func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_types.PrivValidator, - genesisDoc *genesis.GenesisDoc, tmConf *tm_config.Config, rpcConfig *rpc.RPCConfig, - exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) { + genesisDoc *genesis.GenesisDoc, tmConf *tm_config.Config, rpcConfig *rpc.RPCConfig, keyConfig *keys.KeysConfig, + keyStore *keys.KeyStore, exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) { logger = logger.WithScope("NewKernel()").With(structure.TimeKey, kitlog.DefaultTimestampUTC) tmLogger := logger.With(structure.CallerKey, kitlog.Caller(LoggingCallerDepth+1)) @@ -111,7 +114,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t launchers := []process.Launcher{ { Name: "Profiling Server", - Disabled: rpcConfig.Profiler.Disabled, + Disabled: !rpcConfig.Profiler.Enabled, Launch: func() (process.Process, error) { debugServer := &http.Server{ Addr: ":6060", @@ -170,7 +173,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t }, { Name: "RPC/tm", - Disabled: rpcConfig.TM.Disabled, + Disabled: !rpcConfig.TM.Enabled, Launch: func() (process.Process, error) { listener, err := tm.StartServer(service, "/websocket", rpcConfig.TM.ListenAddress, emitter, logger) if err != nil { @@ -181,7 +184,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t }, { Name: "RPC/V0", - Disabled: rpcConfig.V0.Disabled, + Disabled: !rpcConfig.V0.Enabled, Launch: func() (process.Process, error) { codec := v0.NewTCodec() jsonServer := v0.NewJSONServer(v0.NewJSONService(codec, service, logger)) @@ -199,6 +202,37 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t return serveProcess, nil }, }, + { + Name: "grpc service", + Disabled: !rpcConfig.GRPC.Enabled, + Launch: func() (process.Process, error) { + listen, err := net.Listen("tcp", rpcConfig.GRPC.ListenAddress) + if err != nil { + return nil, err + } + + grpcServer := grpc.NewServer() + var ks keys.KeyStore + if keyStore != nil { + ks = *keyStore + } + + if keyConfig.GRPCServiceEnabled { + if keyStore == nil { + ks = keys.NewKeyStore(keyConfig.KeysDirectory) + } + pbkeys.RegisterKeysServer(grpcServer, &ks) + } + + go grpcServer.Serve(listen) + + return process.ShutdownFunc(func(ctx context.Context) error { + grpcServer.Stop() + // listener is closed for us + return nil + }), nil + }, + }, } return &Kernel{ diff --git a/core/kernel_test.go b/core/kernel_test.go index 5cd06d36e46d9946ea03a9f4a1832263f1ca1d24..e02ef7cd60463e64b0590a102be606cd7693c0e3 100644 --- a/core/kernel_test.go +++ b/core/kernel_test.go @@ -12,7 +12,7 @@ import ( "github.com/hyperledger/burrow/consensus/tendermint" "github.com/hyperledger/burrow/consensus/tendermint/validator" "github.com/hyperledger/burrow/genesis" - "github.com/hyperledger/burrow/keys/mock" + "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/rpc" "github.com/stretchr/testify/assert" @@ -65,8 +65,10 @@ func bootWaitBlocksShutdown(privValidator tm_types.PrivValidator, genesisDoc *ge tmConf *tm_config.Config, logger *logging.Logger, blockChecker func(block *tm_types.EventDataNewBlock) (cont bool)) error { - kern, err := NewKernel(context.Background(), mock.NewKeyClient(), privValidator, genesisDoc, tmConf, - rpc.DefaultRPCConfig(), nil, logger) + keyStore := keys.NewKeyStore(keys.DefaultKeysDir) + keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger()) + kern, err := NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, + rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), &keyStore, nil, logger) if err != nil { return err } diff --git a/account/address.go b/crypto/address.go similarity index 99% rename from account/address.go rename to crypto/address.go index 70353baccef9a398392e0a7be6d596e611523064..a72f8c02d9d4456d4e638780d902c0e3ecc09123 100644 --- a/account/address.go +++ b/crypto/address.go @@ -1,4 +1,4 @@ -package account +package crypto import ( "bytes" diff --git a/account/address_test.go b/crypto/address_test.go similarity index 99% rename from account/address_test.go rename to crypto/address_test.go index 5a1572b34d1d763435b2d3961d597ab9a56dd1e5..cf21319eaa9037307b62473c5258223ab539cca0 100644 --- a/account/address_test.go +++ b/crypto/address_test.go @@ -1,4 +1,4 @@ -package account +package crypto import ( "encoding/json" diff --git a/crypto/crypto.go b/crypto/crypto.go new file mode 100644 index 0000000000000000000000000000000000000000..da0e85dd0af80b0c12d026c551fd0b6ae8ed0389 --- /dev/null +++ b/crypto/crypto.go @@ -0,0 +1,361 @@ +package crypto + +import ( + "bytes" + crand "crypto/rand" + "crypto/sha256" + "encoding/json" + "fmt" + "io" + + "github.com/btcsuite/btcd/btcec" + tm_crypto "github.com/tendermint/go-crypto" + "github.com/tmthrgd/go-hex" + "golang.org/x/crypto/ed25519" + "golang.org/x/crypto/ripemd160" +) + +type CurveType int8 + +const ( + CurveTypeSecp256k1 CurveType = iota + CurveTypeEd25519 +) + +func (k CurveType) String() string { + switch k { + case CurveTypeSecp256k1: + return "secp256k1" + case CurveTypeEd25519: + return "ed25519" + default: + return "unknown" + } +} + +func CurveTypeFromString(s string) (CurveType, error) { + switch s { + case "secp256k1": + return CurveTypeSecp256k1, nil + case "ed25519": + return CurveTypeEd25519, nil + default: + var k CurveType + return k, ErrInvalidCurve(s) + } +} + +func (p PublicKey) AddressHashType() string { + switch p.CurveType { + case CurveTypeEd25519: + return "go-crypto-0.5.0" + case CurveTypeSecp256k1: + return "btc" + default: + return "" + } +} + +type ErrInvalidCurve string + +func (err ErrInvalidCurve) Error() string { + return fmt.Sprintf("invalid curve type") +} + +// The types in this file allow us to control serialisation of keys and signatures, as well as the interface +// exposed regardless of crypto library + +type Signer interface { + Sign(msg []byte) (Signature, error) +} + +// PublicKey +type PublicKey struct { + CurveType CurveType + PublicKey []byte +} + +type PrivateKey struct { + CurveType CurveType + PublicKey []byte + PrivateKey []byte +} + +type PublicKeyJSON struct { + CurveType string + PublicKey string +} + +func (p PublicKey) MarshalJSON() ([]byte, error) { + jStruct := PublicKeyJSON{ + CurveType: p.CurveType.String(), + PublicKey: hex.EncodeUpperToString(p.PublicKey), + } + txt, err := json.Marshal(jStruct) + return txt, err +} + +func (p PublicKey) MarshalText() ([]byte, error) { + return p.MarshalJSON() +} + +func (p *PublicKey) UnmarshalJSON(text []byte) error { + var jStruct PublicKeyJSON + err := json.Unmarshal(text, &jStruct) + if err != nil { + return err + } + CurveType, err := CurveTypeFromString(jStruct.CurveType) + if err != nil { + return err + } + bs, err := hex.DecodeString(jStruct.PublicKey) + if err != nil { + return err + } + p.CurveType = CurveType + p.PublicKey = bs + return nil +} + +func (p *PublicKey) UnmarshalText(text []byte) error { + return p.UnmarshalJSON(text) +} + +func (p PublicKey) IsValid() bool { + switch p.CurveType { + case CurveTypeEd25519: + return len(p.PublicKey) == ed25519.PublicKeySize + case CurveTypeSecp256k1: + return len(p.PublicKey) == btcec.PubKeyBytesLenCompressed + default: + return false + } +} +func (p PublicKey) Verify(msg []byte, signature Signature) bool { + switch p.CurveType { + case CurveTypeEd25519: + return ed25519.Verify(p.PublicKey, msg, signature.Signature[:]) + case CurveTypeSecp256k1: + pub, err := btcec.ParsePubKey(p.PublicKey, btcec.S256()) + if err != nil { + return false + } + sig, err := btcec.ParseDERSignature(signature.Signature, btcec.S256()) + if err != nil { + return false + } + return sig.Verify(msg, pub) + default: + panic(fmt.Sprintf("invalid curve type")) + } +} + +func (p PublicKey) Address() Address { + switch p.CurveType { + case CurveTypeEd25519: + // FIMXE: tendermint go-crypto-0.5.0 uses weird scheme, this is fixed in 0.6.0 + tmPubKey := new(tm_crypto.PubKeyEd25519) + copy(tmPubKey[:], p.PublicKey) + addr, _ := AddressFromBytes(tmPubKey.Address()) + return addr + case CurveTypeSecp256k1: + sha := sha256.New() + sha.Write(p.PublicKey[:]) + + hash := ripemd160.New() + hash.Write(sha.Sum(nil)) + addr, _ := AddressFromBytes(hash.Sum(nil)) + return addr + default: + panic(fmt.Sprintf("unknown CurveType %d", p.CurveType)) + } +} + +func (p PublicKey) RawBytes() []byte { + return p.PublicKey[:] +} + +func (p PublicKey) String() string { + return hex.EncodeUpperToString(p.PublicKey) +} + +// Signable is an interface for all signable things. +// It typically removes signatures before serializing. +type Signable interface { + WriteSignBytes(chainID string, w io.Writer, n *int, err *error) +} + +// SignBytes is a convenience method for getting the bytes to sign of a Signable. +func SignBytes(chainID string, o Signable) []byte { + buf, n, err := new(bytes.Buffer), new(int), new(error) + o.WriteSignBytes(chainID, buf, n, err) + if *err != nil { + panic(fmt.Sprintf("could not write sign bytes for a signable: %s", *err)) + } + return buf.Bytes() +} + +// Currently this is a stub that reads the raw bytes returned by key_client and returns +// an ed25519 public key. +func PublicKeyFromBytes(bs []byte, curveType CurveType) (PublicKey, error) { + switch curveType { + case CurveTypeEd25519: + if len(bs) != ed25519.PublicKeySize { + return PublicKey{}, fmt.Errorf("bytes passed have length %v but ed25519 public keys have %v bytes", + len(bs), ed25519.PublicKeySize) + } + case CurveTypeSecp256k1: + if len(bs) != btcec.PubKeyBytesLenCompressed { + return PublicKey{}, fmt.Errorf("bytes passed have length %v but secp256k1 public keys have %v bytes", + len(bs), btcec.PubKeyBytesLenCompressed) + } + default: + return PublicKey{}, ErrInvalidCurve(curveType) + } + + return PublicKey{PublicKey: bs, CurveType: curveType}, nil +} + +func (p PrivateKey) RawBytes() []byte { + return p.PrivateKey +} + +func (p PrivateKey) Sign(msg []byte) (Signature, error) { + switch p.CurveType { + case CurveTypeEd25519: + if len(p.PrivateKey) != ed25519.PrivateKeySize { + return Signature{}, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes", + len(p.PrivateKey), ed25519.PrivateKeySize) + } + privKey := ed25519.PrivateKey(p.PrivateKey) + return Signature{ed25519.Sign(privKey, msg)}, nil + case CurveTypeSecp256k1: + if len(p.PrivateKey) != btcec.PrivKeyBytesLen { + return Signature{}, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes", + len(p.PrivateKey), btcec.PrivKeyBytesLen) + } + privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), p.PrivateKey) + + sig, err := privKey.Sign(msg) + if err != nil { + return Signature{}, err + } + return Signature{Signature: sig.Serialize()}, nil + default: + return Signature{}, ErrInvalidCurve(p.CurveType) + } +} + +func (p PrivateKey) GetPublicKey() PublicKey { + return PublicKey{CurveType: p.CurveType, PublicKey: p.PublicKey} +} + +func PrivateKeyFromRawBytes(privKeyBytes []byte, curveType CurveType) (PrivateKey, error) { + switch curveType { + case CurveTypeEd25519: + if len(privKeyBytes) != ed25519.PrivateKeySize { + return PrivateKey{}, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes", + len(privKeyBytes), ed25519.PrivateKeySize) + } + return PrivateKey{PrivateKey: privKeyBytes, PublicKey: privKeyBytes[32:], CurveType: CurveTypeEd25519}, nil + case CurveTypeSecp256k1: + if len(privKeyBytes) != btcec.PrivKeyBytesLen { + return PrivateKey{}, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes", + len(privKeyBytes), btcec.PrivKeyBytesLen) + } + privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes) + return PrivateKey{PrivateKey: privKey.Serialize(), PublicKey: pubKey.SerializeCompressed(), CurveType: CurveTypeSecp256k1}, nil + default: + return PrivateKey{}, ErrInvalidCurve(curveType) + } +} + +func GeneratePrivateKey(random io.Reader, curveType CurveType) (PrivateKey, error) { + if random == nil { + random = crand.Reader + } + switch curveType { + case CurveTypeEd25519: + _, priv, err := ed25519.GenerateKey(random) + if err != nil { + return PrivateKey{}, err + } + return PrivateKeyFromRawBytes(priv, CurveTypeEd25519) + case CurveTypeSecp256k1: + privKeyBytes := make([]byte, 32) + _, err := random.Read(privKeyBytes) + if err != nil { + return PrivateKey{}, err + } + return PrivateKeyFromRawBytes(privKeyBytes, CurveTypeSecp256k1) + default: + return PrivateKey{}, ErrInvalidCurve(curveType) + } +} + +func PrivateKeyFromSecret(secret string, curveType CurveType) PrivateKey { + hasher := sha256.New() + hasher.Write(([]byte)(secret)) + // No error from a buffer + privateKey, _ := GeneratePrivateKey(bytes.NewBuffer(hasher.Sum(nil)), curveType) + return privateKey +} + +// Ensures the last 32 bytes of the ed25519 private key is the public key derived from the first 32 private bytes +func EnsureEd25519PrivateKeyCorrect(candidatePrivateKey ed25519.PrivateKey) error { + if len(candidatePrivateKey) != ed25519.PrivateKeySize { + return fmt.Errorf("ed25519 key has size %v but %v bytes passed as key", ed25519.PrivateKeySize, + len(candidatePrivateKey)) + } + _, derivedPrivateKey, err := ed25519.GenerateKey(bytes.NewBuffer(candidatePrivateKey)) + if err != nil { + return err + } + if !bytes.Equal(derivedPrivateKey, candidatePrivateKey) { + return fmt.Errorf("ed25519 key generated from prefix of %X should equal %X, but is %X", + candidatePrivateKey, candidatePrivateKey, derivedPrivateKey) + } + return nil +} + +func ChainSign(signer Signer, chainID string, o Signable) (Signature, error) { + sig, err := signer.Sign(SignBytes(chainID, o)) + if err != nil { + return Signature{}, err + } + return sig, nil +} + +// Signature + +type Signature struct { + Signature []byte +} + +// Currently this is a stub that reads the raw bytes returned by key_client and returns +// an ed25519 signature. +func SignatureFromBytes(bs []byte, curveType CurveType) (Signature, error) { + switch curveType { + case CurveTypeEd25519: + signatureEd25519 := Signature{} + if len(bs) != ed25519.SignatureSize { + return Signature{}, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes", + len(bs), ed25519.SignatureSize) + } + copy(signatureEd25519.Signature[:], bs) + return Signature{ + Signature: bs, + }, nil + case CurveTypeSecp256k1: + return Signature{ + Signature: bs, + }, nil + default: + return Signature{}, nil + } +} + +func (sig Signature) RawBytes() []byte { + return sig.Signature +} diff --git a/account/crypto_test.go b/crypto/crypto_test.go similarity index 95% rename from account/crypto_test.go rename to crypto/crypto_test.go index d412e0fc4c83a2ffc4a08088f3ae8182ce90caf5..45e7c897d44a98894826950dcb51d81e29e9bfcd 100644 --- a/account/crypto_test.go +++ b/crypto/crypto_test.go @@ -1,4 +1,4 @@ -package account +package crypto import ( "bytes" @@ -14,7 +14,7 @@ func TestGeneratePrivateKey(t *testing.T) { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, - })) + }), CurveTypeEd25519) require.NoError(t, err) assert.NoError(t, EnsureEd25519PrivateKeyCorrect(privateKey.RawBytes())) badKey := privateKey.RawBytes() diff --git a/crypto/helpers/helpers.go b/crypto/helpers/helpers.go new file mode 100644 index 0000000000000000000000000000000000000000..deed990ebe07792e3a5d700bad521b46a881da1c --- /dev/null +++ b/crypto/helpers/helpers.go @@ -0,0 +1,58 @@ +package helpers + +import ( + "bytes" + "fmt" + + "github.com/tendermint/ed25519" + "github.com/tendermint/go-wire" + "golang.org/x/crypto/ripemd160" +) + +type Signature interface { + IsZero() bool +} + +const ( + SignatureTypeEd25519 = byte(0x01) +) + +type SignatureEd25519 [64]byte + +func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } + +const ( + PrivKeyTypeEd25519 = byte(0x01) +) + +type PrivKeyEd25519 [64]byte + +const ( + PubKeyTypeEd25519 = byte(0x01) +) + +func (key PrivKeyEd25519) Sign(msg []byte) Signature { + privKeyBytes := [64]byte(key) + signatureBytes := ed25519.Sign(&privKeyBytes, msg) + return SignatureEd25519(*signatureBytes) +} + +// Implements PubKey +type PubKeyEd25519 [32]byte + +func (pubKey PubKeyEd25519) Address() []byte { + w, n, err := new(bytes.Buffer), new(int), new(error) + wire.WriteBinary(pubKey[:], w, n, err) + if *err != nil { + panic(fmt.Sprintf("failed to write tender public key: %v", err)) + } + // append type byte + encodedPubkey := append([]byte{1}, w.Bytes()...) + hasher := ripemd160.New() + hasher.Write(encodedPubkey) // does not error + return hasher.Sum(nil) +} + +type ( + Hash [32]byte +) diff --git a/deployment/config.go b/deployment/config.go index 8f1047b638d8465ae527fc887368add3842e61bd..b5ead42643ef360ee97f81b0b55f3c7b7ec96756 100644 --- a/deployment/config.go +++ b/deployment/config.go @@ -8,13 +8,13 @@ import ( "text/template" "github.com/hyperledger/burrow/config" - "github.com/hyperledger/burrow/keys/mock" + "github.com/hyperledger/burrow/keys" "github.com/pkg/errors" "github.com/tmthrgd/go-hex" ) type Package struct { - Keys []*mock.Key + Keys []*keys.Key BurrowConfig *config.BurrowConfig } diff --git a/deployment/config_test.go b/deployment/config_test.go deleted file mode 100644 index 3a159238b538bcca6274ed2370e96f0c049229bf..0000000000000000000000000000000000000000 --- a/deployment/config_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package deployment - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/keys/mock" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestMockKeyClient_DumpKeys(t *testing.T) { - keyClient := mock.NewKeyClient() - _, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - _, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - pkg := Package{Keys: keyClient.Keys()} - dump, err := pkg.Dump(DefaultDumpKeysFormat) - require.NoError(t, err) - - // Check JSON equal - var keys struct{ Keys []*mock.Key } - err = json.Unmarshal([]byte(dump), &keys) - require.NoError(t, err) - bs, err := json.MarshalIndent(keys, "", " ") - require.NoError(t, err) - assert.Equal(t, string(bs), dump) -} - -func TestMockKeyClient_DumpKeysKubernetes(t *testing.T) { - keyClient := mock.NewKeyClient() - _, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - _, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - pkg := Package{Keys: keyClient.Keys()} - dump, err := pkg.Dump(KubernetesKeyDumpFormat) - require.NoError(t, err) - fmt.Println(dump) -} - -func TestMockKeyClient_DumpKeysHelm(t *testing.T) { - keyClient := mock.NewKeyClient() - _, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - _, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - pkg := Package{Keys: keyClient.Keys()} - dump, err := pkg.Dump(HelmDumpKeysFormat) - require.NoError(t, err) - fmt.Println(dump) -} diff --git a/execution/accounts.go b/execution/accounts.go index 7602367eb35c66dfe23535d38bf6718ab25863b3..ec9d663c002dd3aaf928a62a480d060a77c11a57 100644 --- a/execution/accounts.go +++ b/execution/accounts.go @@ -6,6 +6,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys" burrow_sync "github.com/hyperledger/burrow/sync" ) @@ -20,7 +21,7 @@ type Accounts struct { type SigningAccount struct { acm.Account - acm.Signer + crypto.Signer } type SequentialSigningAccount struct { @@ -36,7 +37,7 @@ func NewAccounts(reader state.Reader, keyClient keys.KeyClient, mutexCount int) keyClient: keyClient, } } -func (accs *Accounts) SigningAccount(address acm.Address, signer acm.Signer) (*SigningAccount, error) { +func (accs *Accounts) SigningAccount(address crypto.Address, signer crypto.Signer) (*SigningAccount, error) { account, err := state.GetMutableAccount(accs, address) if err != nil { return nil, err @@ -58,7 +59,7 @@ func (accs *Accounts) SigningAccount(address acm.Address, signer acm.Signer) (*S }, nil } -func (accs *Accounts) SequentialSigningAccount(address acm.Address) *SequentialSigningAccount { +func (accs *Accounts) SequentialSigningAccount(address crypto.Address) *SequentialSigningAccount { signer := keys.Signer(accs.keyClient, address) return &SequentialSigningAccount{ accountLocker: accs.Mutex(address.Bytes()), diff --git a/execution/events/events.go b/execution/events/events.go index 2d4dd548b17ff083dcfd4d9fb338e3c1af9935b9..b9aa92df754ccdb8acff76523a183aa63d9ad694 100644 --- a/execution/events/events.go +++ b/execution/events/events.go @@ -6,19 +6,19 @@ import ( "fmt" "reflect" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/txs" "github.com/tmthrgd/go-hex" ) -func EventStringAccountInput(addr acm.Address) string { return fmt.Sprintf("Acc/%s/Input", addr) } -func EventStringAccountOutput(addr acm.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) } -func EventStringNameReg(name string) string { return fmt.Sprintf("NameReg/%s", name) } -func EventStringPermissions(name string) string { return fmt.Sprintf("Permissions/%s", name) } -func EventStringBond() string { return "Bond" } -func EventStringUnbond() string { return "Unbond" } -func EventStringRebond() string { return "Rebond" } +func EventStringAccountInput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Input", addr) } +func EventStringAccountOutput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) } +func EventStringNameReg(name string) string { return fmt.Sprintf("NameReg/%s", name) } +func EventStringPermissions(name string) string { return fmt.Sprintf("Permissions/%s", name) } +func EventStringBond() string { return "Bond" } +func EventStringUnbond() string { return "Unbond" } +func EventStringRebond() string { return "Rebond" } // All txs fire EventDataTx, but only CallTx might have Return or Exception type EventDataTx struct { @@ -65,7 +65,7 @@ func (edTx *EventDataTx) UnmarshalJSON(data []byte) error { // Publish/Subscribe func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscribable, subscriber string, - address acm.Address, txHash []byte, ch chan<- *txs.SendTx) error { + address crypto.Address, txHash []byte, ch chan<- *txs.SendTx) error { query := sendTxQuery.And(event.QueryForEventID(EventStringAccountOutput(address))). AndEquals(event.TxHashKey, hex.EncodeUpperToString(txHash)) @@ -80,7 +80,7 @@ func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscr }) } -func PublishAccountOutput(publisher event.Publisher, address acm.Address, txHash []byte, +func PublishAccountOutput(publisher event.Publisher, address crypto.Address, txHash []byte, tx txs.Tx, ret []byte, exception string) error { return event.PublishWithEventID(publisher, EventStringAccountOutput(address), @@ -96,7 +96,7 @@ func PublishAccountOutput(publisher event.Publisher, address acm.Address, txHash }) } -func PublishAccountInput(publisher event.Publisher, address acm.Address, txHash []byte, +func PublishAccountInput(publisher event.Publisher, address crypto.Address, txHash []byte, tx txs.Tx, ret []byte, exception string) error { return event.PublishWithEventID(publisher, EventStringAccountInput(address), diff --git a/execution/evm/accounts.go b/execution/evm/accounts.go index 800e6269b1afb7f39c2fcf77a7e79722cc5d4147..1bd61df33a38a91f98fa338e4023c163c71e5053 100644 --- a/execution/evm/accounts.go +++ b/execution/evm/accounts.go @@ -2,6 +2,7 @@ package evm import ( acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/logging" ptypes "github.com/hyperledger/burrow/permission/types" ) @@ -19,7 +20,7 @@ func DeriveNewAccount(creator acm.MutableAccount, permissions ptypes.AccountPerm "new_sequence", sequence+1) creator.IncSequence() - addr := acm.NewContractAddress(creator.Address(), sequence) + addr := crypto.NewContractAddress(creator.Address(), sequence) // Create account from address. return acm.ConcreteAccount{ diff --git a/execution/evm/events/events.go b/execution/evm/events/events.go index a9308bb5b075cfd6e6fe59a8de7d663ea86392e5..9ae628a7a829ac0c858811cd5643910abbffc7da 100644 --- a/execution/evm/events/events.go +++ b/execution/evm/events/events.go @@ -18,23 +18,23 @@ import ( "context" "fmt" - acm "github.com/hyperledger/burrow/account" . "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/tmthrgd/go-hex" ) // Functions to generate eventId strings -func EventStringAccountCall(addr acm.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) } -func EventStringLogEvent(addr acm.Address) string { return fmt.Sprintf("Log/%s", addr) } +func EventStringAccountCall(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) } +func EventStringLogEvent(addr crypto.Address) string { return fmt.Sprintf("Log/%s", addr) } //---------------------------------------- // EventDataCall fires when we call a contract, and when a contract calls another contract type EventDataCall struct { CallData *CallData - Origin acm.Address + Origin crypto.Address TxHash []byte StackDepth int Return []byte @@ -42,8 +42,8 @@ type EventDataCall struct { } type CallData struct { - Caller acm.Address - Callee acm.Address + Caller crypto.Address + Callee crypto.Address Data []byte Value uint64 Gas uint64 @@ -51,7 +51,7 @@ type CallData struct { // EventDataLog fires when a contract executes the LOG opcode type EventDataLog struct { - Address acm.Address + Address crypto.Address Topics []Word256 Data []byte Height uint64 @@ -62,7 +62,7 @@ type EventDataLog struct { // Subscribe to account call event - if TxHash is provided listens for a specifc Tx otherwise captures all, if // stackDepth is greater than or equal to 0 captures calls at a specific stack depth (useful for capturing the return // of the root call over recursive calls -func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable, subscriber string, address acm.Address, +func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address, txHash []byte, stackDepth int, ch chan<- *EventDataCall) error { query := event.QueryForEventID(EventStringAccountCall(address)) @@ -84,7 +84,7 @@ func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable, }) } -func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, subscriber string, address acm.Address, +func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address, ch chan<- *EventDataLog) error { query := event.QueryForEventID(EventStringLogEvent(address)) @@ -98,7 +98,7 @@ func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, sub }) } -func PublishAccountCall(publisher event.Publisher, address acm.Address, eventDataCall *EventDataCall) error { +func PublishAccountCall(publisher event.Publisher, address crypto.Address, eventDataCall *EventDataCall) error { return event.PublishWithEventID(publisher, EventStringAccountCall(address), eventDataCall, map[string]interface{}{ "address": address, @@ -107,7 +107,7 @@ func PublishAccountCall(publisher event.Publisher, address acm.Address, eventDat }) } -func PublishLogEvent(publisher event.Publisher, address acm.Address, eventDataLog *EventDataLog) error { +func PublishLogEvent(publisher event.Publisher, address crypto.Address, eventDataLog *EventDataLog) error { return event.PublishWithEventID(publisher, EventStringLogEvent(address), eventDataLog, map[string]interface{}{"address": address}) } diff --git a/execution/evm/fake_app_state.go b/execution/evm/fake_app_state.go index 7efbe82cd9e13d90ca7fa21b57d381f47f781f39..b618a48ad5b8a8885c032d6ec7ec6ea5c87c65f1 100644 --- a/execution/evm/fake_app_state.go +++ b/execution/evm/fake_app_state.go @@ -22,16 +22,17 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" . "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" ) type FakeAppState struct { - accounts map[acm.Address]acm.Account + accounts map[crypto.Address]acm.Account storage map[string]Word256 } var _ state.Writer = &FakeAppState{} -func (fas *FakeAppState) GetAccount(addr acm.Address) (acm.Account, error) { +func (fas *FakeAppState) GetAccount(addr crypto.Address) (acm.Account, error) { account := fas.accounts[addr] return account, nil } @@ -41,7 +42,7 @@ func (fas *FakeAppState) UpdateAccount(account acm.Account) error { return nil } -func (fas *FakeAppState) RemoveAccount(address acm.Address) error { +func (fas *FakeAppState) RemoveAccount(address crypto.Address) error { _, ok := fas.accounts[address] if !ok { panic(fmt.Sprintf("Invalid account addr: %s", address)) @@ -52,7 +53,7 @@ func (fas *FakeAppState) RemoveAccount(address acm.Address) error { return nil } -func (fas *FakeAppState) GetStorage(addr acm.Address, key Word256) (Word256, error) { +func (fas *FakeAppState) GetStorage(addr crypto.Address, key Word256) (Word256, error) { _, ok := fas.accounts[addr] if !ok { panic(fmt.Sprintf("Invalid account addr: %s", addr)) @@ -66,7 +67,7 @@ func (fas *FakeAppState) GetStorage(addr acm.Address, key Word256) (Word256, err } } -func (fas *FakeAppState) SetStorage(addr acm.Address, key Word256, value Word256) error { +func (fas *FakeAppState) SetStorage(addr crypto.Address, key Word256, value Word256) error { _, ok := fas.accounts[addr] if !ok { diff --git a/execution/evm/log_event_test.go b/execution/evm/log_event_test.go index 91808042a822a57643f624875f152c22412e9e84..500a97e7a9335a7c9bc7fc4137c7b8c9e41b7119 100644 --- a/execution/evm/log_event_test.go +++ b/execution/evm/log_event_test.go @@ -24,6 +24,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" . "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" . "github.com/hyperledger/burrow/execution/evm/asm" "github.com/hyperledger/burrow/execution/evm/events" @@ -46,15 +47,15 @@ func TestLog4(t *testing.T) { cache := state.NewCache(st) // Create accounts account1 := acm.ConcreteAccount{ - Address: acm.Address{1, 3, 5, 7, 9}, + Address: crypto.Address{1, 3, 5, 7, 9}, }.MutableAccount() account2 := acm.ConcreteAccount{ - Address: acm.Address{2, 4, 6, 8, 10}, + Address: crypto.Address{2, 4, 6, 8, 10}, }.MutableAccount() st.accounts[account1.Address()] = account1 st.accounts[account2.Address()] = account2 - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) emitter := event.NewEmitter(logging.NewNoopLogger()) diff --git a/execution/evm/snative.go b/execution/evm/snative.go index 1bb3e89cf7ddd0fbafde63c0328cd29c9084c514..8afbd171c84ed8a05e72c948dcc231958bfd4ee8 100644 --- a/execution/evm/snative.go +++ b/execution/evm/snative.go @@ -22,6 +22,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" . "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/evm/abi" "github.com/hyperledger/burrow/execution/evm/sha3" "github.com/hyperledger/burrow/logging" @@ -227,7 +228,7 @@ func NewSNativeContract(comment, name string, } type ErrLacksSNativePermission struct { - Address acm.Address + Address crypto.Address SNative string } @@ -276,7 +277,7 @@ func (contract *SNativeContractDescription) Dispatch(state state.Writer, caller // We define the address of an SNative contact as the last 20 bytes of the sha3 // hash of its name -func (contract *SNativeContractDescription) Address() (address acm.Address) { +func (contract *SNativeContractDescription) Address() (address crypto.Address) { hash := sha3.Sha3([]byte(contract.Name)) copy(address[:], hash[len(hash)-abi.AddressLength:]) return @@ -354,7 +355,7 @@ func hasBase(state state.Writer, caller acm.Account, args []byte, gas *uint64, logger *logging.Logger) (output []byte, err error) { addrWord256, permNum := returnTwoArgs(args) - address := acm.AddressFromWord256(addrWord256) + address := crypto.AddressFromWord256(addrWord256) acc, err := state.GetAccount(address) if err != nil { return nil, err @@ -380,7 +381,7 @@ func setBase(stateWriter state.Writer, caller acm.Account, args []byte, gas *uin logger *logging.Logger) (output []byte, err error) { addrWord256, permNum, permVal := returnThreeArgs(args) - address := acm.AddressFromWord256(addrWord256) + address := crypto.AddressFromWord256(addrWord256) acc, err := state.GetMutableAccount(stateWriter, address) if err != nil { return nil, err @@ -407,7 +408,7 @@ func unsetBase(stateWriter state.Writer, caller acm.Account, args []byte, gas *u logger *logging.Logger) (output []byte, err error) { addrWord256, permNum := returnTwoArgs(args) - address := acm.AddressFromWord256(addrWord256) + address := crypto.AddressFromWord256(addrWord256) acc, err := state.GetMutableAccount(stateWriter, address) if err != nil { return nil, err @@ -460,7 +461,7 @@ func hasRole(state state.Writer, caller acm.Account, args []byte, gas *uint64, logger *logging.Logger) (output []byte, err error) { addrWord256, role := returnTwoArgs(args) - address := acm.AddressFromWord256(addrWord256) + address := crypto.AddressFromWord256(addrWord256) acc, err := state.GetAccount(address) if err != nil { return nil, err @@ -481,7 +482,7 @@ func addRole(stateWriter state.Writer, caller acm.Account, args []byte, gas *uin logger *logging.Logger) (output []byte, err error) { addrWord256, role := returnTwoArgs(args) - address := acm.AddressFromWord256(addrWord256) + address := crypto.AddressFromWord256(addrWord256) acc, err := state.GetMutableAccount(stateWriter, address) if err != nil { return nil, err @@ -503,7 +504,7 @@ func removeRole(stateWriter state.Writer, caller acm.Account, args []byte, gas * logger *logging.Logger) (output []byte, err error) { addrWord256, role := returnTwoArgs(args) - address := acm.AddressFromWord256(addrWord256) + address := crypto.AddressFromWord256(addrWord256) acc, err := state.GetMutableAccount(stateWriter, address) if err != nil { return nil, err diff --git a/execution/evm/snative_test.go b/execution/evm/snative_test.go index 7c25aaf7910d884869ff6a43719a6f3120f9885c..3f5e5eae9cc0dba28c35f849dd587312b35f65b3 100644 --- a/execution/evm/snative_test.go +++ b/execution/evm/snative_test.go @@ -22,6 +22,7 @@ import ( acm "github.com/hyperledger/burrow/account" . "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/evm/abi" "github.com/hyperledger/burrow/execution/evm/asm/bc" "github.com/hyperledger/burrow/execution/evm/sha3" @@ -66,10 +67,10 @@ func TestSNativeContractDescription_Dispatch(t *testing.T) { contract := SNativeContracts()["Permissions"] state := newAppState() caller := acm.ConcreteAccount{ - Address: acm.Address{1, 1, 1}, + Address: crypto.Address{1, 1, 1}, }.MutableAccount() grantee := acm.ConcreteAccount{ - Address: acm.Address{2, 2, 2}, + Address: crypto.Address{2, 2, 2}, }.MutableAccount() state.UpdateAccount(grantee) diff --git a/execution/evm/vm.go b/execution/evm/vm.go index 32ea15dff619f8f8b1f9a8ea2d68d879fe9e3252..37e9ec0658cc31da92b6979453833772acb7d606 100644 --- a/execution/evm/vm.go +++ b/execution/evm/vm.go @@ -25,6 +25,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" . "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" . "github.com/hyperledger/burrow/execution/evm/asm" "github.com/hyperledger/burrow/execution/evm/events" @@ -68,8 +69,8 @@ func (err ErrPermission) Error() string { type ErrNestedCall struct { NestedError error - Caller acm.Address - Callee acm.Address + Caller crypto.Address + Callee crypto.Address StackDepth int } @@ -107,7 +108,7 @@ type Params struct { type VM struct { memoryProvider func() Memory params Params - origin acm.Address + origin crypto.Address txHash []byte stackDepth int nestedCallErrors []ErrNestedCall @@ -118,7 +119,7 @@ type VM struct { dumpTokens bool } -func NewVM(params Params, origin acm.Address, txid []byte, +func NewVM(params Params, origin crypto.Address, txid []byte, logger *logging.Logger, options ...func(*VM)) *VM { vm := &VM{ memoryProvider: DefaultDynamicMemoryProvider, @@ -156,7 +157,7 @@ func HasPermission(stateWriter state.Writer, acc acm.Account, perm ptypes.PermFl return value } -func (vm *VM) fireCallEvent(exception *string, output *[]byte, callerAddress, calleeAddress acm.Address, input []byte, value uint64, gas *uint64) { +func (vm *VM) fireCallEvent(exception *string, output *[]byte, callerAddress, calleeAddress crypto.Address, input []byte, value uint64, gas *uint64) { // fire the post call event (including exception if applicable) if vm.publisher != nil { events.PublishAccountCall(vm.publisher, calleeAddress, &events.EventDataCall{ @@ -569,7 +570,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable if useGasNegative(gas, GasGetAccount, &err) { return nil, err } - acc, errAcc := callState.GetAccount(acm.AddressFromWord256(addr)) + acc, errAcc := callState.GetAccount(crypto.AddressFromWord256(addr)) if errAcc != nil { return nil, firstErr(err, errAcc) } @@ -665,7 +666,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable if useGasNegative(gas, GasGetAccount, &err) { return nil, err } - acc, errAcc := callState.GetAccount(acm.AddressFromWord256(addr)) + acc, errAcc := callState.GetAccount(crypto.AddressFromWord256(addr)) if errAcc != nil { return nil, firstErr(err, errAcc) } @@ -686,7 +687,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable if useGasNegative(gas, GasGetAccount, &err) { return nil, err } - acc, errAcc := callState.GetAccount(acm.AddressFromWord256(addr)) + acc, errAcc := callState.GetAccount(crypto.AddressFromWord256(addr)) if errAcc != nil { return nil, firstErr(err, errAcc) } @@ -1015,13 +1016,13 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable exception = callErr.Error() } // NOTE: these fire call go_events and not particular go_events for eg name reg or permissions - vm.fireCallEvent(&exception, &ret, callee.Address(), acm.AddressFromWord256(addr), args, value, &gasLimit) + vm.fireCallEvent(&exception, &ret, callee.Address(), crypto.AddressFromWord256(addr), args, value, &gasLimit) } else { // EVM contract if useGasNegative(gas, GasGetAccount, &callErr) { return nil, callErr } - acc, errAcc := state.GetMutableAccount(callState, acm.AddressFromWord256(addr)) + acc, errAcc := state.GetMutableAccount(callState, crypto.AddressFromWord256(addr)) if errAcc != nil { return nil, firstErr(callErr, errAcc) } @@ -1045,7 +1046,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable if !HasPermission(callState, caller, permission.CreateAccount) { return nil, ErrPermission{"create_account"} } - acc = acm.ConcreteAccount{Address: acm.AddressFromWord256(addr)}.MutableAccount() + acc = acm.ConcreteAccount{Address: crypto.AddressFromWord256(addr)}.MutableAccount() } // add account to the tx cache callState.UpdateAccount(acc) @@ -1128,7 +1129,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable if useGasNegative(gas, GasGetAccount, &err) { return nil, err } - receiver, errAcc := state.GetMutableAccount(callState, acm.AddressFromWord256(addr)) + receiver, errAcc := state.GetMutableAccount(callState, crypto.AddressFromWord256(addr)) if errAcc != nil { return nil, firstErr(err, errAcc) } diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go index edce8d7d8f0f057bab30d54e7d32adb88753dbfb..fcd008459d25238492445e8acf065ef7dce91b8a 100644 --- a/execution/evm/vm_test.go +++ b/execution/evm/vm_test.go @@ -26,6 +26,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" . "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" . "github.com/hyperledger/burrow/execution/evm/asm" . "github.com/hyperledger/burrow/execution/evm/asm/bc" @@ -45,7 +46,7 @@ var logger = logging.NewNoopLogger() func newAppState() *FakeAppState { fas := &FakeAppState{ - accounts: make(map[acm.Address]acm.Account), + accounts: make(map[crypto.Address]acm.Account), storage: make(map[string]Word256), } // For default permissions @@ -68,14 +69,14 @@ func newAccount(seed ...byte) acm.MutableAccount { hasher := ripemd160.New() hasher.Write(seed) return acm.ConcreteAccount{ - Address: acm.MustAddressFromBytes(hasher.Sum(nil)), + Address: crypto.MustAddressFromBytes(hasher.Sum(nil)), }.MutableAccount() } // Runs a basic loop func TestVM(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) // Create accounts account1 := newAccount(1) @@ -98,7 +99,7 @@ func TestVM(t *testing.T) { func TestSHL(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) account1 := newAccount(1) account2 := newAccount(1, 0, 1) @@ -247,7 +248,7 @@ func TestSHL(t *testing.T) { func TestSHR(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) account1 := newAccount(1) account2 := newAccount(1, 0, 1) @@ -400,7 +401,7 @@ func TestSHR(t *testing.T) { func TestSAR(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) account1 := newAccount(1) account2 := newAccount(1, 0, 1) @@ -572,7 +573,7 @@ func TestSAR(t *testing.T) { //Test attempt to jump to bad destination (position 16) func TestJumpErr(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) // Create accounts account1 := newAccount(1) @@ -612,7 +613,7 @@ func TestSubcurrency(t *testing.T) { //st.accounts[account1.Address()] = account1 //st.accounts[account2.Address()] = account2 - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) var gas uint64 = 1000 @@ -642,7 +643,7 @@ func TestSubcurrency(t *testing.T) { //it is meant to test the implementation of the REVERT opcode func TestRevert(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) // Create accounts account1 := newAccount(1) @@ -675,7 +676,7 @@ func TestRevert(t *testing.T) { // Test sending tokens from a contract to another account func TestSendCall(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) // Create accounts account1 := newAccount(1) @@ -716,7 +717,7 @@ func TestSendCall(t *testing.T) { // and then run it with 1 gas unit less, expecting a failure func TestDelegateCallGas(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) inOff := 0 inSize := 0 // no call data @@ -777,7 +778,7 @@ func TestMemoryBounds(t *testing.T) { memoryProvider := func() Memory { return NewDynamicMemory(1024, 2048) } - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger, MemoryProvider(memoryProvider)) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger, MemoryProvider(memoryProvider)) caller, _ := makeAccountWithCode(cache, "caller", nil) callee, _ := makeAccountWithCode(cache, "callee", nil) gas := uint64(100000) @@ -828,7 +829,7 @@ func TestMsgSender(t *testing.T) { //st.accounts[account1.Address()] = account1 //st.accounts[account2.Address()] = account2 - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) var gas uint64 = 100000 @@ -870,7 +871,7 @@ func TestMsgSender(t *testing.T) { func TestInvalid(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) // Create accounts account1 := newAccount(1) @@ -891,7 +892,7 @@ func TestInvalid(t *testing.T) { func TestReturnDataSize(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) accountName := "account2addresstests" @@ -930,7 +931,7 @@ func TestReturnDataSize(t *testing.T) { func TestReturnDataCopy(t *testing.T) { cache := state.NewCache(newAppState()) - ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger) + ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) accountName := "account2addresstests" @@ -995,8 +996,8 @@ func returnWord() []byte { } func makeAccountWithCode(accountUpdater state.AccountUpdater, name string, - code []byte) (acm.MutableAccount, acm.Address) { - address, _ := acm.AddressFromBytes([]byte(name)) + code []byte) (acm.MutableAccount, crypto.Address) { + address, _ := crypto.AddressFromBytes([]byte(name)) account := acm.ConcreteAccount{ Address: address, Balance: 9999999, @@ -1011,7 +1012,7 @@ func makeAccountWithCode(accountUpdater state.AccountUpdater, name string, // and then waits for any exceptions transmitted by Data in the AccCall // event (in the case of no direct error from call we will block waiting for // at least 1 AccCall event) -func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr acm.Address, +func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr crypto.Address, contractCode []byte, gas uint64) ([]byte, error) { eventCh := make(chan *evm_events.EventDataCall) output, err := runVM(eventCh, vmCache, ourVm, caller, callee, subscribeAddr, contractCode, gas) @@ -1030,7 +1031,7 @@ func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAc // Subscribes to an AccCall, runs the vm, returns the output and any direct // exception func runVM(eventCh chan<- *evm_events.EventDataCall, vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount, - subscribeAddr acm.Address, contractCode []byte, gas uint64) ([]byte, error) { + subscribeAddr crypto.Address, contractCode []byte, gas uint64) ([]byte, error) { // we need to catch the event from the CALL to check for exceptions emitter := event.NewEmitter(logging.NewNoopLogger()) @@ -1052,7 +1053,7 @@ func runVM(eventCh chan<- *evm_events.EventDataCall, vmCache state.Cache, ourVm } // this is code to call another contract (hardcoded as addr) -func callContractCode(addr acm.Address) []byte { +func callContractCode(addr crypto.Address) []byte { gas1, gas2 := byte(0x1), byte(0x1) value := byte(0x69) inOff, inSize := byte(0x0), byte(0x0) // no call data @@ -1109,7 +1110,7 @@ func TestBytecode(t *testing.T) { []byte{}, MustSplice(MustSplice(MustSplice()))) - contractAccount := &acm.ConcreteAccount{Address: acm.AddressFromWord256(Int64ToWord256(102))} + contractAccount := &acm.ConcreteAccount{Address: crypto.AddressFromWord256(Int64ToWord256(102))} addr := contractAccount.Address gas1, gas2 := byte(0x1), byte(0x1) value := byte(0x69) diff --git a/execution/execution.go b/execution/execution.go index a26646e00096aba66eaf2cb4bb1ee33190c36091..3e7068f2408195bd4036747ec6d147c807c0a43b 100644 --- a/execution/execution.go +++ b/execution/execution.go @@ -23,6 +23,7 @@ import ( "github.com/hyperledger/burrow/account/state" "github.com/hyperledger/burrow/binary" bcm "github.com/hyperledger/burrow/blockchain" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution/events" "github.com/hyperledger/burrow/execution/evm" @@ -111,14 +112,14 @@ func newExecutor(name string, runCall bool, backend *State, chainID string, tip // to always access the freshest mempool state as needed by accounts.SequentialSigningAccount // // Accounts -func (exe *executor) GetAccount(address acm.Address) (acm.Account, error) { +func (exe *executor) GetAccount(address crypto.Address) (acm.Account, error) { exe.RLock() defer exe.RUnlock() return exe.stateCache.GetAccount(address) } // Storage -func (exe *executor) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) { +func (exe *executor) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { exe.RLock() defer exe.RUnlock() return exe.stateCache.GetStorage(address, key) @@ -196,7 +197,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) { return err } - signBytes := acm.SignBytes(exe.chainID, tx) + signBytes := crypto.SignBytes(exe.chainID, tx) inTotal, err := validateInputs(accounts, signBytes, tx.Inputs) if err != nil { return err @@ -270,7 +271,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) { "tx_input", tx.Input) return err } - signBytes := acm.SignBytes(exe.chainID, tx) + signBytes := crypto.SignBytes(exe.chainID, tx) err = validateInput(inAcc, signBytes, tx.Input) if err != nil { logger.InfoMsg("validateInput failed", @@ -472,7 +473,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) { "tx_input", tx.Input) return err } - signBytes := acm.SignBytes(exe.chainID, tx) + signBytes := crypto.SignBytes(exe.chainID, tx) err = validateInput(inAcc, signBytes, tx.Input) if err != nil { logger.InfoMsg("validateInput failed", @@ -783,7 +784,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) { "tx_input", tx.Input) return err } - signBytes := acm.SignBytes(exe.chainID, tx) + signBytes := crypto.SignBytes(exe.chainID, tx) err = validateInput(inAcc, signBytes, tx.Input) if err != nil { logger.InfoMsg("validateInput failed", @@ -876,7 +877,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) { } } -func mutatePermissions(stateReader state.Reader, address acm.Address, +func mutatePermissions(stateReader state.Reader, address crypto.Address, mutator func(*ptypes.AccountPermissions) error) (acm.Account, error) { account, err := stateReader.GetAccount(address) @@ -1025,9 +1026,9 @@ func execBlock(s *State, block *txs.Block, blockPartsHeader txs.PartSetHeader) e // or it must be specified in the TxInput. If redeclared, // the TxInput is modified and input.PublicKey() set to nil. func getInputs(accountGetter state.AccountGetter, - ins []*txs.TxInput) (map[acm.Address]acm.MutableAccount, error) { + ins []*txs.TxInput) (map[crypto.Address]acm.MutableAccount, error) { - accounts := map[acm.Address]acm.MutableAccount{} + accounts := map[crypto.Address]acm.MutableAccount{} for _, in := range ins { // Account shouldn't be duplicated if _, ok := accounts[in.Address]; ok { @@ -1049,10 +1050,10 @@ func getInputs(accountGetter state.AccountGetter, return accounts, nil } -func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[acm.Address]acm.MutableAccount, - outs []*txs.TxOutput, logger *logging.Logger) (map[acm.Address]acm.MutableAccount, error) { +func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount, + outs []*txs.TxOutput, logger *logging.Logger) (map[crypto.Address]acm.MutableAccount, error) { if accs == nil { - accs = make(map[acm.Address]acm.MutableAccount) + accs = make(map[crypto.Address]acm.MutableAccount) } // we should err if an account is being created but the inputs don't have permission @@ -1093,8 +1094,8 @@ func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[acm.Address]ac // If it does then we will associate the public key with the stub account already registered in the system once and // for all time. func checkInputPubKey(acc acm.MutableAccount, in *txs.TxInput) error { - if acc.PublicKey().Unwrap() == nil { - if in.PublicKey.Unwrap() == nil { + if !acc.PublicKey().IsValid() { + if !in.PublicKey.IsValid() { return txs.ErrTxUnknownPubKey } addressFromPubKey := in.PublicKey.Address() @@ -1104,12 +1105,12 @@ func checkInputPubKey(acc acm.MutableAccount, in *txs.TxInput) error { } acc.SetPublicKey(in.PublicKey) } else { - in.PublicKey = acm.PublicKey{} + in.PublicKey = crypto.PublicKey{} } return nil } -func validateInputs(accs map[acm.Address]acm.MutableAccount, signBytes []byte, ins []*txs.TxInput) (uint64, error) { +func validateInputs(accs map[crypto.Address]acm.MutableAccount, signBytes []byte, ins []*txs.TxInput) (uint64, error) { total := uint64(0) for _, in := range ins { acc := accs[in.Address] @@ -1132,7 +1133,7 @@ func validateInput(acc acm.MutableAccount, signBytes []byte, in *txs.TxInput) er return err } // Check signatures - if !acc.PublicKey().VerifyBytes(signBytes, in.Signature) { + if !acc.PublicKey().Verify(signBytes, in.Signature) { return txs.ErrTxInvalidSignature } // Check sequences @@ -1162,7 +1163,7 @@ func validateOutputs(outs []*txs.TxOutput) (uint64, error) { return total, nil } -func adjustByInputs(accs map[acm.Address]acm.MutableAccount, ins []*txs.TxInput, logger *logging.Logger) error { +func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*txs.TxInput, logger *logging.Logger) error { for _, in := range ins { acc := accs[in.Address] if acc == nil { @@ -1187,7 +1188,7 @@ func adjustByInputs(accs map[acm.Address]acm.MutableAccount, ins []*txs.TxInput, return nil } -func adjustByOutputs(accs map[acm.Address]acm.MutableAccount, outs []*txs.TxOutput) error { +func adjustByOutputs(accs map[crypto.Address]acm.MutableAccount, outs []*txs.TxOutput) error { for _, out := range outs { acc := accs[out.Address] if acc == nil { @@ -1237,7 +1238,7 @@ func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm ptyp } // TODO: for debug log the failed accounts -func hasSendPermission(accountGetter state.AccountGetter, accs map[acm.Address]acm.MutableAccount, +func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount, logger *logging.Logger) bool { for _, acc := range accs { if !HasPermission(accountGetter, acc, permission.Send, logger) { @@ -1262,7 +1263,7 @@ func hasCreateContractPermission(accountGetter state.AccountGetter, acc acm.Acco return HasPermission(accountGetter, acc, permission.CreateContract, logger) } -func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[acm.Address]acm.MutableAccount, +func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount, logger *logging.Logger) bool { for _, acc := range accs { if !HasPermission(accountGetter, acc, permission.CreateAccount, logger) { @@ -1277,7 +1278,7 @@ func hasBondPermission(accountGetter state.AccountGetter, acc acm.Account, return HasPermission(accountGetter, acc, permission.Bond, logger) } -func hasBondOrSendPermission(accountGetter state.AccountGetter, accs map[acm.Address]acm.Account, +func hasBondOrSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.Account, logger *logging.Logger) bool { for _, acc := range accs { if !HasPermission(accountGetter, acc, permission.Bond, logger) { diff --git a/execution/execution_test.go b/execution/execution_test.go index b5ff92b288f58b3f132ffd17a007eeff62712c1d..41c1d1cb78ce7cf822fe5b907d0d58da419c69b9 100644 --- a/execution/execution_test.go +++ b/execution/execution_test.go @@ -26,6 +26,7 @@ import ( "github.com/hyperledger/burrow/account/state" . "github.com/hyperledger/burrow/binary" bcm "github.com/hyperledger/burrow/blockchain" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" exe_events "github.com/hyperledger/burrow/execution/events" "github.com/hyperledger/burrow/execution/evm" @@ -408,7 +409,7 @@ func TestCallPermission(t *testing.T) { fmt.Println("\n##### SIMPLE CONTRACT") // create simple contract - simpleContractAddr := acm.NewContractAddress(users[0].Address(), 100) + simpleContractAddr := crypto.NewContractAddress(users[0].Address(), 100) simpleAcc := acm.ConcreteAccount{ Address: simpleContractAddr, Balance: 0, @@ -432,7 +433,7 @@ func TestCallPermission(t *testing.T) { // create contract that calls the simple contract contractCode := callContractCode(simpleContractAddr) - caller1ContractAddr := acm.NewContractAddress(users[0].Address(), 101) + caller1ContractAddr := crypto.NewContractAddress(users[0].Address(), 101) caller1Acc := acm.ConcreteAccount{ Address: caller1ContractAddr, Balance: 10000, @@ -476,7 +477,7 @@ func TestCallPermission(t *testing.T) { fmt.Println("\n##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (FAIL)") contractCode2 := callContractCode(caller1ContractAddr) - caller2ContractAddr := acm.NewContractAddress(users[0].Address(), 102) + caller2ContractAddr := crypto.NewContractAddress(users[0].Address(), 102) caller2Acc := acm.ConcreteAccount{ Address: caller2ContractAddr, Balance: 1000, @@ -542,7 +543,7 @@ func TestCreatePermission(t *testing.T) { t.Fatal("Transaction failed", err) } // ensure the contract is there - contractAddr := acm.NewContractAddress(tx.Input.Address, tx.Input.Sequence) + contractAddr := crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence) contractAcc := getAccount(batchCommitter.stateCache, contractAddr) if contractAcc == nil { t.Fatalf("failed to create contract %s", contractAddr) @@ -567,7 +568,7 @@ func TestCreatePermission(t *testing.T) { t.Fatal("Transaction failed", err) } // ensure the contract is there - contractAddr = acm.NewContractAddress(tx.Input.Address, tx.Input.Sequence) + contractAddr = crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence) contractAcc = getAccount(batchCommitter.stateCache, contractAddr) if contractAcc == nil { t.Fatalf("failed to create contract %s", contractAddr) @@ -607,9 +608,9 @@ func TestCreatePermission(t *testing.T) { //-------------------------------- fmt.Println("\n##### CALL to empty address") - code := callContractCode(acm.Address{}) + code := callContractCode(crypto.Address{}) - contractAddr = acm.NewContractAddress(users[0].Address(), 110) + contractAddr = crypto.NewContractAddress(users[0].Address(), 110) contractAcc = acm.ConcreteAccount{ Address: contractAddr, Balance: 1000, @@ -626,11 +627,11 @@ func TestCreatePermission(t *testing.T) { tx, _ = txs.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 10000, 100) tx.Sign(testChainID, users[0]) // we need to subscribe to the Call event to detect the exception - _, exception = execTxWaitEvent(t, batchCommitter, tx, evm_events.EventStringAccountCall(acm.Address{})) // + _, exception = execTxWaitEvent(t, batchCommitter, tx, evm_events.EventStringAccountCall(crypto.Address{})) // if exception != "" { t.Fatal("unexpected exception", exception) } - zeroAcc := getAccount(batchCommitter.stateCache, acm.Address{}) + zeroAcc := getAccount(batchCommitter.stateCache, crypto.Address{}) if len(zeroAcc.Code()) != 0 { t.Fatal("the zero account was given code from a CALL!") } @@ -736,7 +737,7 @@ func TestCreateAccountPermission(t *testing.T) { // call to contract that calls unknown account - without create_account perm // create contract that calls the simple contract contractCode := callContractCode(users[9].Address()) - caller1ContractAddr := acm.NewContractAddress(users[4].Address(), 101) + caller1ContractAddr := crypto.NewContractAddress(users[4].Address(), 101) caller1Acc := acm.ConcreteAccount{ Address: caller1ContractAddr, Balance: 0, @@ -775,7 +776,7 @@ func TestCreateAccountPermission(t *testing.T) { } // holla at my boy -var DougAddress acm.Address +var DougAddress crypto.Address func init() { copy(DougAddress[:], ([]byte)("THISISDOUG")) @@ -1072,7 +1073,7 @@ func TestNameTxs(t *testing.T) { } } - validateEntry := func(t *testing.T, entry *NameRegEntry, name, data string, addr acm.Address, expires uint64) { + validateEntry := func(t *testing.T, entry *NameRegEntry, name, data string, addr crypto.Address, expires uint64) { if entry == nil { t.Fatalf("Could not find name %s", name) @@ -1721,12 +1722,12 @@ func makeGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV return s0, privAccounts } -func getAccount(accountGetter state.AccountGetter, address acm.Address) acm.MutableAccount { +func getAccount(accountGetter state.AccountGetter, address crypto.Address) acm.MutableAccount { acc, _ := state.GetMutableAccount(accountGetter, address) return acc } -func addressPtr(account acm.Account) *acm.Address { +func addressPtr(account acm.Account) *crypto.Address { if account == nil { return nil } @@ -1775,18 +1776,18 @@ func execTxWaitEvent(t *testing.T, batchCommitter *executor, tx txs.Tx, eventid // give a contract perms for an snative, call it, it calls the snative, but shouldn't have permission func testSNativeCALLExpectFail(t *testing.T, batchCommitter *executor, doug acm.MutableAccount, - snativeAddress acm.Address, data []byte) { + snativeAddress crypto.Address, data []byte) { testSNativeCALL(t, false, batchCommitter, doug, 0, snativeAddress, data, nil) } // give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds func testSNativeCALLExpectPass(t *testing.T, batchCommitter *executor, doug acm.MutableAccount, snativePerm ptypes.PermFlag, - snativeAddress acm.Address, data []byte, f func([]byte) error) { + snativeAddress crypto.Address, data []byte, f func([]byte) error) { testSNativeCALL(t, true, batchCommitter, doug, snativePerm, snativeAddress, data, f) } func testSNativeCALL(t *testing.T, expectPass bool, batchCommitter *executor, doug acm.MutableAccount, - snativePerm ptypes.PermFlag, snativeAddress acm.Address, data []byte, f func([]byte) error) { + snativePerm ptypes.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) { if expectPass { doug.MutablePermissions().Base.Set(snativePerm, true) } @@ -1868,7 +1869,7 @@ func permNameToFuncID(name string) []byte { } func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm ptypes.PermFlag, - val bool) (addr acm.Address, pF ptypes.PermFlag, data []byte) { + val bool) (addr crypto.Address, pF ptypes.PermFlag, data []byte) { addr = permissionsContract.Address() switch name { case "hasBase", "unsetBase": @@ -1907,7 +1908,7 @@ func snativePermTestInputTx(name string, user acm.AddressableSigner, perm ptypes } func snativeRoleTestInputCALL(name string, user acm.AddressableSigner, - role string) (addr acm.Address, pF ptypes.PermFlag, data []byte) { + role string) (addr crypto.Address, pF ptypes.PermFlag, data []byte) { addr = permissionsContract.Address() data = user.Address().Word256().Bytes() data = append(data, RightPadBytes([]byte(role), 32)...) @@ -1933,7 +1934,7 @@ func snativeRoleTestInputTx(name string, user acm.AddressableSigner, role string } // convenience function for contract that calls a given address -func callContractCode(contractAddr acm.Address) []byte { +func callContractCode(contractAddr crypto.Address) []byte { // calldatacopy into mem and use as input to call memOff, inputOff := byte(0x0), byte(0x0) value := byte(0x1) diff --git a/execution/namereg.go b/execution/namereg.go index 50babf2a15b60ae8f6d9143cbc3284c1bed9afd8..0c57b351c540e019ae6ab2f68d7e61bb8c5f650c 100644 --- a/execution/namereg.go +++ b/execution/namereg.go @@ -14,7 +14,7 @@ package execution -import "github.com/hyperledger/burrow/account" +import "github.com/hyperledger/burrow/crypto" // NameReg provides a global key value store based on Name, Data pairs that are subject to expiry and ownership by an // account. @@ -22,7 +22,7 @@ type NameRegEntry struct { // registered name for the entry Name string // address that created the entry - Owner account.Address + Owner crypto.Address // data to store under this name Data string // block at which this entry expires diff --git a/execution/state.go b/execution/state.go index 8c9b739e36da0fecdb7e2efa9be58987f982c47a..1521faad675e176da33f16e62525217afff2bf78 100644 --- a/execution/state.go +++ b/execution/state.go @@ -24,6 +24,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/logging" ptypes "github.com/hyperledger/burrow/permission" @@ -176,7 +177,7 @@ func (s *State) Hash() []byte { } // Returns nil if account does not exist with given address. -func (s *State) GetAccount(address acm.Address) (acm.Account, error) { +func (s *State) GetAccount(address crypto.Address) (acm.Account, error) { s.RLock() defer s.RUnlock() _, accBytes := s.tree.Get(prefixedKey(accountsPrefix, address.Bytes())) @@ -204,7 +205,7 @@ func (s *State) UpdateAccount(account acm.Account) error { return nil } -func (s *State) RemoveAccount(address acm.Address) error { +func (s *State) RemoveAccount(address crypto.Address) error { s.Lock() defer s.Unlock() s.tree.Remove(prefixedKey(accountsPrefix, address.Bytes())) @@ -225,14 +226,14 @@ func (s *State) IterateAccounts(consumer func(acm.Account) (stop bool)) (stopped return } -func (s *State) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) { +func (s *State) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { s.RLock() defer s.RUnlock() _, value := s.tree.Get(prefixedKey(storagePrefix, address.Bytes(), key.Bytes())) return binary.LeftPadWord256(value), nil } -func (s *State) SetStorage(address acm.Address, key, value binary.Word256) error { +func (s *State) SetStorage(address crypto.Address, key, value binary.Word256) error { s.Lock() defer s.Unlock() if value == binary.Zero256 { @@ -243,7 +244,7 @@ func (s *State) SetStorage(address acm.Address, key, value binary.Word256) error return nil } -func (s *State) IterateStorage(address acm.Address, +func (s *State) IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) { s.RLock() defer s.RUnlock() diff --git a/execution/transactor.go b/execution/transactor.go index d6e2206d3a8dcf40e220d8a7dd6a777cea4eb665..96f90c2d260a192bb81f9a1f88548ae48b2c16e7 100644 --- a/execution/transactor.go +++ b/execution/transactor.go @@ -27,6 +27,7 @@ import ( "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/consensus/tendermint/codes" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" exe_events "github.com/hyperledger/burrow/execution/events" "github.com/hyperledger/burrow/execution/evm" @@ -67,7 +68,7 @@ func NewTransactor(tip blockchain.Tip, eventEmitter event.Emitter, // Run a contract's code on an isolated and unpersisted state // Cannot be used to create new contracts -func (trans *Transactor) Call(reader state.Reader, fromAddress, toAddress acm.Address, +func (trans *Transactor) Call(reader state.Reader, fromAddress, toAddress crypto.Address, data []byte) (call *Call, err error) { if evm.RegisteredNativeContract(toAddress.Word256()) { @@ -106,7 +107,7 @@ func (trans *Transactor) Call(reader state.Reader, fromAddress, toAddress acm.Ad // Run the given code on an isolated and unpersisted state // Cannot be used to create new contracts. -func (trans *Transactor) CallCode(reader state.Reader, fromAddress acm.Address, code, data []byte) (*Call, error) { +func (trans *Transactor) CallCode(reader state.Reader, fromAddress crypto.Address, code, data []byte) (*Call, error) { // This was being run against CheckTx cache, need to understand the reasoning callee := acm.ConcreteAccount{Address: fromAddress}.MutableAccount() caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount() @@ -162,7 +163,7 @@ func (trans *Transactor) BroadcastTx(tx txs.Tx) (*txs.Receipt, error) { } // Orders calls to BroadcastTx using lock (waits for response from core before releasing) -func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAccount, address *acm.Address, data []byte, +func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAccount, address *crypto.Address, data []byte, gasLimit, fee uint64) (*txs.Receipt, error) { // Use the get the freshest sequence numbers from mempool state and hold the lock until we get a response from @@ -185,7 +186,7 @@ func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAcc return trans.BroadcastTx(callTx) } -func (trans *Transactor) TransactAndHold(sequentialSigningAccount *SequentialSigningAccount, address *acm.Address, data []byte, gasLimit, +func (trans *Transactor) TransactAndHold(sequentialSigningAccount *SequentialSigningAccount, address *crypto.Address, data []byte, gasLimit, fee uint64) (*evm_events.EventDataCall, error) { inputAccount, unlock, err := sequentialSigningAccount.Lock() @@ -239,7 +240,7 @@ func (trans *Transactor) TransactAndHold(sequentialSigningAccount *SequentialSig } } } -func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address *acm.Address, data []byte, +func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address *crypto.Address, data []byte, gasLimit, fee uint64) (*txs.CallTx, *txs.Receipt, error) { txInput := &txs.TxInput{ @@ -265,7 +266,7 @@ func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address * return tx, &receipt, nil } -func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount, toAddress acm.Address, +func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount, toAddress crypto.Address, amount uint64) (*txs.Receipt, error) { inputAccount, unlock, err := sequentialSigningAccount.Lock() @@ -282,7 +283,7 @@ func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount return trans.BroadcastTx(sendTx) } -func (trans *Transactor) SendAndHold(sequentialSigningAccount *SequentialSigningAccount, toAddress acm.Address, +func (trans *Transactor) SendAndHold(sequentialSigningAccount *SequentialSigningAccount, toAddress crypto.Address, amount uint64) (*txs.Receipt, error) { inputAccount, unlock, err := sequentialSigningAccount.Lock() @@ -334,7 +335,7 @@ func (trans *Transactor) SendAndHold(sequentialSigningAccount *SequentialSigning } } -func (trans *Transactor) formulateSendTx(inputAccount *SigningAccount, toAddress acm.Address, +func (trans *Transactor) formulateSendTx(inputAccount *SigningAccount, toAddress crypto.Address, amount uint64) (*txs.SendTx, *txs.Receipt, error) { sendTx := txs.NewSendTx() diff --git a/genesis/deterministic_genesis.go b/genesis/deterministic_genesis.go index de80e258883a9598a7ab32ce5310952d6d9ad95b..ca023f2617dad40d527ec32e078b7718618f6531 100644 --- a/genesis/deterministic_genesis.go +++ b/genesis/deterministic_genesis.go @@ -6,6 +6,7 @@ import ( "time" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/permission" ) @@ -66,14 +67,14 @@ func (dg *deterministicGenesis) GenesisDoc(numAccounts int, randBalance bool, mi } func (dg *deterministicGenesis) Account(randBalance bool, minBalance uint64) (acm.Account, acm.AddressableSigner) { - privateKey, err := acm.GeneratePrivateKey(dg.random) + privateKey, err := crypto.GeneratePrivateKey(dg.random, crypto.CurveTypeEd25519) if err != nil { panic(fmt.Errorf("could not generate private key deterministically")) } privAccount := &acm.ConcretePrivateAccount{ - PublicKey: privateKey.PublicKey(), + PublicKey: privateKey.GetPublicKey(), PrivateKey: privateKey, - Address: privateKey.PublicKey().Address(), + Address: privateKey.GetPublicKey().Address(), } perms := permission.DefaultAccountPermissions acc := &acm.ConcreteAccount{ diff --git a/genesis/genesis.go b/genesis/genesis.go index 1c4d0341b49eb295ecf08180b43359a355afda03..16edbe3303664304af5148d25cdffed1554c7810 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -22,6 +22,7 @@ import ( "time" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/permission" ptypes "github.com/hyperledger/burrow/permission/types" ) @@ -36,8 +37,8 @@ const ShortHashSuffixBytes = 3 type BasicAccount struct { // Address is convenient to have in file for reference, but otherwise ignored since derived from PublicKey - Address acm.Address - PublicKey acm.PublicKey + Address crypto.Address + PublicKey crypto.PublicKey Amount uint64 } diff --git a/genesis/spec/genesis_spec.go b/genesis/spec/genesis_spec.go index 343b7eaf6d6072ce8caf1d3a4f892cc0a83b22cb..48d8443a968d3385abb6278f9ce5e2e71dd96477 100644 --- a/genesis/spec/genesis_spec.go +++ b/genesis/spec/genesis_spec.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/permission" @@ -35,13 +35,12 @@ type TemplateAccount struct { // Template accounts sharing a name will be merged when merging genesis specs Name string `json:",omitempty" toml:",omitempty"` // Address is convenient to have in file for reference, but otherwise ignored since derived from PublicKey - Address *acm.Address `json:",omitempty" toml:",omitempty"` - PublicKey *acm.PublicKey `json:",omitempty" toml:",omitempty"` - Amount *uint64 `json:",omitempty" toml:",omitempty"` - // If any bonded amount then this account is also a Validator - AmountBonded *uint64 `json:",omitempty" toml:",omitempty"` - Permissions []string `json:",omitempty" toml:",omitempty"` - Roles []string `json:",omitempty" toml:",omitempty"` + Address *crypto.Address `json:",omitempty" toml:",omitempty"` + PublicKey *crypto.PublicKey `json:",omitempty" toml:",omitempty"` + Amount *uint64 `json:",omitempty" toml:",omitempty"` + AmountBonded *uint64 `json:",omitempty" toml:",omitempty"` + Permissions []string `json:",omitempty" toml:",omitempty"` + Roles []string `json:",omitempty" toml:",omitempty"` } func (ta TemplateAccount) Validator(keyClient keys.KeyClient, index int) (*genesis.Validator, error) { @@ -111,11 +110,11 @@ func (ta TemplateAccount) Account(keyClient keys.KeyClient, index int) (*genesis // Adds a public key and address to the template. If PublicKey will try to fetch it by Address. // If both PublicKey and Address are not set will use the keyClient to generate a new keypair -func (ta TemplateAccount) RealisePubKeyAndAddress(keyClient keys.KeyClient) (pubKey acm.PublicKey, address acm.Address, err error) { +func (ta TemplateAccount) RealisePubKeyAndAddress(keyClient keys.KeyClient) (pubKey crypto.PublicKey, address crypto.Address, err error) { if ta.PublicKey == nil { if ta.Address == nil { // If neither PublicKey or Address set then generate a new one - address, err = keyClient.Generate(ta.Name, keys.KeyTypeEd25519Ripemd160) + address, err = keyClient.Generate(ta.Name, crypto.CurveTypeEd25519) if err != nil { return } @@ -128,7 +127,7 @@ func (ta TemplateAccount) RealisePubKeyAndAddress(keyClient keys.KeyClient) (pub return } } else { - address = ta.PublicKey.Address() + address = (*ta.PublicKey).Address() if ta.Address != nil && *ta.Address != address { err = fmt.Errorf("template address %s does not match public key derived address %s", ta.Address, ta.PublicKey) diff --git a/genesis/spec/genesis_spec_test.go b/genesis/spec/genesis_spec_test.go index 294c4ed315e600d9907ecd7d749c979d9eac1896..ca91146fb71be6356ffd55abd31cec4590fc0b0b 100644 --- a/genesis/spec/genesis_spec_test.go +++ b/genesis/spec/genesis_spec_test.go @@ -3,7 +3,7 @@ package spec import ( "testing" - "github.com/hyperledger/burrow/keys" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys/mock" "github.com/hyperledger/burrow/permission" "github.com/stretchr/testify/assert" @@ -33,7 +33,7 @@ func TestGenesisSpec_GenesisDoc(t *testing.T) { assert.Equal(t, amtBonded, genesisDoc.Validators[0].Amount) assert.NotEmpty(t, genesisDoc.ChainName, "Chain name should not be empty") - address, err := keyClient.Generate("test-lookup-of-key", keys.KeyTypeEd25519Ripemd160) + address, err := keyClient.Generate("test-lookup-of-key", crypto.CurveTypeEd25519) require.NoError(t, err) pubKey, err := keyClient.PublicKey(address) require.NoError(t, err) diff --git a/keys/common/paths.go b/keys/common/paths.go new file mode 100644 index 0000000000000000000000000000000000000000..075800636f3034306f135db7fff728811bace0c5 --- /dev/null +++ b/keys/common/paths.go @@ -0,0 +1,38 @@ +package common + +import ( + "os" + "path/filepath" + "runtime" +) + +func HomeDir() string { + if runtime.GOOS == "windows" { + drive := os.Getenv("HOMEDRIVE") + path := os.Getenv("HOMEPATH") + if drive == "" || path == "" { + return os.Getenv("USERPROFILE") + } + return drive + path + } else { + return os.Getenv("HOME") + } +} + +func ResolveMonaxRoot() string { + var monax string + if os.Getenv("MONAX") != "" { + monax = os.Getenv("MONAX") + } else { + if runtime.GOOS == "windows" { + home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") + if home == "" { + home = os.Getenv("USERPROFILE") + } + monax = filepath.Join(home, ".monax") + } else { + monax = filepath.Join(HomeDir(), ".monax") + } + } + return monax +} diff --git a/keys/config.go b/keys/config.go index 2286cabf282d14f97602bad3b7250b0f03a0bf78..d50d61338f9934dbb9301c36ee6878142e1ac81c 100644 --- a/keys/config.go +++ b/keys/config.go @@ -1,12 +1,16 @@ package keys type KeysConfig struct { - URL string + GRPCServiceEnabled bool + RemoteAddress string + KeysDirectory string } func DefaultKeysConfig() *KeysConfig { return &KeysConfig{ // Default Monax keys port - URL: "http://localhost:4767", + GRPCServiceEnabled: true, + RemoteAddress: "", + KeysDirectory: DefaultKeysDir, } } diff --git a/keys/core.go b/keys/core.go new file mode 100644 index 0000000000000000000000000000000000000000..8642a820b331dc99c5ea8c43f30d99210886d433 --- /dev/null +++ b/keys/core.go @@ -0,0 +1,191 @@ +package keys + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + "strings" + + tmint_crypto "github.com/hyperledger/burrow/crypto/helpers" + wire "github.com/tendermint/go-wire" +) + +const ( + DefaultHost = "localhost" + DefaultPort = "10997" + DefaultHashType = "sha256" + DefaultKeysDir = ".keys" + TestPort = "7674" +) + +func returnDataDir(dir string) (string, error) { + dir = path.Join(dir, "data") + dir, err := filepath.Abs(dir) + if err != nil { + return "", err + } + return dir, checkMakeDataDir(dir) +} + +func returnNamesDir(dir string) (string, error) { + dir = path.Join(dir, "names") + dir, err := filepath.Abs(dir) + if err != nil { + return "", err + } + return dir, checkMakeDataDir(dir) +} + +//----- + +func NewKeyStore(dir string) KeyStore { + return KeyStore{keysDirPath: dir} +} + +//---------------------------------------------------------------- +func writeKey(keyDir string, addr, keyJson []byte) ([]byte, error) { + dir, err := returnDataDir(keyDir) + if err != nil { + return nil, fmt.Errorf("Failed to get keys dir: %v", err) + } + if err := WriteKeyFile(addr, dir, keyJson); err != nil { + return nil, err + } + return addr, nil +} + +func coreExport(key *Key) ([]byte, error) { + type privValidator struct { + Address []byte `json:"address"` + PubKey []interface{} `json:"pub_key"` + PrivKey []interface{} `json:"priv_key"` + LastHeight int `json:"last_height"` + LastRound int `json:"last_round"` + LastStep int `json:"last_step"` + } + + pub := key.Pubkey() + + var pubKeyWithType []interface{} + var pubKey tmint_crypto.PubKeyEd25519 + copy(pubKey[:], pub) + pubKeyWithType = append(pubKeyWithType, tmint_crypto.PubKeyTypeEd25519) + pubKeyWithType = append(pubKeyWithType, pubKey) + + var privKeyWithType []interface{} + var privKey tmint_crypto.PrivKeyEd25519 + copy(privKey[:], key.PrivateKey.RawBytes()) + privKeyWithType = append(privKeyWithType, tmint_crypto.PrivKeyTypeEd25519) + privKeyWithType = append(privKeyWithType, privKey) + + privVal := &privValidator{ + Address: key.Address[:], + PubKey: pubKeyWithType, + PrivKey: privKeyWithType, + } + + return wire.JSONBytes(privVal), nil +} + +//---------------------------------------------------------------- +// manage names for keys + +func coreNameAdd(keysDir, name, addr string) error { + namesDir, err := returnNamesDir(keysDir) + if err != nil { + return err + } + dataDir, err := returnDataDir(keysDir) + if err != nil { + return err + } + if _, err := os.Stat(path.Join(dataDir, addr+".json")); err != nil { + return fmt.Errorf("Unknown key %s", addr) + } + return ioutil.WriteFile(path.Join(namesDir, name), []byte(addr), 0600) +} + +func coreNameList(keysDir string) (map[string]string, error) { + dir, err := returnNamesDir(keysDir) + if err != nil { + return nil, err + } + names := make(map[string]string) + fs, err := ioutil.ReadDir(dir) + if err != nil { + return nil, err + } + for _, f := range fs { + b, err := ioutil.ReadFile(path.Join(dir, f.Name())) + if err != nil { + return nil, err + } + names[f.Name()] = string(b) + } + return names, nil +} + +func coreAddrList(keysDir string) (map[int]string, error) { + dir, err := returnDataDir(keysDir) + if err != nil { + return nil, err + } + addrs := make(map[int]string) + fs, err := ioutil.ReadDir(dir) + if err != nil { + return nil, err + } + for i := 0; i < len(fs); i++ { + addrs[i] = fs[i].Name() + } + return addrs, nil +} + +func coreNameRm(keysDir string, name string) error { + dir, err := returnNamesDir(keysDir) + if err != nil { + return err + } + return os.Remove(path.Join(dir, name)) +} + +func coreNameGet(keysDir, name string) (string, error) { + dir, err := returnNamesDir(keysDir) + if err != nil { + return "", err + } + b, err := ioutil.ReadFile(path.Join(dir, name)) + if err != nil { + return "", err + } + return string(b), nil +} + +func checkMakeDataDir(dir string) error { + if _, err := os.Stat(dir); err != nil { + err = os.MkdirAll(dir, 0700) + if err != nil { + return err + } + } + return nil +} + +// return addr from name or addr +func getNameAddr(keysDir, name, addr string) (string, error) { + if name == "" && addr == "" { + return "", fmt.Errorf("at least one of name or addr must be provided") + } + + // name takes precedent if both are given + var err error + if name != "" { + addr, err = coreNameGet(keysDir, name) + if err != nil { + return "", err + } + } + return strings.ToUpper(addr), nil +} diff --git a/keys/integration/key_client_test.go b/keys/integration/key_client_test.go deleted file mode 100644 index 83f5d4b6282521292a2326b1d76ee41599b53d47..0000000000000000000000000000000000000000 --- a/keys/integration/key_client_test.go +++ /dev/null @@ -1,134 +0,0 @@ -// +build integration - -// Space above here matters -package integration - -import ( - "fmt" - "io/ioutil" - "os" - "os/exec" - "testing" - "time" - - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/logging" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -//var logger, _ = lifecycle.NewStdErrLogger() -var logger = logging.NewNoopLogger() - -const monaxKeysBin = "monax-keys" -const keysHost = "localhost" -const keysPort = "56667" -const keysTimeoutSeconds = 3 - -var rpcString = fmt.Sprintf("http://%s:%s", keysHost, keysPort) - -func TestMain(m *testing.M) { - fmt.Fprint(os.Stderr, "Running monax-keys using test main\n") - _, err := exec.LookPath(monaxKeysBin) - if err != nil { - fatalf("could not run keys integration tests because could not find keys binary: %v", err) - } - - keysDir, err := ioutil.TempDir("", "key_client_test") - if err != nil { - fatalf("could not create temp dir: %v", err) - } - cmd := exec.Command(monaxKeysBin, "server", "--dir", keysDir, "--port", keysPort) - err = cmd.Start() - if err != nil { - fatalf("could not start command: %v", err) - } - - select { - case <-waitKeysRunning(): - // A plain call to os.Exit will terminate before deferred calls run, so defer that too. - defer os.Exit(m.Run()) - case <-time.After(keysTimeoutSeconds * time.Second): - defer fatalf("timed out waiting for monax-keys to become live") - } - - defer func() { - err := cmd.Process.Kill() - if err != nil { - fmt.Fprintf(os.Stderr, "Error killing monax-keys from test main:%v\n", err) - } - fmt.Fprint(os.Stderr, "Killed monax-keys from test main\n") - }() -} - -func TestMonaxKeyClient_Generate(t *testing.T) { - keyClient := keys.NewKeyClient(rpcString, logger) - addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160) - assert.NoError(t, err) - assert.NotEqual(t, acm.ZeroAddress, addr) -} - -func TestMonaxKeyClient_PublicKey(t *testing.T) { - keyClient := keys.NewKeyClient(rpcString, logger) - addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160) - assert.NoError(t, err) - pubKey, err := keyClient.PublicKey(addr) - assert.Equal(t, addr, pubKey.Address()) -} - -func TestMonaxKeyClient_PublicKey_NonExistent(t *testing.T) { - keyClient := keys.NewKeyClient(rpcString, logger) - _, err := keyClient.PublicKey(acm.Address{8, 7, 6, 222}) - assert.Error(t, err) -} - -func TestMonaxKeyClient_Sign(t *testing.T) { - keyClient := keys.NewKeyClient(rpcString, logger) - addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - pubKey, err := keyClient.PublicKey(addr) - assert.NoError(t, err) - message := []byte("I'm a hat, a hat, a hat") - signature, err := keyClient.Sign(addr, message) - assert.NoError(t, err) - assert.True(t, pubKey.VerifyBytes(message, signature), "signature should verify message") -} - -func TestMonaxKeyClient_HealthCheck(t *testing.T) { - deadKeyClient := keys.NewKeyClient("http://localhost:99999", logger) - assert.NotNil(t, deadKeyClient.HealthCheck()) - keyClient := keys.NewKeyClient(rpcString, logger) - assert.Nil(t, keyClient.HealthCheck()) -} - -func TestPublicKeyAddressAgreement(t *testing.T) { - keyClient := keys.NewKeyClient(rpcString, logger) - addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160) - require.NoError(t, err) - pubKey, err := keyClient.PublicKey(addr) - addrOut := pubKey.Address() - require.NoError(t, err) - assert.Equal(t, addr, addrOut) -} - -func fatalf(format string, a ...interface{}) { - fmt.Fprintf(os.Stderr, format, a...) - os.Exit(1) -} - -func waitKeysRunning() chan bool { - ch := make(chan bool) - keyClient := keys.NewKeyClient(rpcString, logger) - go func() { - for { - err := keyClient.HealthCheck() - if err == nil { - ch <- true - return - } - } - - }() - return ch -} diff --git a/keys/key_client.go b/keys/key_client.go index c70cb4aecca9af987937d6f50675c5def19f4bce..49983e41c987427e403b747b41a96cbe5234cb11 100644 --- a/keys/key_client.go +++ b/keys/key_client.go @@ -15,71 +15,177 @@ package keys import ( - "encoding/hex" + "context" "fmt" + "time" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging" + "google.golang.org/grpc" ) type KeyClient interface { // Sign returns the signature bytes for given message signed with the key associated with signAddress - Sign(signAddress acm.Address, message []byte) (signature acm.Signature, err error) + Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) // PublicKey returns the public key associated with a given address - PublicKey(address acm.Address) (publicKey acm.PublicKey, err error) + PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) // Generate requests that a key be generate within the keys instance and returns the address - Generate(keyName string, keyType KeyType) (keyAddress acm.Address, err error) + Generate(keyName string, keyType crypto.CurveType) (keyAddress crypto.Address, err error) // Returns nil if the keys instance is healthy, error otherwise HealthCheck() error } -// This mirrors "github.com/monax/keys/crypto/KeyType" but since we have no use for the struct here it seems simpler -// to replicate rather than cop an import -type KeyType string +var _ KeyClient = (*localKeyClient)(nil) +var _ KeyClient = (*remoteKeyClient)(nil) -func (kt KeyType) String() string { - return string(kt) +type localKeyClient struct { + ks KeyStore + logger *logging.Logger } -const ( - KeyTypeEd25519Ripemd160 KeyType = "ed25519,ripemd160" - KeyTypeEd25519Ripemd160sha256 = "ed25519,ripemd160sha256" - KeyTypeEd25519Ripemd160sha3 = "ed25519,sha3" - KeyTypeSecp256k1Ripemd160 = "secp256k1,ripemd160" - KeyTypeSecp256k1Ripemd160sha256 = "secp256k1,ripemd160sha256" - KeyTypeSecp256k1Ripemd160sha3 = "secp256k1,sha3" - KeyTypeDefault = KeyTypeEd25519Ripemd160 -) +type remoteKeyClient struct { + rpcAddress string + kc pbkeys.KeysClient + logger *logging.Logger +} + +func (l localKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) { + resp, err := l.ks.Sign(nil, &pbkeys.SignRequest{Address: signAddress.String(), Message: message}) + if err != nil { + return crypto.Signature{}, err + } + curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + if err != nil { + return crypto.Signature{}, err + } + return crypto.SignatureFromBytes(resp.GetSignature(), curveType) +} + +func (l localKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) { + resp, err := l.ks.PublicKey(nil, &pbkeys.PubRequest{Address: address.String()}) + if err != nil { + return crypto.PublicKey{}, err + } + curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + if err != nil { + return crypto.PublicKey{}, err + } + return crypto.PublicKeyFromBytes(resp.GetPub(), curveType) +} -// NOTE [ben] Compiler check to ensure keyClient successfully implements -// burrow/keys.KeyClient -var _ KeyClient = (*keyClient)(nil) +// Generate requests that a key be generate within the keys instance and returns the address +func (l localKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) { + resp, err := l.ks.GenerateKey(nil, &pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()}) + if err != nil { + return crypto.Address{}, err + } + return crypto.AddressFromHexString(resp.GetAddress()) +} -type keyClient struct { - requester Requester - logger *logging.Logger +// Returns nil if the keys instance is healthy, error otherwise +func (l localKeyClient) HealthCheck() error { + return nil } -type signer struct { - keyClient KeyClient - address acm.Address +func (l remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + req := pbkeys.SignRequest{Address: signAddress.String(), Message: message} + l.logger.TraceMsg("Sending Sign request to remote key server: ", fmt.Sprintf("%v", req)) + resp, err := l.kc.Sign(ctx, &req) + if err != nil { + l.logger.TraceMsg("Received Sign request error response: ", err) + return crypto.Signature{}, err + } + l.logger.TraceMsg("Received Sign response to remote key server: %v", resp) + curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + if err != nil { + return crypto.Signature{}, err + } + return crypto.SignatureFromBytes(resp.GetSignature(), curveType) +} + +func (l remoteKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + req := pbkeys.PubRequest{Address: address.String()} + l.logger.TraceMsg("Sending PublicKey request to remote key server: ", fmt.Sprintf("%v", req)) + resp, err := l.kc.PublicKey(ctx, &req) + if err != nil { + l.logger.TraceMsg("Received PublicKey error response: ", err) + return crypto.PublicKey{}, err + } + curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + if err != nil { + return crypto.PublicKey{}, err + } + l.logger.TraceMsg("Received PublicKey response to remote key server: ", fmt.Sprintf("%v", resp)) + return crypto.PublicKeyFromBytes(resp.GetPub(), curveType) +} + +// Generate requests that a key be generate within the keys instance and returns the address +func (l remoteKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + req := pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()} + l.logger.TraceMsg("Sending Generate request to remote key server: ", fmt.Sprintf("%v", req)) + resp, err := l.kc.GenerateKey(ctx, &req) + if err != nil { + l.logger.TraceMsg("Received Generate error response: ", err) + return crypto.Address{}, err + } + l.logger.TraceMsg("Received Generate response to remote key server: ", fmt.Sprintf("%v", resp)) + return crypto.AddressFromHexString(resp.GetAddress()) +} + +// Returns nil if the keys instance is healthy, error otherwise +func (l remoteKeyClient) HealthCheck() error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + _, err := l.kc.List(ctx, &pbkeys.Name{""}) + return err } // keyClient.New returns a new monax-keys client for provided rpc location // Monax-keys connects over http request-responses -func NewKeyClient(rpcAddress string, logger *logging.Logger) *keyClient { - logger = logger.WithScope("NewKeyClient") - return &keyClient{ - requester: DefaultRequester(rpcAddress, logger), - logger: logger, +func NewRemoteKeyClient(rpcAddress string, logger *logging.Logger) (KeyClient, error) { + logger = logger.WithScope("RemoteKeyClient") + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + conn, err := grpc.Dial(rpcAddress, opts...) + if err != nil { + return nil, err } + kc := pbkeys.NewKeysClient(conn) + + return remoteKeyClient{kc: kc, rpcAddress: rpcAddress, logger: logger}, nil +} + +func NewLocalKeyClient(ks KeyStore, logger *logging.Logger) KeyClient { + logger = logger.WithScope("LocalKeyClient") + return localKeyClient{ks: ks, logger: logger} +} + +type signer struct { + keyClient KeyClient + address crypto.Address +} + +func (ms *signer) Sign(messsage []byte) (crypto.Signature, error) { + signature, err := ms.keyClient.Sign(ms.address, messsage) + if err != nil { + return crypto.Signature{}, err + } + return signature, nil } // Creates a Signer that assumes the address holds an Ed25519 key -func Signer(keyClient KeyClient, address acm.Address) acm.Signer { +func Signer(keyClient KeyClient, address crypto.Address) crypto.Signer { // TODO: we can do better than this and return a typed signature when we reform the keys service return &signer{ keyClient: keyClient, @@ -88,19 +194,19 @@ func Signer(keyClient KeyClient, address acm.Address) acm.Signer { } type keyAddressable struct { - publicKey acm.PublicKey - address acm.Address + publicKey crypto.PublicKey + address crypto.Address } -func (ka *keyAddressable) Address() acm.Address { +func (ka *keyAddressable) Address() crypto.Address { return ka.address } -func (ka *keyAddressable) PublicKey() acm.PublicKey { +func (ka *keyAddressable) PublicKey() crypto.PublicKey { return ka.publicKey } -func Addressable(keyClient KeyClient, address acm.Address) (acm.Addressable, error) { +func Addressable(keyClient KeyClient, address crypto.Address) (acm.Addressable, error) { pubKey, err := keyClient.PublicKey(address) if err != nil { return nil, err @@ -110,69 +216,3 @@ func Addressable(keyClient KeyClient, address acm.Address) (acm.Addressable, err publicKey: pubKey, }, nil } - -func (ms *signer) Sign(messsage []byte) (acm.Signature, error) { - signature, err := ms.keyClient.Sign(ms.address, messsage) - if err != nil { - return acm.Signature{}, err - } - return signature, nil -} - -// Monax-keys client Sign requests the signature from BurrowKeysClient over rpc for the given -// bytes to be signed and the address to sign them with. -func (kc *keyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) { - sigS, err := kc.requester("sign", map[string]string{ - "msg": hex.EncodeToString(message), - "addr": signAddress.String(), - }) - if err != nil { - return acm.Signature{}, err - } - sigBytes, err := hex.DecodeString(sigS) - if err != nil { - return acm.Signature{}, err - } - return acm.SignatureFromBytes(sigBytes) -} - -// Monax-keys client PublicKey requests the public key associated with an address from -// the monax-keys server. -func (kc *keyClient) PublicKey(address acm.Address) (acm.PublicKey, error) { - pubS, err := kc.requester("pub", map[string]string{ - "addr": address.String(), - }) - if err != nil { - return acm.PublicKey{}, err - } - pubKeyBytes, err := hex.DecodeString(pubS) - if err != nil { - return acm.PublicKey{}, err - } - publicKey, err := acm.PublicKeyFromBytes(pubKeyBytes) - if err != nil { - return acm.PublicKey{}, err - } - if address != publicKey.Address() { - return acm.PublicKey{}, fmt.Errorf("public key %s maps to address %s but was returned for address %s", - publicKey, publicKey.Address(), address) - } - return publicKey, nil -} - -func (kc *keyClient) Generate(keyName string, keyType KeyType) (acm.Address, error) { - addr, err := kc.requester("gen", map[string]string{ - //"auth": auth, - "name": keyName, - "type": keyType.String(), - }) - if err != nil { - return acm.ZeroAddress, err - } - return acm.AddressFromHexString(addr) -} - -func (kc *keyClient) HealthCheck() error { - _, err := kc.requester("name/ls", nil) - return err -} diff --git a/keys/key_client_util.go b/keys/key_client_util.go deleted file mode 100644 index 89a41a366d359b1fc2cc90377fa20f5c9e004e08..0000000000000000000000000000000000000000 --- a/keys/key_client_util.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keys - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - "github.com/hyperledger/burrow/logging" -) - -// Monax-Keys server connects over http request-response structures - -type HTTPResponse struct { - Response string - Error string -} - -type Requester func(method string, args map[string]string) (response string, err error) - -func DefaultRequester(rpcAddress string, logger *logging.Logger) Requester { - return func(method string, args map[string]string) (string, error) { - body, err := json.Marshal(args) - if err != nil { - return "", err - } - endpoint := fmt.Sprintf("%s/%s", rpcAddress, method) - logger.TraceMsg("Sending request to key server", - "key_server_endpoint", endpoint, - "request_body", string(body), - ) - req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(body)) - if err != nil { - return "", err - } - req.Header.Add("Content-Type", "application/json") - res, err := requestResponse(req) - if err != nil { - return "", fmt.Errorf("error calling monax-keys at %s: %s", endpoint, err.Error()) - } - if res.Error != "" { - return "", fmt.Errorf("response error when calling monax-keys at %s: %s", endpoint, res.Error) - } - logger.TraceMsg("Received response from key server", - "endpoint", endpoint, - "request_body", string(body), - "response", res, - ) - return res.Response, nil - } -} - -func requestResponse(req *http.Request) (*HTTPResponse, error) { - client := new(http.Client) - resp, err := client.Do(req) - if err != nil { - return nil, err - } - if resp.StatusCode >= 400 { - return nil, fmt.Errorf(resp.Status) - } - bs, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - httpResponse := new(HTTPResponse) - if err := json.Unmarshal(bs, httpResponse); err != nil { - return nil, err - } - return httpResponse, nil -} diff --git a/keys/key_store.go b/keys/key_store.go new file mode 100644 index 0000000000000000000000000000000000000000..fe6c3d54ba306ea46a3dc17ebe1141216be17df3 --- /dev/null +++ b/keys/key_store.go @@ -0,0 +1,68 @@ +package keys + +import ( + "github.com/hyperledger/burrow/crypto" +) + +type Key struct { + CurveType crypto.CurveType + Address crypto.Address + PublicKey crypto.PublicKey + PrivateKey crypto.PrivateKey +} + +func NewKey(typ crypto.CurveType) (*Key, error) { + privKey, err := crypto.GeneratePrivateKey(nil, typ) + if err != nil { + return nil, err + } + pubKey := privKey.GetPublicKey() + return &Key{ + CurveType: typ, + PublicKey: pubKey, + Address: pubKey.Address(), + PrivateKey: privKey, + }, nil +} + +func (k *Key) Pubkey() []byte { + return k.PublicKey.RawBytes() +} + +func NewKeyFromPub(curveType crypto.CurveType, PubKeyBytes []byte) (*Key, error) { + pubKey, err := crypto.PublicKeyFromBytes(PubKeyBytes, curveType) + if err != nil { + return nil, err + } + + return &Key{ + CurveType: curveType, + PublicKey: pubKey, + Address: pubKey.Address(), + }, nil +} + +func NewKeyFromPriv(curveType crypto.CurveType, PrivKeyBytes []byte) (*Key, error) { + privKey, err := crypto.PrivateKeyFromRawBytes(PrivKeyBytes, curveType) + + if err != nil { + return nil, err + } + + pubKey := privKey.GetPublicKey() + + return &Key{ + CurveType: curveType, + Address: pubKey.Address(), + PublicKey: pubKey, + PrivateKey: privKey, + }, nil +} + +func (k *Key) Sign(hash []byte) ([]byte, error) { + signature, err := k.PrivateKey.Sign(hash) + if err != nil { + return nil, err + } + return signature.RawBytes(), nil +} diff --git a/keys/key_store_file.go b/keys/key_store_file.go new file mode 100644 index 0000000000000000000000000000000000000000..25c2f56728c7c436250bda1837c5b90c81874180 --- /dev/null +++ b/keys/key_store_file.go @@ -0,0 +1,336 @@ +package keys + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path" + "strings" + "sync" + + "github.com/hyperledger/burrow/crypto" + "github.com/tmthrgd/go-hex" + + "golang.org/x/crypto/scrypt" +) + +const ( + scryptN = 1 << 18 + scryptr = 8 + scryptp = 1 + scryptdkLen = 32 + CryptoNone = "none" + CryptoAESGCM = "scrypt-aes-gcm" + HashEd25519 = "go-crypto-0.5.0" + HashSecp256k1 = "btc" +) + +//----------------------------------------------------------------------------- +// json encodings + +// addresses should be hex encoded + +type keyJSON struct { + CurveType string + Address string + PublicKey []byte + AddressHash string + PrivateKey privateKeyJSON +} + +type privateKeyJSON struct { + Crypto string + Plain []byte `json:",omitempty"` + Salt []byte `json:",omitempty"` + Nonce []byte `json:",omitempty"` + CipherText []byte `json:",omitempty"` +} + +func (k *Key) MarshalJSON() (j []byte, err error) { + jStruct := keyJSON{ + CurveType: k.CurveType.String(), + Address: hex.EncodeToString(k.Address[:]), + PublicKey: k.Pubkey(), + AddressHash: k.PublicKey.AddressHashType(), + PrivateKey: privateKeyJSON{Crypto: CryptoNone, Plain: k.PrivateKey.RawBytes()}, + } + j, err = json.Marshal(jStruct) + return j, err +} + +func (k *Key) UnmarshalJSON(j []byte) (err error) { + keyJ := new(keyJSON) + err = json.Unmarshal(j, &keyJ) + if err != nil { + return err + } + if len(keyJ.PrivateKey.Plain) == 0 { + return fmt.Errorf("no private key") + } + curveType, err := crypto.CurveTypeFromString(keyJ.CurveType) + if err != nil { + curveType = crypto.CurveTypeEd25519 + } + k2, err := NewKeyFromPriv(curveType, keyJ.PrivateKey.Plain) + if err != nil { + return err + } + + k.Address = k2.Address + k.CurveType = curveType + k.PublicKey = k2.PrivateKey.GetPublicKey() + k.PrivateKey = k2.PrivateKey + + return nil +} + +// returns the address if valid, nil otherwise +func IsValidKeyJson(j []byte) []byte { + j1 := new(keyJSON) + e1 := json.Unmarshal(j, &j1) + if e1 == nil { + addr, _ := hex.DecodeString(j1.Address) + return addr + } + return nil +} + +type KeyStore struct { + sync.Mutex + keysDirPath string +} + +func (ks KeyStore) Gen(passphrase string, curveType crypto.CurveType) (key *Key, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("GenerateNewKey error: %v", r) + } + }() + key, err = NewKey(curveType) + if err != nil { + return nil, err + } + err = ks.StoreKey(passphrase, key) + return key, err +} + +func (ks KeyStore) GetKey(passphrase string, keyAddr []byte) (*Key, error) { + ks.Lock() + defer ks.Unlock() + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return nil, err + } + fileContent, err := GetKeyFile(dataDirPath, keyAddr) + if err != nil { + return nil, err + } + key := new(keyJSON) + if err = json.Unmarshal(fileContent, key); err != nil { + return nil, err + } + + if len(key.PrivateKey.CipherText) > 0 { + return DecryptKey(passphrase, key) + } else { + key := new(Key) + err = key.UnmarshalJSON(fileContent) + return key, err + } +} + +func (ks KeyStore) AllKeys() ([]*Key, error) { + + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return nil, err + } + addrs, err := GetAllAddresses(dataDirPath) + if err != nil { + return nil, err + } + + var list []*Key + + for _, addr := range addrs { + k, err := ks.GetKey("", addr) + if err != nil { + return nil, err + } + list = append(list, k) + } + + return list, nil +} + +func DecryptKey(passphrase string, keyProtected *keyJSON) (*Key, error) { + salt := keyProtected.PrivateKey.Salt + nonce := keyProtected.PrivateKey.Nonce + cipherText := keyProtected.PrivateKey.CipherText + + curveType, err := crypto.CurveTypeFromString(keyProtected.CurveType) + if err != nil { + return nil, err + } + authArray := []byte(passphrase) + derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen) + if err != nil { + return nil, err + } + aesBlock, err := aes.NewCipher(derivedKey) + if err != nil { + return nil, err + } + gcm, err := cipher.NewGCM(aesBlock) + if err != nil { + return nil, err + } + plainText, err := gcm.Open(nil, nonce, cipherText, nil) + if err != nil { + pkey, _ := NewKeyFromPub(curveType, keyProtected.PublicKey) + return pkey, err + } + address, err := crypto.AddressFromHexString(keyProtected.Address) + if err != nil { + return nil, err + } + k, err := NewKeyFromPriv(curveType, plainText) + if err != nil { + return nil, err + } + if address != k.Address { + return nil, fmt.Errorf("address does not match") + } + return k, nil +} + +func (ks KeyStore) GetAllAddresses() (addresses [][]byte, err error) { + ks.Lock() + defer ks.Unlock() + return GetAllAddresses(ks.keysDirPath) +} + +func (ks KeyStore) StoreKey(passphrase string, key *Key) error { + ks.Lock() + defer ks.Unlock() + if passphrase != "" { + return ks.StoreKeyEncrypted(passphrase, key) + } else { + return ks.StoreKeyPlain(key) + } +} + +func (ks KeyStore) StoreKeyPlain(key *Key) (err error) { + keyJSON, err := json.Marshal(key) + if err != nil { + return err + } + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return err + } + err = WriteKeyFile(key.Address[:], dataDirPath, keyJSON) + return err +} + +func (ks KeyStore) StoreKeyEncrypted(passphrase string, key *Key) error { + authArray := []byte(passphrase) + salt := make([]byte, 32) + _, err := rand.Read(salt) + if err != nil { + return err + } + + derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen) + if err != nil { + return err + } + + toEncrypt := key.PrivateKey.RawBytes() + + AES256Block, err := aes.NewCipher(derivedKey) + if err != nil { + return err + } + + gcm, err := cipher.NewGCM(AES256Block) + if err != nil { + return err + } + + // XXX: a GCM nonce may only be used once per key ever! + nonce := make([]byte, gcm.NonceSize()) + _, err = rand.Read(nonce) + if err != nil { + return err + } + + // (dst, nonce, plaintext, extradata) + cipherText := gcm.Seal(nil, nonce, toEncrypt, nil) + + cipherStruct := privateKeyJSON{ + Crypto: CryptoAESGCM, Salt: salt, Nonce: nonce, CipherText: cipherText, + } + keyStruct := keyJSON{ + CurveType: key.CurveType.String(), + Address: strings.ToUpper(hex.EncodeToString(key.Address[:])), + PublicKey: key.Pubkey(), + AddressHash: key.PublicKey.AddressHashType(), + PrivateKey: cipherStruct, + } + keyJSON, err := json.Marshal(keyStruct) + if err != nil { + return err + } + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return err + } + + return WriteKeyFile(key.Address[:], dataDirPath, keyJSON) +} + +func (ks KeyStore) DeleteKey(passphrase string, keyAddr []byte) (err error) { + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return err + } + keyDirPath := path.Join(dataDirPath, strings.ToUpper(hex.EncodeToString(keyAddr))+".json") + return os.Remove(keyDirPath) +} + +func GetKeyFile(dataDirPath string, keyAddr []byte) (fileContent []byte, err error) { + fileName := strings.ToUpper(hex.EncodeToString(keyAddr)) + return ioutil.ReadFile(path.Join(dataDirPath, fileName+".json")) +} + +func WriteKeyFile(addr []byte, dataDirPath string, content []byte) (err error) { + addrHex := strings.ToUpper(hex.EncodeToString(addr)) + keyFilePath := path.Join(dataDirPath, addrHex+".json") + err = os.MkdirAll(dataDirPath, 0700) // read, write and dir search for user + if err != nil { + return err + } + return ioutil.WriteFile(keyFilePath, content, 0600) // read, write for user +} + +func GetAllAddresses(dataDirPath string) (addresses [][]byte, err error) { + fileInfos, err := ioutil.ReadDir(dataDirPath) + if err != nil { + return nil, err + } + addresses = make([][]byte, len(fileInfos)) + for i, fileInfo := range fileInfos { + addr := strings.TrimSuffix(fileInfo.Name(), "json") + address, err := hex.DecodeString(addr) + if err != nil { + continue + } + addresses[i] = address + } + return addresses, err +} diff --git a/keys/mock/key.go b/keys/mock/key.go index 8000bf28cd43e462cb6f6b0395c36bcd5e015eab..83a7f0010aedd4c4646956b3bd5c6d1060425b73 100644 --- a/keys/mock/key.go +++ b/keys/mock/key.go @@ -6,10 +6,9 @@ import ( "fmt" acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/keys" + "github.com/hyperledger/burrow/crypto" + "github.com/pkg/errors" - "github.com/tendermint/go-crypto" - "github.com/wayn3h0/go-uuid" "golang.org/x/crypto/ed25519" ) @@ -17,7 +16,7 @@ import ( // Simple ed25519 key structure for mock purposes with ripemd160 address type Key struct { Name string - Address acm.Address + Address crypto.Address PublicKey []byte PrivateKey []byte } @@ -37,10 +36,12 @@ func newKey(name string) (*Key, error) { copy(key.PrivateKey[:], privateKey[:]) copy(key.PublicKey[:], publicKey[:]) - var ed25519 crypto.PubKeyEd25519 - copy(ed25519[:], publicKey[:]) + pk, err := crypto.PublicKeyFromBytes(publicKey, crypto.CurveTypeEd25519) + if err != nil { + return nil, err + } - key.Address, err = acm.AddressFromBytes(ed25519.Address()) + key.Address, err = crypto.AddressFromBytes(pk.Address().Bytes()) if err != nil { return nil, err } @@ -55,8 +56,7 @@ func newKey(name string) (*Key, error) { } func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *Key { - _, ok := privateAccount.PrivateKey().Unwrap().(crypto.PrivKeyEd25519) - if !ok { + if privateAccount.PrivateKey().CurveType != crypto.CurveTypeEd25519 { panic(fmt.Errorf("mock key client only supports ed25519 private keys at present")) } key := &Key{ @@ -68,29 +68,27 @@ func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *Key { return key } -func (key *Key) Sign(message []byte) (acm.Signature, error) { - return acm.SignatureFromBytes(ed25519.Sign(key.PrivateKey, message)) +func (key *Key) Sign(message []byte) (crypto.Signature, error) { + return crypto.SignatureFromBytes(ed25519.Sign(key.PrivateKey, message), crypto.CurveTypeEd25519) +} + +type PrivateKeyplainKeyJSON struct { + Plain []byte } // TODO: remove after merging keys taken from there to match serialisation type plainKeyJSON struct { - Id []byte Type string Address string - PrivateKey []byte + PrivateKey PrivateKeyplainKeyJSON } // Returns JSON string compatible with that stored by monax-keys func (key *Key) MonaxKeysJSON() string { - id, err := uuid.NewRandom() - if err != nil { - return errors.Wrap(err, "could not create monax key json").Error() - } jsonKey := plainKeyJSON{ - Id: []byte(id.String()), Address: key.Address.String(), - Type: string(keys.KeyTypeEd25519Ripemd160), - PrivateKey: key.PrivateKey, + Type: "ed25519", + PrivateKey: PrivateKeyplainKeyJSON{Plain: key.PrivateKey}, } bs, err := json.Marshal(jsonKey) if err != nil { diff --git a/keys/mock/key_client.go b/keys/mock/key_client.go index 821c0c82499cb970a5f796497879e8281d9c8cc7..a9c646704cc466b027e0ec344a0962117ec7a410 100644 --- a/keys/mock/key_client.go +++ b/keys/mock/key_client.go @@ -18,8 +18,8 @@ import ( "fmt" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys" - "github.com/tendermint/go-crypto" ) //--------------------------------------------------------------------- @@ -29,12 +29,12 @@ import ( var _ keys.KeyClient = (*KeyClient)(nil) type KeyClient struct { - knownKeys map[acm.Address]*Key + knownKeys map[crypto.Address]*Key } func NewKeyClient(privateAccounts ...acm.PrivateAccount) *KeyClient { client := &KeyClient{ - knownKeys: make(map[acm.Address]*Key), + knownKeys: make(map[crypto.Address]*Key), } for _, pa := range privateAccounts { client.knownKeys[pa.Address()] = mockKeyFromPrivateAccount(pa) @@ -42,7 +42,7 @@ func NewKeyClient(privateAccounts ...acm.PrivateAccount) *KeyClient { return client } -func (mkc *KeyClient) NewKey(name string) acm.Address { +func (mkc *KeyClient) NewKey(name string) crypto.Address { // Only tests ED25519 curve and ripemd160. key, err := newKey(name) if err != nil { @@ -52,25 +52,23 @@ func (mkc *KeyClient) NewKey(name string) acm.Address { return key.Address } -func (mkc *KeyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) { +func (mkc *KeyClient) Sign(signAddress crypto.Address, message []byte) (crypto.Signature, error) { key := mkc.knownKeys[signAddress] if key == nil { - return acm.Signature{}, fmt.Errorf("unknown address (%s)", signAddress) + return crypto.Signature{}, fmt.Errorf("unknown address (%s)", signAddress) } return key.Sign(message) } -func (mkc *KeyClient) PublicKey(address acm.Address) (acm.PublicKey, error) { +func (mkc *KeyClient) PublicKey(address crypto.Address) (crypto.PublicKey, error) { key := mkc.knownKeys[address] if key == nil { - return acm.PublicKey{}, fmt.Errorf("unknown address (%s)", address) + return crypto.PublicKey{}, fmt.Errorf("unknown address (%s)", address) } - pubKeyEd25519 := crypto.PubKeyEd25519{} - copy(pubKeyEd25519[:], key.PublicKey) - return acm.PublicKeyFromGoCryptoPubKey(pubKeyEd25519.Wrap()) + return crypto.PublicKeyFromBytes(key.PublicKey, crypto.CurveTypeEd25519) } -func (mkc *KeyClient) Generate(keyName string, keyType keys.KeyType) (acm.Address, error) { +func (mkc *KeyClient) Generate(keyName string, curve crypto.CurveType) (crypto.Address, error) { return mkc.NewKey(keyName), nil } diff --git a/keys/mock/key_client_test.go b/keys/mock/key_client_test.go index 7f74a03733c54f751bcecab7fa6abfe691dbeebf..72dc557e7fe05439a39af3e6604b5fd5a5650ecc 100644 --- a/keys/mock/key_client_test.go +++ b/keys/mock/key_client_test.go @@ -5,7 +5,7 @@ import ( "encoding/json" - "github.com/hyperledger/burrow/keys" + "github.com/hyperledger/burrow/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -19,8 +19,7 @@ func TestMockKey_MonaxKeyJSON(t *testing.T) { err = json.Unmarshal([]byte(monaxKey), keyJSON) require.NoError(t, err) // byte length of UUID string = 16 * 2 + 4 = 36 - assert.Len(t, keyJSON.Id, 36) assert.Equal(t, key.Address.String(), keyJSON.Address) - assert.Equal(t, key.PrivateKey, keyJSON.PrivateKey) - assert.Equal(t, string(keys.KeyTypeEd25519Ripemd160), keyJSON.Type) + assert.Equal(t, key.PrivateKey, keyJSON.PrivateKey.Plain) + assert.Equal(t, string(crypto.CurveTypeEd25519.String()), keyJSON.Type) } diff --git a/keys/pbkeys/keys.pb.go b/keys/pbkeys/keys.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..a099818d370ebfe3db85f66d429ccafa7ed8a008 --- /dev/null +++ b/keys/pbkeys/keys.pb.go @@ -0,0 +1,977 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: keys.proto + +/* +Package pbkeys is a generated protocol buffer package. + +It is generated from these files: + keys.proto + +It has these top-level messages: + Name + Empty + GenRequest + GenResponse + PubRequest + PubResponse + ImportJSONRequest + ImportResponse + ImportRequest + ExportRequest + ExportResponse + SignRequest + SignResponse + VerifyRequest + HashRequest + HashResponse + Key + ListResponse + AddNameRequest +*/ +package pbkeys + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Name struct { + Keyname string `protobuf:"bytes,1,opt,name=keyname" json:"keyname,omitempty"` +} + +func (m *Name) Reset() { *m = Name{} } +func (m *Name) String() string { return proto.CompactTextString(m) } +func (*Name) ProtoMessage() {} +func (*Name) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Name) GetKeyname() string { + if m != nil { + return m.Keyname + } + return "" +} + +type Empty struct { +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +type GenRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + Curvetype string `protobuf:"bytes,2,opt,name=curvetype" json:"curvetype,omitempty"` + Keyname string `protobuf:"bytes,3,opt,name=keyname" json:"keyname,omitempty"` +} + +func (m *GenRequest) Reset() { *m = GenRequest{} } +func (m *GenRequest) String() string { return proto.CompactTextString(m) } +func (*GenRequest) ProtoMessage() {} +func (*GenRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *GenRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *GenRequest) GetCurvetype() string { + if m != nil { + return m.Curvetype + } + return "" +} + +func (m *GenRequest) GetKeyname() string { + if m != nil { + return m.Keyname + } + return "" +} + +type GenResponse struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` +} + +func (m *GenResponse) Reset() { *m = GenResponse{} } +func (m *GenResponse) String() string { return proto.CompactTextString(m) } +func (*GenResponse) ProtoMessage() {} +func (*GenResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *GenResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type PubRequest struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` +} + +func (m *PubRequest) Reset() { *m = PubRequest{} } +func (m *PubRequest) String() string { return proto.CompactTextString(m) } +func (*PubRequest) ProtoMessage() {} +func (*PubRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *PubRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *PubRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type PubResponse struct { + Pub []byte `protobuf:"bytes,1,opt,name=pub,proto3" json:"pub,omitempty"` + Curvetype string `protobuf:"bytes,2,opt,name=curvetype" json:"curvetype,omitempty"` +} + +func (m *PubResponse) Reset() { *m = PubResponse{} } +func (m *PubResponse) String() string { return proto.CompactTextString(m) } +func (*PubResponse) ProtoMessage() {} +func (*PubResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *PubResponse) GetPub() []byte { + if m != nil { + return m.Pub + } + return nil +} + +func (m *PubResponse) GetCurvetype() string { + if m != nil { + return m.Curvetype + } + return "" +} + +type ImportJSONRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + JSON string `protobuf:"bytes,2,opt,name=JSON" json:"JSON,omitempty"` +} + +func (m *ImportJSONRequest) Reset() { *m = ImportJSONRequest{} } +func (m *ImportJSONRequest) String() string { return proto.CompactTextString(m) } +func (*ImportJSONRequest) ProtoMessage() {} +func (*ImportJSONRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *ImportJSONRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *ImportJSONRequest) GetJSON() string { + if m != nil { + return m.JSON + } + return "" +} + +type ImportResponse struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` +} + +func (m *ImportResponse) Reset() { *m = ImportResponse{} } +func (m *ImportResponse) String() string { return proto.CompactTextString(m) } +func (*ImportResponse) ProtoMessage() {} +func (*ImportResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *ImportResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type ImportRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Curvetype string `protobuf:"bytes,3,opt,name=curvetype" json:"curvetype,omitempty"` + Keybytes []byte `protobuf:"bytes,4,opt,name=keybytes,proto3" json:"keybytes,omitempty"` +} + +func (m *ImportRequest) Reset() { *m = ImportRequest{} } +func (m *ImportRequest) String() string { return proto.CompactTextString(m) } +func (*ImportRequest) ProtoMessage() {} +func (*ImportRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func (m *ImportRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *ImportRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ImportRequest) GetCurvetype() string { + if m != nil { + return m.Curvetype + } + return "" +} + +func (m *ImportRequest) GetKeybytes() []byte { + if m != nil { + return m.Keybytes + } + return nil +} + +type ExportRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"` +} + +func (m *ExportRequest) Reset() { *m = ExportRequest{} } +func (m *ExportRequest) String() string { return proto.CompactTextString(m) } +func (*ExportRequest) ProtoMessage() {} +func (*ExportRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } + +func (m *ExportRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *ExportRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ExportRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type ExportResponse struct { + Export string `protobuf:"bytes,1,opt,name=export" json:"export,omitempty"` +} + +func (m *ExportResponse) Reset() { *m = ExportResponse{} } +func (m *ExportResponse) String() string { return proto.CompactTextString(m) } +func (*ExportResponse) ProtoMessage() {} +func (*ExportResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +func (m *ExportResponse) GetExport() string { + if m != nil { + return m.Export + } + return "" +} + +type SignRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + Message []byte `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"` +} + +func (m *SignRequest) Reset() { *m = SignRequest{} } +func (m *SignRequest) String() string { return proto.CompactTextString(m) } +func (*SignRequest) ProtoMessage() {} +func (*SignRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } + +func (m *SignRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *SignRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *SignRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *SignRequest) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +type SignResponse struct { + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` + Curvetype string `protobuf:"bytes,2,opt,name=curvetype" json:"curvetype,omitempty"` +} + +func (m *SignResponse) Reset() { *m = SignResponse{} } +func (m *SignResponse) String() string { return proto.CompactTextString(m) } +func (*SignResponse) ProtoMessage() {} +func (*SignResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } + +func (m *SignResponse) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *SignResponse) GetCurvetype() string { + if m != nil { + return m.Curvetype + } + return "" +} + +type VerifyRequest struct { + Curvetype string `protobuf:"bytes,1,opt,name=curvetype" json:"curvetype,omitempty"` + Pub []byte `protobuf:"bytes,2,opt,name=pub,proto3" json:"pub,omitempty"` + Message []byte `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (m *VerifyRequest) Reset() { *m = VerifyRequest{} } +func (m *VerifyRequest) String() string { return proto.CompactTextString(m) } +func (*VerifyRequest) ProtoMessage() {} +func (*VerifyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } + +func (m *VerifyRequest) GetCurvetype() string { + if m != nil { + return m.Curvetype + } + return "" +} + +func (m *VerifyRequest) GetPub() []byte { + if m != nil { + return m.Pub + } + return nil +} + +func (m *VerifyRequest) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +func (m *VerifyRequest) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +type HashRequest struct { + Hashtype string `protobuf:"bytes,1,opt,name=hashtype" json:"hashtype,omitempty"` + Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` +} + +func (m *HashRequest) Reset() { *m = HashRequest{} } +func (m *HashRequest) String() string { return proto.CompactTextString(m) } +func (*HashRequest) ProtoMessage() {} +func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } + +func (m *HashRequest) GetHashtype() string { + if m != nil { + return m.Hashtype + } + return "" +} + +func (m *HashRequest) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +type HashResponse struct { + Hash string `protobuf:"bytes,1,opt,name=hash" json:"hash,omitempty"` +} + +func (m *HashResponse) Reset() { *m = HashResponse{} } +func (m *HashResponse) String() string { return proto.CompactTextString(m) } +func (*HashResponse) ProtoMessage() {} +func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } + +func (m *HashResponse) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +type Key struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + Keyname string `protobuf:"bytes,2,opt,name=keyname" json:"keyname,omitempty"` +} + +func (m *Key) Reset() { *m = Key{} } +func (m *Key) String() string { return proto.CompactTextString(m) } +func (*Key) ProtoMessage() {} +func (*Key) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } + +func (m *Key) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *Key) GetKeyname() string { + if m != nil { + return m.Keyname + } + return "" +} + +type ListResponse struct { + Key []*Key `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` +} + +func (m *ListResponse) Reset() { *m = ListResponse{} } +func (m *ListResponse) String() string { return proto.CompactTextString(m) } +func (*ListResponse) ProtoMessage() {} +func (*ListResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } + +func (m *ListResponse) GetKey() []*Key { + if m != nil { + return m.Key + } + return nil +} + +type AddNameRequest struct { + Keyname string `protobuf:"bytes,1,opt,name=keyname" json:"keyname,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` +} + +func (m *AddNameRequest) Reset() { *m = AddNameRequest{} } +func (m *AddNameRequest) String() string { return proto.CompactTextString(m) } +func (*AddNameRequest) ProtoMessage() {} +func (*AddNameRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } + +func (m *AddNameRequest) GetKeyname() string { + if m != nil { + return m.Keyname + } + return "" +} + +func (m *AddNameRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func init() { + proto.RegisterType((*Name)(nil), "pbkeys.Name") + proto.RegisterType((*Empty)(nil), "pbkeys.Empty") + proto.RegisterType((*GenRequest)(nil), "pbkeys.GenRequest") + proto.RegisterType((*GenResponse)(nil), "pbkeys.GenResponse") + proto.RegisterType((*PubRequest)(nil), "pbkeys.PubRequest") + proto.RegisterType((*PubResponse)(nil), "pbkeys.PubResponse") + proto.RegisterType((*ImportJSONRequest)(nil), "pbkeys.ImportJSONRequest") + proto.RegisterType((*ImportResponse)(nil), "pbkeys.ImportResponse") + proto.RegisterType((*ImportRequest)(nil), "pbkeys.ImportRequest") + proto.RegisterType((*ExportRequest)(nil), "pbkeys.ExportRequest") + proto.RegisterType((*ExportResponse)(nil), "pbkeys.ExportResponse") + proto.RegisterType((*SignRequest)(nil), "pbkeys.SignRequest") + proto.RegisterType((*SignResponse)(nil), "pbkeys.SignResponse") + proto.RegisterType((*VerifyRequest)(nil), "pbkeys.VerifyRequest") + proto.RegisterType((*HashRequest)(nil), "pbkeys.HashRequest") + proto.RegisterType((*HashResponse)(nil), "pbkeys.HashResponse") + proto.RegisterType((*Key)(nil), "pbkeys.Key") + proto.RegisterType((*ListResponse)(nil), "pbkeys.ListResponse") + proto.RegisterType((*AddNameRequest)(nil), "pbkeys.AddNameRequest") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for Keys service + +type KeysClient interface { + GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) + PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) + Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) + Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*Empty, error) + Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) + ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) + Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) + Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) + RemoveName(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error) + List(ctx context.Context, in *Name, opts ...grpc.CallOption) (*ListResponse, error) + AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*Empty, error) +} + +type keysClient struct { + cc *grpc.ClientConn +} + +func NewKeysClient(cc *grpc.ClientConn) KeysClient { + return &keysClient{cc} +} + +func (c *keysClient) GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) { + out := new(GenResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/GenerateKey", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) { + out := new(PubResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/PublicKey", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) { + out := new(SignResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/Sign", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pbkeys.Keys/Verify", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) { + out := new(ImportResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/Import", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) { + out := new(ImportResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/ImportJSON", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) { + out := new(ExportResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/Export", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) { + out := new(HashResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/Hash", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) RemoveName(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pbkeys.Keys/RemoveName", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) List(ctx context.Context, in *Name, opts ...grpc.CallOption) (*ListResponse, error) { + out := new(ListResponse) + err := grpc.Invoke(ctx, "/pbkeys.Keys/List", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pbkeys.Keys/AddName", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Keys service + +type KeysServer interface { + GenerateKey(context.Context, *GenRequest) (*GenResponse, error) + PublicKey(context.Context, *PubRequest) (*PubResponse, error) + Sign(context.Context, *SignRequest) (*SignResponse, error) + Verify(context.Context, *VerifyRequest) (*Empty, error) + Import(context.Context, *ImportRequest) (*ImportResponse, error) + ImportJSON(context.Context, *ImportJSONRequest) (*ImportResponse, error) + Export(context.Context, *ExportRequest) (*ExportResponse, error) + Hash(context.Context, *HashRequest) (*HashResponse, error) + RemoveName(context.Context, *Name) (*Empty, error) + List(context.Context, *Name) (*ListResponse, error) + AddName(context.Context, *AddNameRequest) (*Empty, error) +} + +func RegisterKeysServer(s *grpc.Server, srv KeysServer) { + s.RegisterService(&_Keys_serviceDesc, srv) +} + +func _Keys_GenerateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).GenerateKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/GenerateKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).GenerateKey(ctx, req.(*GenRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_PublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PubRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).PublicKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/PublicKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).PublicKey(ctx, req.(*PubRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Sign(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/Sign", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Sign(ctx, req.(*SignRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Verify(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/Verify", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Verify(ctx, req.(*VerifyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Import_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImportRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Import(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/Import", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Import(ctx, req.(*ImportRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_ImportJSON_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImportJSONRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).ImportJSON(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/ImportJSON", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).ImportJSON(ctx, req.(*ImportJSONRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExportRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Export(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/Export", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Export(ctx, req.(*ExportRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Hash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/Hash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Hash(ctx, req.(*HashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_RemoveName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Name) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).RemoveName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/RemoveName", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).RemoveName(ctx, req.(*Name)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Name) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).List(ctx, req.(*Name)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_AddName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).AddName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbkeys.Keys/AddName", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).AddName(ctx, req.(*AddNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Keys_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pbkeys.Keys", + HandlerType: (*KeysServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GenerateKey", + Handler: _Keys_GenerateKey_Handler, + }, + { + MethodName: "PublicKey", + Handler: _Keys_PublicKey_Handler, + }, + { + MethodName: "Sign", + Handler: _Keys_Sign_Handler, + }, + { + MethodName: "Verify", + Handler: _Keys_Verify_Handler, + }, + { + MethodName: "Import", + Handler: _Keys_Import_Handler, + }, + { + MethodName: "ImportJSON", + Handler: _Keys_ImportJSON_Handler, + }, + { + MethodName: "Export", + Handler: _Keys_Export_Handler, + }, + { + MethodName: "Hash", + Handler: _Keys_Hash_Handler, + }, + { + MethodName: "RemoveName", + Handler: _Keys_RemoveName_Handler, + }, + { + MethodName: "List", + Handler: _Keys_List_Handler, + }, + { + MethodName: "AddName", + Handler: _Keys_AddName_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "keys.proto", +} + +func init() { proto.RegisterFile("keys.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 640 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x51, 0x6f, 0xd3, 0x3c, + 0x14, 0x55, 0x9b, 0x7c, 0xdd, 0x7a, 0xda, 0x4e, 0x1f, 0x06, 0xa6, 0x52, 0x0d, 0x34, 0xf9, 0x85, + 0x31, 0x89, 0x8a, 0x0d, 0xc4, 0x04, 0x12, 0x42, 0x08, 0xa6, 0xc1, 0x86, 0xc6, 0xd4, 0x49, 0xbc, + 0xf1, 0x90, 0xae, 0x97, 0xb5, 0x2a, 0x69, 0x43, 0x9c, 0x0c, 0xf2, 0xc0, 0xdf, 0xe3, 0x77, 0x21, + 0x3b, 0x76, 0x6d, 0x47, 0xeb, 0xa8, 0xc4, 0x9b, 0xef, 0xcd, 0xbd, 0xf7, 0x1c, 0xdf, 0x9c, 0x9c, + 0x00, 0x53, 0x2a, 0x44, 0x3f, 0x49, 0xe7, 0xd9, 0x9c, 0x35, 0x92, 0xa1, 0x8c, 0xf8, 0x36, 0xc2, + 0xd3, 0x28, 0x26, 0xd6, 0xc5, 0xda, 0x94, 0x8a, 0x59, 0x14, 0x53, 0xb7, 0xb6, 0x5d, 0xdb, 0x69, + 0x0e, 0x4c, 0xc8, 0xd7, 0xf0, 0xdf, 0x61, 0x9c, 0x64, 0x05, 0x1f, 0x01, 0x47, 0x34, 0x1b, 0xd0, + 0xf7, 0x9c, 0x44, 0xc6, 0x1e, 0x00, 0x49, 0x24, 0x44, 0x32, 0x4e, 0x23, 0x61, 0x7a, 0x9c, 0x0c, + 0xdb, 0x42, 0xf3, 0x22, 0x4f, 0xaf, 0x28, 0x2b, 0x12, 0xea, 0xd6, 0xd5, 0x63, 0x9b, 0x70, 0xe1, + 0x02, 0x1f, 0xee, 0x21, 0x5a, 0x0a, 0x45, 0x24, 0xf3, 0x99, 0x50, 0x85, 0xd1, 0x68, 0x94, 0x92, + 0x10, 0x86, 0x97, 0x0e, 0xf9, 0x4b, 0xe0, 0x2c, 0x1f, 0x1a, 0x3a, 0x4b, 0xeb, 0x18, 0x43, 0xa8, + 0x70, 0x4a, 0x0e, 0xea, 0xcc, 0x5f, 0xa1, 0xa5, 0x7a, 0x35, 0xc8, 0xff, 0x08, 0x92, 0x7c, 0xa8, + 0x1a, 0xdb, 0x03, 0x79, 0xbc, 0x99, 0x3d, 0x3f, 0xc2, 0xad, 0x0f, 0x71, 0x32, 0x4f, 0xb3, 0xe3, + 0xf3, 0x4f, 0xa7, 0xab, 0x2e, 0x84, 0x21, 0x94, 0xe5, 0x86, 0x87, 0x3c, 0xf3, 0x5d, 0x6c, 0x94, + 0x83, 0x56, 0xb8, 0xef, 0x2f, 0x74, 0x4c, 0xed, 0xca, 0x80, 0xd5, 0x8b, 0xfb, 0xf7, 0x0a, 0xaa, + 0x6f, 0xa5, 0x87, 0xf5, 0x29, 0x15, 0xc3, 0x22, 0x23, 0xd1, 0x0d, 0xd5, 0x32, 0x16, 0x31, 0xff, + 0x82, 0xce, 0xe1, 0xcf, 0x7f, 0x85, 0x77, 0x6e, 0x17, 0xf8, 0xb7, 0xdb, 0xc1, 0x86, 0x19, 0xaf, + 0x37, 0xb1, 0x89, 0x06, 0xa9, 0x8c, 0x9e, 0xad, 0x23, 0x9e, 0xa3, 0x75, 0x3e, 0xb9, 0x5c, 0x59, + 0x87, 0x0e, 0x64, 0xfd, 0x7a, 0x61, 0x04, 0x3e, 0xc1, 0x98, 0x84, 0x88, 0x2e, 0x49, 0x2f, 0xc0, + 0x84, 0xfc, 0x18, 0xed, 0x12, 0x56, 0xd3, 0xdb, 0x42, 0x53, 0x4c, 0x2e, 0x67, 0x51, 0x96, 0xa7, + 0xa4, 0x95, 0x63, 0x13, 0x7f, 0xd1, 0xcf, 0x0f, 0x74, 0x3e, 0x53, 0x3a, 0xf9, 0x5a, 0x98, 0x4b, + 0x78, 0xe5, 0xb5, 0xea, 0x6b, 0xd1, 0xf2, 0xac, 0x5b, 0x79, 0x3a, 0x34, 0x03, 0x8f, 0xa6, 0x4f, + 0x2b, 0xac, 0xd0, 0xe2, 0x6f, 0xd1, 0x7a, 0x1f, 0x89, 0xb1, 0x81, 0xed, 0x61, 0x7d, 0x1c, 0x89, + 0xb1, 0x83, 0xba, 0x88, 0x5d, 0x88, 0xba, 0xbf, 0x09, 0x8e, 0x76, 0x39, 0x44, 0x6f, 0x82, 0x21, + 0x94, 0x5d, 0x7a, 0x82, 0x3a, 0xf3, 0x17, 0x08, 0x4e, 0xa8, 0xb8, 0xe1, 0xab, 0x74, 0x0c, 0xa0, + 0xee, 0x1b, 0xc0, 0x63, 0xb4, 0x3f, 0x4e, 0x84, 0xd5, 0xc1, 0x7d, 0x04, 0x53, 0x2a, 0xba, 0xb5, + 0xed, 0x60, 0xa7, 0xb5, 0xdf, 0xea, 0x97, 0xbe, 0xd5, 0x3f, 0xa1, 0x62, 0x20, 0xf3, 0xfc, 0x1d, + 0x36, 0xde, 0x8c, 0x46, 0xd2, 0xc3, 0x1c, 0x2b, 0xb8, 0xde, 0xca, 0x96, 0x6b, 0x61, 0xff, 0x77, + 0x88, 0xf0, 0x84, 0x0a, 0xc1, 0x9e, 0x2b, 0xfb, 0xa1, 0x34, 0xca, 0x48, 0x5e, 0x80, 0x19, 0x3c, + 0xeb, 0x7c, 0xbd, 0xdb, 0x5e, 0x4e, 0xb3, 0x7c, 0x86, 0xe6, 0x59, 0x3e, 0xfc, 0x36, 0xb9, 0xf0, + 0xba, 0xac, 0x41, 0xd9, 0x2e, 0xd7, 0x78, 0xf6, 0x10, 0x4a, 0x51, 0xb1, 0xc5, 0x43, 0x47, 0xd9, + 0xbd, 0x3b, 0x7e, 0x52, 0xb7, 0xf4, 0xd1, 0x28, 0xb5, 0xc3, 0xee, 0x9a, 0xe7, 0x9e, 0x96, 0x7a, + 0x1d, 0x93, 0x56, 0xae, 0xcd, 0x0e, 0xd0, 0x28, 0x6d, 0xc3, 0xd6, 0x7b, 0x36, 0xd2, 0xdb, 0xac, + 0xa6, 0x35, 0xd0, 0x6b, 0xc0, 0x9a, 0x1c, 0xbb, 0xe7, 0x57, 0x39, 0xc6, 0xb7, 0x74, 0xc0, 0x01, + 0x1a, 0xe5, 0x27, 0x6d, 0x91, 0x3d, 0x07, 0xb1, 0x8d, 0x95, 0x2f, 0x7f, 0x0f, 0xa1, 0x14, 0x98, + 0xdd, 0x8a, 0xa3, 0x59, 0xbb, 0x15, 0x4f, 0x83, 0x8f, 0x80, 0x01, 0xc5, 0xf3, 0x2b, 0x52, 0x3f, + 0xb3, 0xb6, 0xa9, 0x91, 0x51, 0x75, 0x21, 0xbb, 0x08, 0xa5, 0xbe, 0x2a, 0x45, 0x8b, 0xb1, 0x9e, + 0xf6, 0x9e, 0x60, 0x4d, 0x8b, 0x8b, 0x2d, 0xc8, 0xfa, 0x6a, 0xab, 0x4c, 0x1f, 0x36, 0xd4, 0xef, + 0xf5, 0xe9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3b, 0xed, 0x32, 0x21, 0x6c, 0x07, 0x00, 0x00, +} diff --git a/keys/pbkeys/keys.proto b/keys/pbkeys/keys.proto new file mode 100644 index 0000000000000000000000000000000000000000..06ef091eee5694daa1f546e04a85badf2acb9f9e --- /dev/null +++ b/keys/pbkeys/keys.proto @@ -0,0 +1,113 @@ +syntax = "proto3"; + +package pbkeys; + +service Keys { + rpc GenerateKey(GenRequest) returns (GenResponse); + rpc PublicKey(PubRequest) returns (PubResponse); + rpc Sign(SignRequest) returns (SignResponse); + rpc Verify(VerifyRequest) returns (Empty); + rpc Import(ImportRequest) returns (ImportResponse); + rpc ImportJSON(ImportJSONRequest) returns (ImportResponse); + rpc Export(ExportRequest) returns (ExportResponse); + rpc Hash(HashRequest) returns (HashResponse); + rpc RemoveName(Name) returns (Empty); + rpc List(Name) returns (ListResponse); + rpc AddName(AddNameRequest) returns (Empty); +} + +message Name { + string keyname = 1; +} + +message Empty { + +} + +message GenRequest { + string passphrase = 1; + string curvetype = 2; + string keyname = 3; +} + +message GenResponse { + string address = 1; +} + +message PubRequest { + string address = 1; + string name = 2; +} + +message PubResponse { + bytes pub = 1; + string curvetype = 2; +} + +message ImportJSONRequest { + string passphrase = 1; + string JSON = 2; +} + +message ImportResponse { + string address = 1; +} + +message ImportRequest { + string passphrase = 1; + string name = 2; + string curvetype = 3; + bytes keybytes = 4; +} + +message ExportRequest { + string passphrase = 1; + string name = 2; + string address = 3; +} + +message ExportResponse { + string export = 1; +} + +message SignRequest { + string passphrase = 1; + string address = 2; + string name = 3; + bytes message = 4; +} + +message SignResponse { + bytes signature = 1; + string curvetype = 2; +} + +message VerifyRequest { + string curvetype = 1; + bytes pub = 2; + bytes message = 3; + bytes signature = 4; +} + +message HashRequest { + string hashtype = 1; + bytes message = 2; +} + +message HashResponse { + string hash = 1; +} + +message Key { + string address = 1; + string keyname = 2; +} + +message ListResponse { + repeated Key key = 1; +} + +message AddNameRequest { + string keyname = 1; + string address = 2; +} diff --git a/keys/server.go b/keys/server.go new file mode 100644 index 0000000000000000000000000000000000000000..3ffa0e4375084c987baf075fea31fdc00dc5e8f5 --- /dev/null +++ b/keys/server.go @@ -0,0 +1,245 @@ +package keys + +import ( + "context" + "crypto/sha256" + "fmt" + "hash" + "net" + "strings" + + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/keys/pbkeys" + "github.com/tmthrgd/go-hex" + "golang.org/x/crypto/ripemd160" + "google.golang.org/grpc" +) + +//------------------------------------------------------------------------ +// all cli commands pass through the http KeyStore +// the KeyStore process also maintains the unlocked accounts + +func StartStandAloneServer(keysDir, host, port string) error { + listen, err := net.Listen("tcp", host+":"+port) + if err != nil { + return err + } + + ks := NewKeyStore(keysDir) + + grpcServer := grpc.NewServer() + pbkeys.RegisterKeysServer(grpcServer, &ks) + return grpcServer.Serve(listen) +} + +//------------------------------------------------------------------------ +// handlers + +func (k *KeyStore) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbkeys.GenResponse, error) { + curveT, err := crypto.CurveTypeFromString(in.Curvetype) + if err != nil { + return nil, err + } + + key, err := k.Gen(in.Passphrase, curveT) + if err != nil { + return nil, fmt.Errorf("error generating key %s %s", curveT, err) + } + + addrH := key.Address.String() + if in.Keyname != "" { + err = coreNameAdd(k.keysDirPath, in.Keyname, addrH) + if err != nil { + return nil, err + } + } + + return &pbkeys.GenResponse{Address: addrH}, nil +} + +func (k *KeyStore) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkeys.ExportResponse, error) { + addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) + + if err != nil { + return nil, err + } + + addrB, err := crypto.AddressFromHexString(addr) + if err != nil { + return nil, err + } + + // No phrase needed for public key. I hope. + key, err := k.GetKey(in.GetPassphrase(), addrB.Bytes()) + if err != nil { + return nil, err + } + resp, err := coreExport(key) + if err != nil { + return nil, err + } + + return &pbkeys.ExportResponse{Export: string(resp)}, nil +} + +func (k *KeyStore) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys.PubResponse, error) { + addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) + if err != nil { + return nil, err + } + + addrB, err := crypto.AddressFromHexString(addr) + if err != nil { + return nil, err + } + + // No phrase needed for public key. I hope. + key, err := k.GetKey("", addrB.Bytes()) + if key == nil { + return nil, err + } + + return &pbkeys.PubResponse{Curvetype: key.CurveType.String(), Pub: key.Pubkey()}, nil +} + +func (k *KeyStore) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.SignResponse, error) { + addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) + if err != nil { + return nil, err + } + + addrB, err := crypto.AddressFromHexString(addr) + if err != nil { + return nil, err + } + + key, err := k.GetKey(in.GetPassphrase(), addrB[:]) + if err != nil { + return nil, err + } + + sig, err := key.Sign(in.GetMessage()) + + return &pbkeys.SignResponse{Signature: sig}, nil +} + +func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys.Empty, error) { + if in.GetPub() == nil { + return nil, fmt.Errorf("must provide a pubkey") + } + if in.GetMessage() == nil { + return nil, fmt.Errorf("must provide a message") + } + if in.GetSignature() == nil { + return nil, fmt.Errorf("must provide a signature") + } + + curveT, err := crypto.CurveTypeFromString(in.GetCurvetype()) + if err != nil { + return nil, err + } + sig, err := crypto.SignatureFromBytes(in.GetSignature(), curveT) + if err != nil { + return nil, err + } + pubkey, err := crypto.PublicKeyFromBytes(in.GetPub(), curveT) + if err != nil { + return nil, err + } + match := pubkey.Verify(in.GetMessage(), sig) + if !match { + return nil, fmt.Errorf("Signature does not match") + } + + return &pbkeys.Empty{}, nil +} + +func (k *KeyStore) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.HashResponse, error) { + var hasher hash.Hash + switch in.GetHashtype() { + case "ripemd160": + hasher = ripemd160.New() + case "sha256": + hasher = sha256.New() + // case "sha3": + default: + return nil, fmt.Errorf("Unknown hash type %v", in.GetHashtype()) + } + + hasher.Write(in.GetMessage()) + + return &pbkeys.HashResponse{Hash: hex.EncodeUpperToString(hasher.Sum(nil))}, nil +} + +func (k *KeyStore) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest) (*pbkeys.ImportResponse, error) { + keyJSON := []byte(in.GetJSON()) + var err error + addr := IsValidKeyJson(keyJSON) + if addr != nil { + _, err = writeKey(k.keysDirPath, addr, keyJSON) + } else { + err = fmt.Errorf("invalid json key passed on command line") + } + if err != nil { + return nil, err + } + return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(addr)}, nil +} + +func (k *KeyStore) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkeys.ImportResponse, error) { + curveT, err := crypto.CurveTypeFromString(in.GetCurvetype()) + if err != nil { + return nil, err + } + key, err := NewKeyFromPriv(curveT, in.GetKeybytes()) + if err != nil { + return nil, err + } + + // store the new key + if err = k.StoreKey(in.GetPassphrase(), key); err != nil { + return nil, err + } + + if in.GetName() != "" { + if err := coreNameAdd(k.keysDirPath, in.GetName(), key.Address.String()); err != nil { + return nil, err + } + } + return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(key.Address[:])}, nil +} + +func (k *KeyStore) List(ctx context.Context, in *pbkeys.Name) (*pbkeys.ListResponse, error) { + names, err := coreNameList(k.keysDirPath) + if err != nil { + return nil, err + } + + var list []*pbkeys.Key + + for name, addr := range names { + list = append(list, &pbkeys.Key{Keyname: name, Address: addr}) + } + + return &pbkeys.ListResponse{Key: list}, nil +} + +func (k *KeyStore) RemoveName(ctx context.Context, in *pbkeys.Name) (*pbkeys.Empty, error) { + if in.GetKeyname() == "" { + return nil, fmt.Errorf("please specify a name") + } + + return &pbkeys.Empty{}, coreNameRm(k.keysDirPath, in.GetKeyname()) +} + +func (k *KeyStore) AddName(ctx context.Context, in *pbkeys.AddNameRequest) (*pbkeys.Empty, error) { + if in.GetKeyname() == "" { + return nil, fmt.Errorf("please specify a name") + } + + if in.GetAddress() == "" { + return nil, fmt.Errorf("please specify an address") + } + + return &pbkeys.Empty{}, coreNameAdd(k.keysDirPath, in.GetKeyname(), strings.ToUpper(in.GetAddress())) +} diff --git a/keys/server_test.go b/keys/server_test.go new file mode 100644 index 0000000000000000000000000000000000000000..614daaecb6f9eba0950acc29d9b1d43feef7f72a --- /dev/null +++ b/keys/server_test.go @@ -0,0 +1,179 @@ +package keys + +import ( + "bytes" + "context" + "crypto/sha256" + "fmt" + "os" + "testing" + "time" + + "golang.org/x/crypto/ripemd160" + + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/execution/evm/sha3" + "github.com/hyperledger/burrow/keys/pbkeys" + tm_crypto "github.com/tendermint/go-crypto" + "google.golang.org/grpc" +) + +type hashInfo struct { + data string + expected string +} + +var hashData = map[string]hashInfo{ + "sha256": {"hi", "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4"}, + "ripemd160": {"hi", "242485AB6BFD3502BCB3442EA2E211687B8E4D89"}, +} + +var ( + KEY_TYPES = []string{"ed25519", "secp256k1"} + HASH_TYPES = []string{"sha256", "ripemd160"} +) + +// start the server +func init() { + failedCh := make(chan error) + go func() { + err := StartStandAloneServer(DefaultKeysDir, DefaultHost, TestPort) + failedCh <- err + }() + tick := time.NewTicker(time.Second) + select { + case err := <-failedCh: + fmt.Println(err) + os.Exit(1) + case <-tick.C: + } +} + +func grpcKeysClient() pbkeys.KeysClient { + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + conn, err := grpc.Dial(DefaultHost+":"+TestPort, opts...) + if err != nil { + fmt.Printf("Failed to connect to grpc server: %v\n", err) + os.Exit(1) + } + return pbkeys.NewKeysClient(conn) +} + +func checkAddrFromPub(typ string, pub, addr []byte) error { + var addr2 []byte + switch typ { + case "ed25519": + tmPubKey := new(tm_crypto.PubKeyEd25519) + copy(tmPubKey[:], pub) + addr2 = tmPubKey.Address() + case "secp256k1": + sha := sha256.New() + sha.Write(pub) + + hash := ripemd160.New() + hash.Write(sha.Sum(nil)) + addr2 = hash.Sum(nil) + default: + return fmt.Errorf("Unknown or incomplete typ %s", typ) + } + if bytes.Compare(addr, addr2) != 0 { + return fmt.Errorf("Keygen addr doesn't match pub. Got %X, expected %X", addr2, addr) + } + return nil +} + +func testServerKeygenAndPub(t *testing.T, typ string) { + c := grpcKeysClient() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ}) + if err != nil { + t.Fatal(err) + } + addr := genresp.Address + resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr}) + if err != nil { + t.Fatal(err) + } + addrB, err := crypto.AddressFromHexString(addr) + if err != nil { + t.Fatal(err) + } + if err = checkAddrFromPub(typ, resp.GetPub(), addrB[:]); err != nil { + t.Fatal(err) + } +} + +func TestServerKeygenAndPub(t *testing.T) { + for _, typ := range KEY_TYPES { + testServerKeygenAndPub(t, typ) + } +} + +func testServerSignAndVerify(t *testing.T, typ string) { + c := grpcKeysClient() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ}) + if err != nil { + t.Fatal(err) + } + addr := genresp.Address + resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr}) + if err != nil { + t.Fatal(err) + } + hash := sha3.Sha3([]byte("the hash of something!")) + + sig, err := c.Sign(ctx, &pbkeys.SignRequest{Address: addr, Message: hash}) + if err != nil { + t.Fatal(err) + } + + _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Signature: sig.GetSignature(), Pub: resp.GetPub(), Message: hash, Curvetype: typ}) + if err != nil { + t.Fatal(err) + } +} + +func TestServerSignAndVerify(t *testing.T) { + for _, typ := range KEY_TYPES { + testServerSignAndVerify(t, typ) + } +} + +func testServerHash(t *testing.T, typ string) { + hData := hashData[typ] + data, expected := hData.data, hData.expected + + c := grpcKeysClient() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: typ, Message: []byte(data)}) + if err != nil { + t.Fatal(err) + } + hash := resp.GetHash() + + if hash != expected { + t.Fatalf("Hash error for %s. Got %s, expected %s", typ, hash, expected) + } +} + +func TestServerHash(t *testing.T) { + for _, typ := range HASH_TYPES { + testServerHash(t, typ) + } +} + +//--------------------------------------------------------------------------------- + +func checkErrs(t *testing.T, errS string, err error) { + if err != nil { + t.Fatal(err) + } + if errS != "" { + t.Fatal(errS) + } +} diff --git a/keys/test.sh b/keys/test.sh new file mode 100755 index 0000000000000000000000000000000000000000..7bb16ed18f12b9ee425fdc03a178aaa4d91fb7cb --- /dev/null +++ b/keys/test.sh @@ -0,0 +1,155 @@ +#! /bin/bash + +# tests +# run the suite with and without the daemon + +# TODO: run the suite with/without encryption! + + +burrow_bin=${burrow_bin:-burrow} + +echo "-----------------------------" +echo "starting the server" +$burrow_bin keys server & +keys_pid=$! +sleep 1 +echo "-----------------------------" +echo "testing the cli" + +# we test keys, hashes, names, and import +# this file should be run with and without the daemon running + +echo "testing keys" + +CURVETYPES=("ed25519" "secp256k1") +for CURVETYPE in ${CURVETYPES[*]} +do + # test key gen, sign verify: + # for each step, ensure it works using --addr or --name + echo "... $CURVETYPE" + + HASH=`$burrow_bin keys hash --type sha256 ok` + #echo "HASH: $HASH" + NAME=testkey1 + ADDR=`$burrow_bin keys gen --curvetype $CURVETYPE --name $NAME --no-password` + #echo "my addr: $ADDR" + PUB1=`$burrow_bin keys pub --name $NAME` + PUB2=`$burrow_bin keys pub --addr $ADDR` + if [ "$PUB1" != "$PUB2" ]; then + echo "FAILED pub: got $PUB2, expected $PUB1" + kill $keys_pid + exit 1 + fi + echo "...... passed pub" + + SIG1=`$burrow_bin keys sign --name $NAME $HASH` + VERIFY1=`$burrow_bin keys verify --curvetype $CURVETYPE $HASH $SIG1 $PUB1` + if [ $VERIFY1 != "true" ]; then + echo "FAILED verify: got $VERIFY1 expected true" + kill $keys_pid + exit 1 + fi + + SIG2=`$burrow_bin keys sign --addr $ADDR $HASH` + VERIFY1=`$burrow_bin keys verify --curvetype $CURVETYPE $HASH $SIG2 $PUB1` + if [ $VERIFY1 != "true" ]; then + echo "FAILED verify: got $VERIFY1 expected true" + kill $keys_pid + exit 1 + fi + + echo "...... passed sig/verify" + +done + +echo "testing hashes" +# test hashing (we need openssl) +TOHASH=okeydokey +HASHTYPES=(sha256 ripemd160) +for HASHTYPE in ${HASHTYPES[*]} +do + echo "... $HASHTYPE" + HASH0=`echo -n $TOHASH | openssl dgst -$HASHTYPE | awk '{print toupper($2)}'` + HASH1=`$burrow_bin keys hash --type $HASHTYPE $TOHASH` + if [ "$HASH0" != "$HASH1" ]; then + echo "FAILED hash $HASHTYPE: got $HASH1 expected $HASH0" + fi + echo "...... passed" +done + +echo "testing imports" + +# TODO: IMPORTS +# for each key type, import a priv key, ensure it returns +# the right address. do again with both plain and encrypted jsons + +for CURVETYPE in ${CURVETYPES[*]} +do + echo "... $CURVETYPE" + # create a key, get its address and priv, backup the json, delete the key + ADDR=`$burrow_bin keys gen --curvetype $CURVETYPE --no-password` + DIR=.keys/data + FILE=$DIR/$ADDR.json + PRIV=`cat $FILE | jq -r .PrivateKey.Plain` + HEXPRIV=`echo -n "$PRIV" | base64 -d | xxd -p -u -c 256` + cp $FILE ~/$ADDR + rm -rf $DIR + + # import the key via priv + ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE $HEXPRIV` + if [ "$ADDR" != "$ADDR2" ]; then + echo "FAILED import $CURVETYPE: got $ADDR2 expected $ADDR" + kill $keys_pid + exit + fi + rm -rf $DIR + + # import the key via json + JSON=`cat ~/$ADDR` + ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE $JSON` + if [ "$ADDR" != "$ADDR2" ]; then + echo "FAILED import (json) $CURVETYPE: got $ADDR2 expected $ADDR" + kill $keys_pid + exit + fi + rm -rf $DIR + + # import the key via path + ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE ~/$ADDR` + if [ "$ADDR" != "$ADDR2" ]; then + echo "FAILED import $CURVETYPE: got $ADDR2 expected $ADDR" + kill $keys_pid + exit + fi + rm -rf $DIR + + echo "...... passed raw hex and json" +done + + +echo "testing names" + +NAME=mykey +ADDR=`$burrow_bin keys gen --name $NAME --no-password` +ADDR2=`$burrow_bin keys list --name $NAME` +if [ "$ADDR" != "$ADDR2" ]; then + echo "FAILED name: got $ADDR2 expected $ADDR" + kill $keys_pid + exit +fi + +NAME2=mykey2 +$burrow_bin keys name $NAME2 $ADDR +ADDR2=`$burrow_bin keys list --name $NAME2` +if [ "$ADDR" != "$ADDR2" ]; then + echo "FAILED rename: got $ADDR2 expected $ADDR" + kill $keys_pid + exit +fi + +echo "... passed" + +kill $keys_pid + +# TODO a little more on names... + diff --git a/permission/snatives/snatives.go b/permission/snatives/snatives.go index 2323d83b641b49ec8065b578499a663efe74303e..40e560ea9087903b220e5eaec49a82a3721ce352 100644 --- a/permission/snatives/snatives.go +++ b/permission/snatives/snatives.go @@ -18,7 +18,7 @@ import ( "fmt" "strings" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/permission" "github.com/hyperledger/burrow/permission/types" ) @@ -28,7 +28,7 @@ import ( type PermArgs struct { PermFlag types.PermFlag - Address *acm.Address `json:",omitempty"` + Address *crypto.Address `json:",omitempty"` Permission *types.PermFlag `json:",omitempty"` Role *string `json:",omitempty"` Value *bool `json:",omitempty"` @@ -73,7 +73,7 @@ func (pa PermArgs) EnsureValid() error { return nil } -func HasBaseArgs(address acm.Address, permFlag types.PermFlag) PermArgs { +func HasBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs { return PermArgs{ PermFlag: permission.HasBase, Address: &address, @@ -81,7 +81,7 @@ func HasBaseArgs(address acm.Address, permFlag types.PermFlag) PermArgs { } } -func SetBaseArgs(address acm.Address, permFlag types.PermFlag, value bool) PermArgs { +func SetBaseArgs(address crypto.Address, permFlag types.PermFlag, value bool) PermArgs { return PermArgs{ PermFlag: permission.SetBase, Address: &address, @@ -90,7 +90,7 @@ func SetBaseArgs(address acm.Address, permFlag types.PermFlag, value bool) PermA } } -func UnsetBaseArgs(address acm.Address, permFlag types.PermFlag) PermArgs { +func UnsetBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs { return PermArgs{ PermFlag: permission.UnsetBase, Address: &address, @@ -106,7 +106,7 @@ func SetGlobalArgs(permFlag types.PermFlag, value bool) PermArgs { } } -func HasRoleArgs(address acm.Address, role string) PermArgs { +func HasRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ PermFlag: permission.HasRole, Address: &address, @@ -114,7 +114,7 @@ func HasRoleArgs(address acm.Address, role string) PermArgs { } } -func AddRoleArgs(address acm.Address, role string) PermArgs { +func AddRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ PermFlag: permission.AddRole, Address: &address, @@ -122,7 +122,7 @@ func AddRoleArgs(address acm.Address, role string) PermArgs { } } -func RemoveRoleArgs(address acm.Address, role string) PermArgs { +func RemoveRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ PermFlag: permission.RemoveRole, Address: &address, diff --git a/rpc/config.go b/rpc/config.go index eba0b7ed93758a45b0ae21539031dee279f579f1..9449609d98ead8a4330fa4fac0f4d2a8930ff9bf 100644 --- a/rpc/config.go +++ b/rpc/config.go @@ -3,23 +3,29 @@ package rpc import "github.com/hyperledger/burrow/rpc/v0/server" type RPCConfig struct { - V0 *V0Config `json:",omitempty" toml:",omitempty"` - TM *TMConfig `json:",omitempty" toml:",omitempty"` - Profiler *ProfilerConfig `json:",omitempty" toml:",omitempty"` + V0 *V0Config `json:",omitempty" toml:",omitempty"` + TM *ServerConfig `json:",omitempty" toml:",omitempty"` + Profiler *ServerConfig `json:",omitempty" toml:",omitempty"` + GRPC *ServerConfig `json:",omitempty" toml:",omitempty"` } -type TMConfig struct { - Disabled bool +type ServerConfig struct { + Enabled bool ListenAddress string } type V0Config struct { - Disabled bool - Server *server.ServerConfig + Enabled bool + Server *server.ServerConfig } type ProfilerConfig struct { - Disabled bool + Enabled bool + ListenAddress string +} + +type GRPCConfig struct { + Enabled bool ListenAddress string } @@ -28,23 +34,34 @@ func DefaultRPCConfig() *RPCConfig { TM: DefaultTMConfig(), V0: DefaultV0Config(), Profiler: DefaultProfilerConfig(), + GRPC: DefaultGRPCConfig(), } } + func DefaultV0Config() *V0Config { return &V0Config{ - Server: server.DefaultServerConfig(), + Enabled: true, + Server: server.DefaultServerConfig(), } } -func DefaultTMConfig() *TMConfig { - return &TMConfig{ +func DefaultTMConfig() *ServerConfig { + return &ServerConfig{ + Enabled: true, ListenAddress: "tcp://localhost:46657", } } -func DefaultProfilerConfig() *ProfilerConfig { - return &ProfilerConfig{ - Disabled: true, +func DefaultGRPCConfig() *ServerConfig { + return &ServerConfig{ + Enabled: true, + ListenAddress: "localhost:10997", + } +} + +func DefaultProfilerConfig() *ServerConfig { + return &ServerConfig{ + Enabled: false, ListenAddress: "tcp://localhost:6060", } } diff --git a/rpc/result.go b/rpc/result.go index 440a152aeb7928bcdb2544a35c93c060875e8b43..0de6909a798cfd266f6605ceb9342cdd44bd2fdf 100644 --- a/rpc/result.go +++ b/rpc/result.go @@ -19,6 +19,7 @@ import ( "fmt" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution" exe_events "github.com/hyperledger/burrow/execution/events" evm_events "github.com/hyperledger/burrow/execution/evm/events" @@ -74,7 +75,7 @@ type ResultGetBlock struct { type ResultStatus struct { NodeInfo p2p.NodeInfo GenesisHash []byte - PubKey acm.PublicKey + PubKey crypto.PublicKey LatestBlockHash []byte LatestBlockHeight uint64 LatestBlockTime int64 @@ -136,8 +137,8 @@ type ResultGetAccount struct { } type AccountHumanReadable struct { - Address acm.Address - PublicKey acm.PublicKey + Address crypto.Address + PublicKey crypto.PublicKey Sequence uint64 Balance uint64 Code []string diff --git a/rpc/result_test.go b/rpc/result_test.go index d275011305bb73617805140b91e324161e8cbf80..01c531e9527c79b94513c657c544073688d7caf0 100644 --- a/rpc/result_test.go +++ b/rpc/result_test.go @@ -19,6 +19,7 @@ import ( "testing" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/txs" "github.com/stretchr/testify/assert" @@ -31,7 +32,7 @@ func TestResultBroadcastTx(t *testing.T) { // Make sure these are unpacked as expected res := ResultBroadcastTx{ Receipt: txs.Receipt{ - ContractAddress: acm.Address{0, 2, 3}, + ContractAddress: crypto.Address{0, 2, 3}, CreatesContract: true, TxHash: []byte("foo"), }, @@ -50,7 +51,7 @@ func TestListUnconfirmedTxs(t *testing.T) { NumTxs: 3, Txs: []txs.Wrapper{ txs.Wrap(&txs.CallTx{ - Address: &acm.Address{1}, + Address: &crypto.Address{1}, }), }, } diff --git a/rpc/service.go b/rpc/service.go index 0ec8291cf95c88c3454bddc95f23e3ed04b4df54..415768f851caf0ca9d76252d6b344ddde20ec88c 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -23,6 +23,7 @@ import ( "github.com/hyperledger/burrow/binary" bcm "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/consensus/tendermint/query" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/keys" @@ -222,7 +223,7 @@ func (s *Service) Genesis() (*ResultGenesis, error) { } // Accounts -func (s *Service) GetAccount(address acm.Address) (*ResultGetAccount, error) { +func (s *Service) GetAccount(address crypto.Address) (*ResultGetAccount, error) { acc, err := s.state.GetAccount(address) if err != nil { return nil, err @@ -248,7 +249,7 @@ func (s *Service) ListAccounts(predicate func(acm.Account) bool) (*ResultListAcc }, nil } -func (s *Service) GetStorage(address acm.Address, key []byte) (*ResultGetStorage, error) { +func (s *Service) GetStorage(address crypto.Address, key []byte) (*ResultGetStorage, error) { account, err := s.state.GetAccount(address) if err != nil { return nil, err @@ -267,7 +268,7 @@ func (s *Service) GetStorage(address acm.Address, key []byte) (*ResultGetStorage return &ResultGetStorage{Key: key, Value: value.UnpadLeft()}, nil } -func (s *Service) DumpStorage(address acm.Address) (*ResultDumpStorage, error) { +func (s *Service) DumpStorage(address crypto.Address) (*ResultDumpStorage, error) { account, err := s.state.GetAccount(address) if err != nil { return nil, err @@ -286,7 +287,7 @@ func (s *Service) DumpStorage(address acm.Address) (*ResultDumpStorage, error) { }, nil } -func (s *Service) GetAccountHumanReadable(address acm.Address) (*ResultGetAccountHumanReadable, error) { +func (s *Service) GetAccountHumanReadable(address crypto.Address) (*ResultGetAccountHumanReadable, error) { acc, err := s.state.GetAccount(address) if err != nil { return nil, err diff --git a/rpc/tm/client/client.go b/rpc/tm/client/client.go index fffdeb72bbb1e3a5e55b605eb3dbc76a0750463f..773f34436402623306fe993425a245cb2f02c4af 100644 --- a/rpc/tm/client/client.go +++ b/rpc/tm/client/client.go @@ -19,6 +19,7 @@ import ( "fmt" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/rpc" "github.com/hyperledger/burrow/rpc/tm" @@ -65,7 +66,7 @@ func GenPrivAccount(client RPCClient) (*rpc.ResultGeneratePrivateAccount, error) return res, nil } -func GetAccount(client RPCClient, address acm.Address) (acm.Account, error) { +func GetAccount(client RPCClient, address crypto.Address) (acm.Account, error) { res := new(rpc.ResultGetAccount) _, err := client.Call(tm.GetAccount, pmap("address", address), res) if err != nil { @@ -87,7 +88,7 @@ func SignTx(client RPCClient, tx txs.Tx, privAccounts []*acm.ConcretePrivateAcco return res.Tx, nil } -func DumpStorage(client RPCClient, address acm.Address) (*rpc.ResultDumpStorage, error) { +func DumpStorage(client RPCClient, address crypto.Address) (*rpc.ResultDumpStorage, error) { res := new(rpc.ResultDumpStorage) _, err := client.Call(tm.DumpStorage, pmap("address", address), res) if err != nil { @@ -96,7 +97,7 @@ func DumpStorage(client RPCClient, address acm.Address) (*rpc.ResultDumpStorage, return res, nil } -func GetStorage(client RPCClient, address acm.Address, key []byte) ([]byte, error) { +func GetStorage(client RPCClient, address crypto.Address, key []byte) ([]byte, error) { res := new(rpc.ResultGetStorage) _, err := client.Call(tm.GetStorage, pmap("address", address, "key", key), res) if err != nil { @@ -105,7 +106,7 @@ func GetStorage(client RPCClient, address acm.Address, key []byte) ([]byte, erro return res.Value, nil } -func CallCode(client RPCClient, fromAddress acm.Address, code, data []byte) (*rpc.ResultCall, error) { +func CallCode(client RPCClient, fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) { res := new(rpc.ResultCall) _, err := client.Call(tm.CallCode, pmap("fromAddress", fromAddress, "code", code, "data", data), res) if err != nil { @@ -114,7 +115,7 @@ func CallCode(client RPCClient, fromAddress acm.Address, code, data []byte) (*rp return res, nil } -func Call(client RPCClient, fromAddress, toAddress acm.Address, data []byte) (*rpc.ResultCall, error) { +func Call(client RPCClient, fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) { res := new(rpc.ResultCall) _, err := client.Call(tm.Call, pmap("fromAddress", fromAddress, "toAddress", toAddress, "data", data), res) diff --git a/rpc/tm/integration/shared.go b/rpc/tm/integration/shared.go index e9c1981f3554daaf5af1d065ac41d3db7b53ae62..ee6e0aee21a191ef05991780a1598cba415ea5b9 100644 --- a/rpc/tm/integration/shared.go +++ b/rpc/tm/integration/shared.go @@ -25,6 +25,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/core/integration" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/rpc" tm_client "github.com/hyperledger/burrow/rpc/tm/client" @@ -54,7 +55,7 @@ var ( //------------------------------------------------------------------------------- // some default transaction functions -func makeDefaultSendTx(t *testing.T, client tm_client.RPCClient, addr acm.Address, amt uint64) *txs.SendTx { +func makeDefaultSendTx(t *testing.T, client tm_client.RPCClient, addr crypto.Address, amt uint64) *txs.SendTx { sequence := getSequence(t, client, privateAccounts[0].Address()) tx := txs.NewSendTx() tx.AddInputWithSequence(privateAccounts[0].PublicKey(), amt, sequence+1) @@ -62,13 +63,13 @@ func makeDefaultSendTx(t *testing.T, client tm_client.RPCClient, addr acm.Addres return tx } -func makeDefaultSendTxSigned(t *testing.T, client tm_client.RPCClient, addr acm.Address, amt uint64) *txs.SendTx { +func makeDefaultSendTxSigned(t *testing.T, client tm_client.RPCClient, addr crypto.Address, amt uint64) *txs.SendTx { tx := makeDefaultSendTx(t, client, addr, amt) require.NoError(t, tx.Sign(genesisDoc.ChainID(), privateAccounts[0])) return tx } -func makeDefaultCallTx(t *testing.T, client tm_client.RPCClient, addr *acm.Address, code []byte, amt, gasLim, +func makeDefaultCallTx(t *testing.T, client tm_client.RPCClient, addr *crypto.Address, code []byte, amt, gasLim, fee uint64) *txs.CallTx { sequence := getSequence(t, client, privateAccounts[0].Address()) tx := txs.NewCallTxWithSequence(privateAccounts[0].PublicKey(), addr, code, amt, gasLim, fee, @@ -88,7 +89,7 @@ func makeDefaultNameTx(t *testing.T, client tm_client.RPCClient, name, value str // rpc call wrappers (fail on err) // get an account's sequence number -func getSequence(t *testing.T, client tm_client.RPCClient, addr acm.Address) uint64 { +func getSequence(t *testing.T, client tm_client.RPCClient, addr crypto.Address) uint64 { acc, err := tm_client.GetAccount(client, addr) if err != nil { t.Fatal(err) @@ -100,7 +101,7 @@ func getSequence(t *testing.T, client tm_client.RPCClient, addr acm.Address) uin } // get the account -func getAccount(t *testing.T, client tm_client.RPCClient, addr acm.Address) acm.Account { +func getAccount(t *testing.T, client tm_client.RPCClient, addr crypto.Address) acm.Account { ac, err := tm_client.GetAccount(client, addr) if err != nil { t.Fatal(err) @@ -126,7 +127,7 @@ func broadcastTx(t *testing.T, client tm_client.RPCClient, tx txs.Tx) *txs.Recei } // dump all storage for an account. currently unused -func dumpStorage(t *testing.T, addr acm.Address) *rpc.ResultDumpStorage { +func dumpStorage(t *testing.T, addr crypto.Address) *rpc.ResultDumpStorage { client := clients["HTTP"] resp, err := tm_client.DumpStorage(client, addr) if err != nil { @@ -135,7 +136,7 @@ func dumpStorage(t *testing.T, addr acm.Address) *rpc.ResultDumpStorage { return resp } -func getStorage(t *testing.T, client tm_client.RPCClient, addr acm.Address, key []byte) []byte { +func getStorage(t *testing.T, client tm_client.RPCClient, addr crypto.Address, key []byte) []byte { resp, err := tm_client.GetStorage(client, addr, key) if err != nil { t.Fatal(err) @@ -143,7 +144,7 @@ func getStorage(t *testing.T, client tm_client.RPCClient, addr acm.Address, key return resp } -func callCode(t *testing.T, client tm_client.RPCClient, fromAddress acm.Address, code, data, +func callCode(t *testing.T, client tm_client.RPCClient, fromAddress crypto.Address, code, data, expected []byte) { resp, err := tm_client.CallCode(client, fromAddress, code, data) if err != nil { @@ -156,7 +157,7 @@ func callCode(t *testing.T, client tm_client.RPCClient, fromAddress acm.Address, } } -func callContract(t *testing.T, client tm_client.RPCClient, fromAddress, toAddress acm.Address, +func callContract(t *testing.T, client tm_client.RPCClient, fromAddress, toAddress crypto.Address, data, expected []byte) { resp, err := tm_client.Call(client, fromAddress, toAddress, data) if err != nil { @@ -209,7 +210,7 @@ func simpleContract() ([]byte, []byte, []byte) { } // simple call contract calls another contract -func simpleCallContract(addr acm.Address) ([]byte, []byte, []byte) { +func simpleCallContract(addr crypto.Address) ([]byte, []byte, []byte) { gas1, gas2 := byte(0x1), byte(0x1) value := byte(0x1) inOff, inSize := byte(0x0), byte(0x0) // no call data diff --git a/rpc/tm/integration/websocket_client_test.go b/rpc/tm/integration/websocket_client_test.go index 00b3c7234ef9c89b517d20f8035dead41fca8a8b..d19e32fe4892600b08efff4315e27a34cecb3e49 100644 --- a/rpc/tm/integration/websocket_client_test.go +++ b/rpc/tm/integration/websocket_client_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" exe_events "github.com/hyperledger/burrow/execution/events" evm_events "github.com/hyperledger/burrow/execution/evm/events" "github.com/hyperledger/burrow/rpc" @@ -171,7 +171,7 @@ func TestWSCallWait(t *testing.T) { for i := 0; i < 20; i++ { amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000) code, returnCode, returnVal := simpleContract() - var contractAddr acm.Address + var contractAddr crypto.Address eid1 := exe_events.EventStringAccountInput(privateAccounts[0].Address()) subId1 := subscribeAndGetSubscriptionId(t, wsc, eid1) // wait for the contract to be created diff --git a/rpc/tm/integration/websocket_helpers.go b/rpc/tm/integration/websocket_helpers.go index ea30de8f3aac27685c104ccff78aee33fc930fde..2df6cd390bfb4151cad5cbb092447ee39b9cf42c 100644 --- a/rpc/tm/integration/websocket_helpers.go +++ b/rpc/tm/integration/websocket_helpers.go @@ -25,7 +25,7 @@ import ( "testing" "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/events" "github.com/hyperledger/burrow/rpc" tm_client "github.com/hyperledger/burrow/rpc/tm/client" @@ -245,7 +245,7 @@ func readResponse(r rpctypes.RPCResponse) (*rpc.ResultEvent, error) { //-------------------------------------------------------------------------------- -func unmarshalValidateSend(amt uint64, toAddr acm.Address, resultEvent *rpc.ResultEvent) error { +func unmarshalValidateSend(amt uint64, toAddr crypto.Address, resultEvent *rpc.ResultEvent) error { data := resultEvent.EventDataTx if data == nil { return fmt.Errorf("event data %v is not EventDataTx", resultEvent) @@ -294,7 +294,7 @@ func unmarshalValidateTx(amt uint64, returnCode []byte) resultEventChecker { } } -func unmarshalValidateCall(origin acm.Address, returnCode []byte, txid *[]byte) resultEventChecker { +func unmarshalValidateCall(origin crypto.Address, returnCode []byte, txid *[]byte) resultEventChecker { return func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { data := resultEvent.EventDataCall if data == nil { diff --git a/rpc/tm/methods.go b/rpc/tm/methods.go index 49e6696f68290258078e84e2ce6a3d3415caaf8a..4f54885aa390f78a11ce462e5c4bf8348a2e5382 100644 --- a/rpc/tm/methods.go +++ b/rpc/tm/methods.go @@ -6,6 +6,7 @@ import ( "time" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/logging" @@ -79,7 +80,7 @@ func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*gorpc.R }, "tx,privAccounts"), // Simulated call - Call: gorpc.NewRPCFunc(func(fromAddress, toAddress acm.Address, data []byte) (*rpc.ResultCall, error) { + Call: gorpc.NewRPCFunc(func(fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) { call, err := service.Transactor().Call(service.State(), fromAddress, toAddress, data) if err != nil { return nil, err @@ -87,7 +88,7 @@ func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*gorpc.R return &rpc.ResultCall{Call: *call}, nil }, "fromAddress,toAddress,data"), - CallCode: gorpc.NewRPCFunc(func(fromAddress acm.Address, code, data []byte) (*rpc.ResultCall, error) { + CallCode: gorpc.NewRPCFunc(func(fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) { call, err := service.Transactor().CallCode(service.State(), fromAddress, code, data) if err != nil { return nil, err diff --git a/rpc/v0/codec_test.go b/rpc/v0/codec_test.go index 5bd6d231906c9940e0484857ecca91267e1cb3ad..500afb1e5c8f8f8ab4adfb42da5c4ceb49bed822 100644 --- a/rpc/v0/codec_test.go +++ b/rpc/v0/codec_test.go @@ -17,22 +17,22 @@ package v0 import ( "testing" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestKeysEncoding(t *testing.T) { codec := NewTCodec() - privateKey := acm.PrivateKeyFromSecret("foo") + privateKey := crypto.PrivateKeyFromSecret("foo", crypto.CurveTypeEd25519) type keyPair struct { - PrivateKey acm.PrivateKey - PublicKey acm.PublicKey + PrivateKey crypto.PrivateKey + PublicKey crypto.PublicKey } kp := keyPair{ PrivateKey: privateKey, - PublicKey: privateKey.PublicKey(), + PublicKey: privateKey.GetPublicKey(), } bs, err := codec.EncodeBytes(kp) diff --git a/rpc/v0/methods.go b/rpc/v0/methods.go index 0226189e399ed8719d004732b9d0753f95f35232..3209b7f36952ac94608742f88236c1cbaa7f0487 100644 --- a/rpc/v0/methods.go +++ b/rpc/v0/methods.go @@ -18,6 +18,7 @@ import ( "fmt" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/rpc" @@ -97,7 +98,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - address, err := acm.AddressFromBytes(param.Address) + address, err := crypto.AddressFromBytes(param.Address) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -113,7 +114,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - address, err := acm.AddressFromBytes(param.Address) + address, err := crypto.AddressFromBytes(param.Address) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -129,7 +130,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - address, err := acm.AddressFromBytes(param.Address) + address, err := crypto.AddressFromBytes(param.Address) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -165,11 +166,11 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - from, err := acm.AddressFromBytes(param.From) + from, err := crypto.AddressFromBytes(param.From) if err != nil { return nil, rpc.INVALID_PARAMS, err } - address, err := acm.AddressFromBytes(param.Address) + address, err := crypto.AddressFromBytes(param.Address) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -185,7 +186,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - from, err := acm.AddressFromBytes(param.From) + from, err := crypto.AddressFromBytes(param.From) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -226,7 +227,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - address, err := acm.MaybeAddressFromBytes(param.Address) + address, err := crypto.MaybeAddressFromBytes(param.Address) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -247,7 +248,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - address, err := acm.MaybeAddressFromBytes(param.Address) + address, err := crypto.MaybeAddressFromBytes(param.Address) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -267,7 +268,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - toAddress, err := acm.AddressFromBytes(param.ToAddress) + toAddress, err := crypto.AddressFromBytes(param.ToAddress) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -288,7 +289,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m if err != nil { return nil, rpc.INVALID_PARAMS, err } - toAddress, err := acm.AddressFromBytes(param.ToAddress) + toAddress, err := crypto.AddressFromBytes(param.ToAddress) if err != nil { return nil, rpc.INVALID_PARAMS, err } @@ -449,7 +450,7 @@ func signingAccount(accounts *execution.Accounts, inputAccount InputAccount) (*e if len(inputAccount.PrivateKey) > 0 { return nil, fmt.Errorf("privKey and address provided but only one or the other should be given") } - address, err := acm.AddressFromBytes(inputAccount.Address) + address, err := crypto.AddressFromBytes(inputAccount.Address) if err != nil { return nil, err } diff --git a/rpc/v0/server/server.go b/rpc/v0/server/server.go index 2ee096c5b2aef767c3d121c6a169888c94296a6d..ec4c89c2e8d7733ef4c5d0c16460780f22a7f4dc 100644 --- a/rpc/v0/server/server.go +++ b/rpc/v0/server/server.go @@ -63,8 +63,8 @@ type ServeProcess struct { // Initializes all the servers and starts listening for connections. func (serveProcess *ServeProcess) Start() error { - router := gin.New() gin.SetMode(gin.ReleaseMode) + router := gin.New() config := serveProcess.config ch := NewCORSMiddleware(config.CORS) diff --git a/txs/bond_tx.go b/txs/bond_tx.go index aa6aecea7d64472134e3a87ce99f17f3ed5c3824..a7100ddf86f4094d5313f5288da10e5e63131d24 100644 --- a/txs/bond_tx.go +++ b/txs/bond_tx.go @@ -6,12 +6,13 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) type BondTx struct { - PubKey acm.PublicKey - Signature acm.Signature + PubKey crypto.PublicKey + Signature crypto.Signature Inputs []*TxInput UnbondTo []*TxOutput txHashMemoizer @@ -19,7 +20,7 @@ type BondTx struct { var _ Tx = &BondTx{} -func NewBondTx(pubkey acm.PublicKey) (*BondTx, error) { +func NewBondTx(pubkey crypto.PublicKey) (*BondTx, error) { return &BondTx{ PubKey: pubkey, Inputs: []*TxInput{}, @@ -60,7 +61,7 @@ func (tx *BondTx) Hash(chainID string) []byte { return tx.txHashMemoizer.hash(chainID, tx) } -func (tx *BondTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uint64) error { +func (tx *BondTx) AddInput(st state.AccountGetter, pubkey crypto.PublicKey, amt uint64) error { addr := pubkey.Address() acc, err := st.GetAccount(addr) if err != nil { @@ -72,7 +73,7 @@ func (tx *BondTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uin return tx.AddInputWithSequence(pubkey, amt, acc.Sequence()+uint64(1)) } -func (tx *BondTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequence uint64) error { +func (tx *BondTx) AddInputWithSequence(pubkey crypto.PublicKey, amt uint64, sequence uint64) error { tx.Inputs = append(tx.Inputs, &TxInput{ Address: pubkey.Address(), Amount: amt, @@ -82,7 +83,7 @@ func (tx *BondTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequenc return nil } -func (tx *BondTx) AddOutput(addr acm.Address, amt uint64) error { +func (tx *BondTx) AddOutput(addr crypto.Address, amt uint64) error { tx.UnbondTo = append(tx.UnbondTo, &TxOutput{ Address: addr, Amount: amt, @@ -96,13 +97,13 @@ func (tx *BondTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner) len(signingAccounts)) } var err error - tx.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx) + tx.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx) if err != nil { return fmt.Errorf("could not sign %v: %v", tx, err) } for i := 1; i <= len(signingAccounts); i++ { tx.Inputs[i].PublicKey = signingAccounts[i].PublicKey() - tx.Inputs[i].Signature, err = acm.ChainSign(signingAccounts[i], chainID, tx) + tx.Inputs[i].Signature, err = crypto.ChainSign(signingAccounts[i], chainID, tx) if err != nil { return fmt.Errorf("could not sign tx %v input %v: %v", tx, tx.Inputs[i], err) } diff --git a/txs/call_tx.go b/txs/call_tx.go index a3d0f1b849db203f34c55739bfd827ede46af135..ebfdb6f49f05444c23e56278f9e087af2b788b61 100644 --- a/txs/call_tx.go +++ b/txs/call_tx.go @@ -6,13 +6,14 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) type CallTx struct { Input *TxInput // Pointer since CallTx defines unset 'to' address as inducing account creation - Address *acm.Address + Address *crypto.Address GasLimit uint64 Fee uint64 Data []byte @@ -21,7 +22,7 @@ type CallTx struct { var _ Tx = &CallTx{} -func NewCallTx(st state.AccountGetter, from acm.PublicKey, to *acm.Address, data []byte, +func NewCallTx(st state.AccountGetter, from crypto.PublicKey, to *crypto.Address, data []byte, amt, gasLimit, fee uint64) (*CallTx, error) { addr := from.Address() @@ -37,7 +38,7 @@ func NewCallTx(st state.AccountGetter, from acm.PublicKey, to *acm.Address, data return NewCallTxWithSequence(from, to, data, amt, gasLimit, fee, sequence), nil } -func NewCallTxWithSequence(from acm.PublicKey, to *acm.Address, data []byte, +func NewCallTxWithSequence(from crypto.PublicKey, to *crypto.Address, data []byte, amt, gasLimit, fee, sequence uint64) *CallTx { input := &TxInput{ Address: from.Address(), @@ -62,7 +63,7 @@ func (tx *CallTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner) } var err error tx.Input.PublicKey = signingAccounts[0].PublicKey() - tx.Input.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx) + tx.Input.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx) if err != nil { return fmt.Errorf("could not sign %v: %v", tx, err) } diff --git a/txs/go_wire_codec_test.go b/txs/go_wire_codec_test.go index 7e191c19e6d5818b296064b27cda244780ddea9f..4b4dd579ef4d1926d84bdd638ea37b23541f5350 100644 --- a/txs/go_wire_codec_test.go +++ b/txs/go_wire_codec_test.go @@ -3,21 +3,23 @@ package txs import ( "testing" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/stretchr/testify/assert" ) func TestEncodeTxDecodeTx(t *testing.T) { gwc := NewGoWireCodec() - inputAddress := acm.Address{1, 2, 3, 4, 5} - outputAddress := acm.Address{5, 4, 3, 2, 1} + inputAddress := crypto.Address{1, 2, 3, 4, 5} + outputAddress := crypto.Address{5, 4, 3, 2, 1} amount := uint64(2) sequence := uint64(3) tx := &SendTx{ Inputs: []*TxInput{{ - Address: inputAddress, - Amount: amount, - Sequence: sequence, + Address: inputAddress, + Amount: amount, + Sequence: sequence, + PublicKey: crypto.PublicKey{PublicKey: []byte{0}}, + Signature: crypto.Signature{Signature: []byte{0}}, }}, Outputs: []*TxOutput{{ Address: outputAddress, @@ -35,14 +37,16 @@ func TestEncodeTxDecodeTx(t *testing.T) { func TestEncodeTxDecodeTx_CallTx(t *testing.T) { gwc := NewGoWireCodec() - inputAddress := acm.Address{1, 2, 3, 4, 5} + inputAddress := crypto.Address{1, 2, 3, 4, 5} amount := uint64(2) sequence := uint64(3) tx := &CallTx{ Input: &TxInput{ - Address: inputAddress, - Amount: amount, - Sequence: sequence, + Address: inputAddress, + Amount: amount, + Sequence: sequence, + PublicKey: crypto.PublicKey{PublicKey: []byte{0}}, + Signature: crypto.Signature{Signature: []byte{0}}, }, GasLimit: 233, Fee: 2, diff --git a/txs/name_tx.go b/txs/name_tx.go index 76ef57dceb4b4d568e1f5da46d9ce5d4575e5480..d16ff0d1c026da67fa7052433d451595b05518e0 100644 --- a/txs/name_tx.go +++ b/txs/name_tx.go @@ -8,6 +8,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) @@ -26,7 +27,7 @@ type NameTx struct { var _ Tx = &NameTx{} -func NewNameTx(st state.AccountGetter, from acm.PublicKey, name, data string, amt, fee uint64) (*NameTx, error) { +func NewNameTx(st state.AccountGetter, from crypto.PublicKey, name, data string, amt, fee uint64) (*NameTx, error) { addr := from.Address() acc, err := st.GetAccount(addr) if err != nil { @@ -40,7 +41,7 @@ func NewNameTx(st state.AccountGetter, from acm.PublicKey, name, data string, am return NewNameTxWithSequence(from, name, data, amt, fee, sequence), nil } -func NewNameTxWithSequence(from acm.PublicKey, name, data string, amt, fee, sequence uint64) *NameTx { +func NewNameTxWithSequence(from crypto.PublicKey, name, data string, amt, fee, sequence uint64) *NameTx { input := &TxInput{ Address: from.Address(), Amount: amt, @@ -63,7 +64,7 @@ func (tx *NameTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner) } var err error tx.Input.PublicKey = signingAccounts[0].PublicKey() - tx.Input.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx) + tx.Input.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx) if err != nil { return fmt.Errorf("could not sign %v: %v", tx, err) } diff --git a/txs/permission_tx.go b/txs/permission_tx.go index c2dad89bf1750cd35ab217fa613e591ce64305f1..2ec99eb81d921810594f1feeffaeab554eeb4109 100644 --- a/txs/permission_tx.go +++ b/txs/permission_tx.go @@ -6,6 +6,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/permission/snatives" "github.com/tendermint/go-wire" ) @@ -18,7 +19,7 @@ type PermissionsTx struct { var _ Tx = &PermissionsTx{} -func NewPermissionsTx(st state.AccountGetter, from acm.PublicKey, args snatives.PermArgs) (*PermissionsTx, error) { +func NewPermissionsTx(st state.AccountGetter, from crypto.PublicKey, args snatives.PermArgs) (*PermissionsTx, error) { addr := from.Address() acc, err := st.GetAccount(addr) if err != nil { @@ -32,7 +33,7 @@ func NewPermissionsTx(st state.AccountGetter, from acm.PublicKey, args snatives. return NewPermissionsTxWithSequence(from, args, sequence), nil } -func NewPermissionsTxWithSequence(from acm.PublicKey, args snatives.PermArgs, sequence uint64) *PermissionsTx { +func NewPermissionsTxWithSequence(from crypto.PublicKey, args snatives.PermArgs, sequence uint64) *PermissionsTx { input := &TxInput{ Address: from.Address(), Amount: 1, // NOTE: amounts can't be 0 ... @@ -53,7 +54,7 @@ func (tx *PermissionsTx) Sign(chainID string, signingAccounts ...acm.Addressable } var err error tx.Input.PublicKey = signingAccounts[0].PublicKey() - tx.Input.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx) + tx.Input.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx) if err != nil { return fmt.Errorf("could not sign %v: %v", tx, err) } diff --git a/txs/rebond_tx.go b/txs/rebond_tx.go index b5b22ff4b0f87e123b6b7101f2049b28d47405e5..8816937d18f67fc7a8713947e0e78c22204e1bb8 100644 --- a/txs/rebond_tx.go +++ b/txs/rebond_tx.go @@ -5,19 +5,20 @@ import ( "io" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) type RebondTx struct { - Address acm.Address + Address crypto.Address Height int - Signature acm.Signature + Signature crypto.Signature txHashMemoizer } var _ Tx = &RebondTx{} -func NewRebondTx(addr acm.Address, height int) *RebondTx { +func NewRebondTx(addr crypto.Address, height int) *RebondTx { return &RebondTx{ Address: addr, Height: height, @@ -30,7 +31,7 @@ func (tx *RebondTx) Sign(chainID string, signingAccounts ...acm.AddressableSigne len(signingAccounts)) } var err error - tx.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx) + tx.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx) if err != nil { return fmt.Errorf("could not sign %v: %v", tx, err) } diff --git a/txs/send_tx.go b/txs/send_tx.go index e9212fd8042ff5511a643b6b2ea7c32a94065978..421d9f190e2d75fdca637d0b7a686409d7a78833 100644 --- a/txs/send_tx.go +++ b/txs/send_tx.go @@ -6,6 +6,7 @@ import ( acm "github.com/hyperledger/burrow/account" "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) @@ -55,7 +56,7 @@ func (tx *SendTx) Hash(chainID string) []byte { return tx.txHashMemoizer.hash(chainID, tx) } -func (tx *SendTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uint64) error { +func (tx *SendTx) AddInput(st state.AccountGetter, pubkey crypto.PublicKey, amt uint64) error { addr := pubkey.Address() acc, err := st.GetAccount(addr) if err != nil { @@ -67,7 +68,7 @@ func (tx *SendTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uin return tx.AddInputWithSequence(pubkey, amt, acc.Sequence()+1) } -func (tx *SendTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequence uint64) error { +func (tx *SendTx) AddInputWithSequence(pubkey crypto.PublicKey, amt uint64, sequence uint64) error { addr := pubkey.Address() tx.Inputs = append(tx.Inputs, &TxInput{ Address: addr, @@ -78,7 +79,7 @@ func (tx *SendTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequenc return nil } -func (tx *SendTx) AddOutput(addr acm.Address, amt uint64) error { +func (tx *SendTx) AddOutput(addr crypto.Address, amt uint64) error { tx.Outputs = append(tx.Outputs, &TxOutput{ Address: addr, Amount: amt, @@ -94,7 +95,7 @@ func (tx *SendTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner) var err error for i, signingAccount := range signingAccounts { tx.Inputs[i].PublicKey = signingAccount.PublicKey() - tx.Inputs[i].Signature, err = acm.ChainSign(signingAccount, chainID, tx) + tx.Inputs[i].Signature, err = crypto.ChainSign(signingAccount, chainID, tx) if err != nil { return fmt.Errorf("could not sign tx %v input %v: %v", tx, tx.Inputs[i], err) } diff --git a/txs/tx.go b/txs/tx.go index dec958e22c3f19420a819d81a2f0e10d795bc2f8..e20292ef1f2f0e126b1a03ee8dc33013033453bd 100644 --- a/txs/tx.go +++ b/txs/tx.go @@ -21,6 +21,7 @@ import ( "io" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire/data" "golang.org/x/crypto/ripemd160" ) @@ -99,7 +100,7 @@ type Decoder interface { type Receipt struct { TxHash []byte CreatesContract bool - ContractAddress acm.Address + ContractAddress crypto.Address } type Wrapper struct { @@ -153,7 +154,7 @@ func (thm *txHashMemoizer) hash(chainID string, tx Tx) []byte { } func TxHash(chainID string, tx Tx) []byte { - signBytes := acm.SignBytes(chainID, tx) + signBytes := crypto.SignBytes(chainID, tx) hasher := ripemd160.New() hasher.Write(signBytes) // Calling Sum(nil) just gives us the digest with nothing prefixed @@ -167,7 +168,7 @@ func GenerateReceipt(chainId string, tx Tx) Receipt { if callTx, ok := tx.(*CallTx); ok { receipt.CreatesContract = callTx.Address == nil if receipt.CreatesContract { - receipt.ContractAddress = acm.NewContractAddress(callTx.Input.Address, callTx.Input.Sequence) + receipt.ContractAddress = crypto.NewContractAddress(callTx.Input.Address, callTx.Input.Sequence) } else { receipt.ContractAddress = *callTx.Address } diff --git a/txs/tx_input.go b/txs/tx_input.go index 8ed9059da1b7d1827b310f8b0b58a77c1ea6ef1d..b8d4d4a974ffb741bf2234699bdb6ad81a7aeffa 100644 --- a/txs/tx_input.go +++ b/txs/tx_input.go @@ -4,16 +4,16 @@ import ( "fmt" "io" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) type TxInput struct { - Address acm.Address + Address crypto.Address Amount uint64 Sequence uint64 - Signature acm.Signature - PublicKey acm.PublicKey + Signature crypto.Signature + PublicKey crypto.PublicKey } func (txIn *TxInput) ValidateBasic() error { diff --git a/txs/tx_output.go b/txs/tx_output.go index 79c17b4953aa5e7ba4c41119e6c7546f4dd8c5a3..7467d29b13d6f511099d02388cf521b2dc0f06bd 100644 --- a/txs/tx_output.go +++ b/txs/tx_output.go @@ -4,12 +4,12 @@ import ( "fmt" "io" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) type TxOutput struct { - Address acm.Address + Address crypto.Address Amount uint64 } diff --git a/txs/tx_test.go b/txs/tx_test.go index 73c7da8e113baae7ef6f6ad8a45cbf85185dd5d9..44f9892a73027b41bfc6be9a7c70b13ffbd31023 100644 --- a/txs/tx_test.go +++ b/txs/tx_test.go @@ -21,6 +21,7 @@ import ( "encoding/json" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" ptypes "github.com/hyperledger/burrow/permission" "github.com/hyperledger/burrow/permission/snatives" "github.com/stretchr/testify/assert" @@ -29,7 +30,7 @@ import ( var chainID = "myChainID" -func makeAddress(str string) (address acm.Address) { +func makeAddress(str string) (address crypto.Address) { copy(address[:], ([]byte)(str)) return } @@ -59,7 +60,7 @@ func TestSendTxSignable(t *testing.T) { }, }, } - signBytes := acm.SignBytes(chainID, sendTx) + signBytes := crypto.SignBytes(chainID, sendTx) signStr := string(signBytes) expected := fmt.Sprintf(`{"chain_id":"%s","tx":[1,{"inputs":[{"address":"%s","amount":12345,"sequence":67890},{"address":"%s","amount":111,"sequence":222}],"outputs":[{"address":"%s","amount":333},{"address":"%s","amount":444}]}]}`, chainID, sendTx.Inputs[0].Address.String(), sendTx.Inputs[1].Address.String(), sendTx.Outputs[0].Address.String(), sendTx.Outputs[1].Address.String()) @@ -82,7 +83,7 @@ func TestCallTxSignable(t *testing.T) { Fee: 222, Data: []byte("data1"), } - signBytes := acm.SignBytes(chainID, callTx) + signBytes := crypto.SignBytes(chainID, callTx) signStr := string(signBytes) expected := fmt.Sprintf(`{"chain_id":"%s","tx":[2,{"address":"%s","data":"6461746131","fee":222,"gas_limit":111,"input":{"address":"%s","amount":12345,"sequence":67890}}]}`, chainID, callTx.Address.String(), callTx.Input.Address.String()) @@ -102,7 +103,7 @@ func TestNameTxSignable(t *testing.T) { Data: "secretly.not.google.com", Fee: 1000, } - signBytes := acm.SignBytes(chainID, nameTx) + signBytes := crypto.SignBytes(chainID, nameTx) signStr := string(signBytes) expected := fmt.Sprintf(`{"chain_id":"%s","tx":[3,{"data":"secretly.not.google.com","fee":1000,"input":{"address":"%s","amount":12345,"sequence":250},"name":"google.com"}]}`, chainID, nameTx.Input.Address.String()) @@ -141,7 +142,7 @@ func TestBondTxSignable(t *testing.T) { expected := fmt.Sprintf(`{"chain_id":"%s",`+ `"tx":[17,{"inputs":[{"address":"%s",`+ `"amount":12345,"sequence":67890},{"address":"%s",`+ - `"amount":111,"sequence":222}],"pub_key":[1,"%X"],`+ + `"amount":111,"sequence":222}],"pub_key":{"CurveType":1,"PublicKey":"%X"},`+ `"unbond_to":[{"address":"%s",`+ `"amount":333},{"address":"%s",`+ `"amount":444}]}]}`, @@ -152,7 +153,7 @@ func TestBondTxSignable(t *testing.T) { bondTx.UnbondTo[0].Address.String(), bondTx.UnbondTo[1].Address.String()) - assert.Equal(t, expected, string(acm.SignBytes(chainID, bondTx)), "Unexpected sign string for BondTx") + assert.Equal(t, expected, string(crypto.SignBytes(chainID, bondTx)), "Unexpected sign string for BondTx") } func TestUnbondTxSignable(t *testing.T) { @@ -160,7 +161,7 @@ func TestUnbondTxSignable(t *testing.T) { Address: makeAddress("address1"), Height: 111, } - signBytes := acm.SignBytes(chainID, unbondTx) + signBytes := crypto.SignBytes(chainID, unbondTx) signStr := string(signBytes) expected := fmt.Sprintf(`{"chain_id":"%s","tx":[18,{"address":"%s","height":111}]}`, chainID, unbondTx.Address.String()) @@ -174,7 +175,7 @@ func TestRebondTxSignable(t *testing.T) { Address: makeAddress("address1"), Height: 111, } - signBytes := acm.SignBytes(chainID, rebondTx) + signBytes := crypto.SignBytes(chainID, rebondTx) signStr := string(signBytes) expected := fmt.Sprintf(`{"chain_id":"%s","tx":[19,{"address":"%s","height":111}]}`, chainID, rebondTx.Address.String()) @@ -193,7 +194,7 @@ func TestPermissionsTxSignable(t *testing.T) { PermArgs: snatives.SetBaseArgs(makeAddress("address1"), 1, true), } - signBytes := acm.SignBytes(chainID, permsTx) + signBytes := crypto.SignBytes(chainID, permsTx) signStr := string(signBytes) expected := fmt.Sprintf(`{"chain_id":"%s","tx":[31,{"args":"{"PermFlag":%v,"Address":"%s","Permission":1,"Value":true}","input":{"address":"%s","amount":12345,"sequence":250}}]}`, chainID, ptypes.SetBase, permsTx.PermArgs.Address.String(), permsTx.Input.Address.String()) @@ -219,10 +220,10 @@ func TestTxWrapper_MarshalJSON(t *testing.T) { } func TestNewPermissionsTxWithSequence(t *testing.T) { - privateKey := acm.PrivateKeyFromSecret("Shhh...") + privateKey := crypto.PrivateKeyFromSecret("Shhh...", crypto.CurveTypeEd25519) - args := snatives.SetBaseArgs(privateKey.PublicKey().Address(), ptypes.HasRole, true) - permTx := NewPermissionsTxWithSequence(privateKey.PublicKey(), args, 1) + args := snatives.SetBaseArgs(privateKey.GetPublicKey().Address(), ptypes.HasRole, true) + permTx := NewPermissionsTxWithSequence(privateKey.GetPublicKey(), args, 1) testTxMarshalJSON(t, permTx) } diff --git a/txs/unbond_tx.go b/txs/unbond_tx.go index 786530295ff2596aea475ea8b534953fa53d0986..850de4f5266c15d5fc4a318f45092587d013ff3a 100644 --- a/txs/unbond_tx.go +++ b/txs/unbond_tx.go @@ -5,19 +5,20 @@ import ( "io" acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/crypto" "github.com/tendermint/go-wire" ) type UnbondTx struct { - Address acm.Address + Address crypto.Address Height int - Signature acm.Signature + Signature crypto.Signature txHashMemoizer } var _ Tx = &UnbondTx{} -func NewUnbondTx(addr acm.Address, height int) *UnbondTx { +func NewUnbondTx(addr crypto.Address, height int) *UnbondTx { return &UnbondTx{ Address: addr, Height: height, @@ -30,7 +31,7 @@ func (tx *UnbondTx) Sign(chainID string, signingAccounts ...acm.AddressableSigne len(signingAccounts)) } var err error - tx.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx) + tx.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx) if err != nil { return fmt.Errorf("could not sign %v: %v", tx, err) } diff --git a/vendor/github.com/howeyc/gopass/LICENSE.txt b/vendor/github.com/howeyc/gopass/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..14f74708a4a288be1f5d13c72ac7604abffd1e77 --- /dev/null +++ b/vendor/github.com/howeyc/gopass/LICENSE.txt @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2012 Chris Howey + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/howeyc/gopass/pass.go b/vendor/github.com/howeyc/gopass/pass.go new file mode 100644 index 0000000000000000000000000000000000000000..f5bd5a51a8c6888d7a2ac37946ed036f35dc7088 --- /dev/null +++ b/vendor/github.com/howeyc/gopass/pass.go @@ -0,0 +1,110 @@ +package gopass + +import ( + "errors" + "fmt" + "io" + "os" +) + +type FdReader interface { + io.Reader + Fd() uintptr +} + +var defaultGetCh = func(r io.Reader) (byte, error) { + buf := make([]byte, 1) + if n, err := r.Read(buf); n == 0 || err != nil { + if err != nil { + return 0, err + } + return 0, io.EOF + } + return buf[0], nil +} + +var ( + maxLength = 512 + ErrInterrupted = errors.New("interrupted") + ErrMaxLengthExceeded = fmt.Errorf("maximum byte limit (%v) exceeded", maxLength) + + // Provide variable so that tests can provide a mock implementation. + getch = defaultGetCh +) + +// getPasswd returns the input read from terminal. +// If prompt is not empty, it will be output as a prompt to the user +// If masked is true, typing will be matched by asterisks on the screen. +// Otherwise, typing will echo nothing. +func getPasswd(prompt string, masked bool, r FdReader, w io.Writer) ([]byte, error) { + var err error + var pass, bs, mask []byte + if masked { + bs = []byte("\b \b") + mask = []byte("*") + } + + if isTerminal(r.Fd()) { + if oldState, err := makeRaw(r.Fd()); err != nil { + return pass, err + } else { + defer func() { + restore(r.Fd(), oldState) + fmt.Fprintln(w) + }() + } + } + + if prompt != "" { + fmt.Fprint(w, prompt) + } + + // Track total bytes read, not just bytes in the password. This ensures any + // errors that might flood the console with nil or -1 bytes infinitely are + // capped. + var counter int + for counter = 0; counter <= maxLength; counter++ { + if v, e := getch(r); e != nil { + err = e + break + } else if v == 127 || v == 8 { + if l := len(pass); l > 0 { + pass = pass[:l-1] + fmt.Fprint(w, string(bs)) + } + } else if v == 13 || v == 10 { + break + } else if v == 3 { + err = ErrInterrupted + break + } else if v != 0 { + pass = append(pass, v) + fmt.Fprint(w, string(mask)) + } + } + + if counter > maxLength { + err = ErrMaxLengthExceeded + } + + return pass, err +} + +// GetPasswd returns the password read from the terminal without echoing input. +// The returned byte array does not include end-of-line characters. +func GetPasswd() ([]byte, error) { + return getPasswd("", false, os.Stdin, os.Stdout) +} + +// GetPasswdMasked returns the password read from the terminal, echoing asterisks. +// The returned byte array does not include end-of-line characters. +func GetPasswdMasked() ([]byte, error) { + return getPasswd("", true, os.Stdin, os.Stdout) +} + +// GetPasswdPrompt prompts the user and returns the password read from the terminal. +// If mask is true, then asterisks are echoed. +// The returned byte array does not include end-of-line characters. +func GetPasswdPrompt(prompt string, mask bool, r FdReader, w io.Writer) ([]byte, error) { + return getPasswd(prompt, mask, r, w) +} diff --git a/vendor/github.com/howeyc/gopass/terminal.go b/vendor/github.com/howeyc/gopass/terminal.go new file mode 100644 index 0000000000000000000000000000000000000000..083564146238fce92ac639cb0170edd023218748 --- /dev/null +++ b/vendor/github.com/howeyc/gopass/terminal.go @@ -0,0 +1,25 @@ +// +build !solaris + +package gopass + +import "golang.org/x/crypto/ssh/terminal" + +type terminalState struct { + state *terminal.State +} + +func isTerminal(fd uintptr) bool { + return terminal.IsTerminal(int(fd)) +} + +func makeRaw(fd uintptr) (*terminalState, error) { + state, err := terminal.MakeRaw(int(fd)) + + return &terminalState{ + state: state, + }, err +} + +func restore(fd uintptr, oldState *terminalState) error { + return terminal.Restore(int(fd), oldState.state) +} diff --git a/vendor/github.com/howeyc/gopass/terminal_solaris.go b/vendor/github.com/howeyc/gopass/terminal_solaris.go new file mode 100644 index 0000000000000000000000000000000000000000..257e1b4e81ea5bd163566588849f5533082fc0c3 --- /dev/null +++ b/vendor/github.com/howeyc/gopass/terminal_solaris.go @@ -0,0 +1,69 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +// Below is derived from Solaris source, so CDDL license is included. + +package gopass + +import ( + "syscall" + + "golang.org/x/sys/unix" +) + +type terminalState struct { + state *unix.Termios +} + +// isTerminal returns true if there is a terminal attached to the given +// file descriptor. +// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c +func isTerminal(fd uintptr) bool { + var termio unix.Termio + err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) + return err == nil +} + +// makeRaw puts the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c +func makeRaw(fd uintptr) (*terminalState, error) { + oldTermiosPtr, err := unix.IoctlGetTermios(int(fd), unix.TCGETS) + if err != nil { + return nil, err + } + oldTermios := *oldTermiosPtr + + newTermios := oldTermios + newTermios.Lflag &^= syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL + if err := unix.IoctlSetTermios(int(fd), unix.TCSETS, &newTermios); err != nil { + return nil, err + } + + return &terminalState{ + state: oldTermiosPtr, + }, nil +} + +func restore(fd uintptr, oldState *terminalState) error { + return unix.IoctlSetTermios(int(fd), unix.TCSETS, oldState.state) +} diff --git a/vendor/github.com/wayn3h0/go-uuid/LICENSE b/vendor/github.com/wayn3h0/go-uuid/LICENSE deleted file mode 100644 index fad0aa6350da088c679b81e73dee76ef873491da..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2015 Wayne Ho. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/github.com/wayn3h0/go-uuid/domain.go b/vendor/github.com/wayn3h0/go-uuid/domain.go deleted file mode 100644 index ce09399bcae3b33d13fd12648d20594b9952530a..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/domain.go +++ /dev/null @@ -1,14 +0,0 @@ -package uuid - -import ( - "github.com/wayn3h0/go-uuid/internal/dcesecurity" -) - -// Domain represents the identifier for a local domain -type Domain byte - -// Domains. -const ( - DomainUser = Domain(dcesecurity.User) // POSIX UID domain - DomainGroup = Domain(dcesecurity.Group) // POSIX GID domain -) diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/dcesecurity.go b/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/dcesecurity.go deleted file mode 100644 index 9de07243d9483e479daa7cf6be52b36496d90cf7..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/dcesecurity.go +++ /dev/null @@ -1,37 +0,0 @@ -package dcesecurity - -import ( - "encoding/binary" - "errors" - "os" - - "github.com/wayn3h0/go-uuid/internal/layout" - "github.com/wayn3h0/go-uuid/internal/timebased" - "github.com/wayn3h0/go-uuid/internal/version" -) - -// Generate returns a new DCE security uuid. -func New(domain Domain) ([]byte, error) { - uuid, err := timebased.New() - if err != nil { - return nil, err - } - - switch domain { - case User: - uid := os.Getuid() - binary.BigEndian.PutUint32(uuid[0:], uint32(uid)) // network byte order - case Group: - gid := os.Getgid() - binary.BigEndian.PutUint32(uuid[0:], uint32(gid)) // network byte order - default: - return nil, errors.New("uuid: domain is invalid") - } - - // set version(v2) - version.Set(uuid, version.DCESecurity) - // set layout(RFC4122) - layout.Set(uuid, layout.RFC4122) - - return uuid, nil -} diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/domain.go b/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/domain.go deleted file mode 100644 index 38eae8301fdb4a49fe10e50b74ef64a666919a51..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/domain.go +++ /dev/null @@ -1,9 +0,0 @@ -package dcesecurity - -// Domain represents the identifier for a local domain -type Domain byte - -const ( - User Domain = iota + 1 // POSIX UID domain - Group // POSIX GID domain -) diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/layout/layout.go b/vendor/github.com/wayn3h0/go-uuid/internal/layout/layout.go deleted file mode 100644 index 65a84cc463e4e429bbcea37024c1cffc56859daa..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/layout/layout.go +++ /dev/null @@ -1,12 +0,0 @@ -package layout - -// Layout represents the layout of UUID. See page 5 in RFC 4122. -type Layout byte - -const ( - Invalid Layout = iota // Invalid - NCS // Reserved, NCS backward compatibility. (Values: 0x00-0x07) - RFC4122 // The variant specified in RFC 4122. (Values: 0x08-0x0b) - Microsoft // Reserved, Microsoft Corporation backward compatibility. (Values: 0x0c-0x0d) - Future // Reserved for future definition. (Values: 0x0e-0x0f) -) diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/layout/utility.go b/vendor/github.com/wayn3h0/go-uuid/internal/layout/utility.go deleted file mode 100644 index 7c5fde7beb4acd4386126cbbe93e5cf8040e8b67..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/layout/utility.go +++ /dev/null @@ -1,33 +0,0 @@ -package layout - -// Set sets the layout for uuid. -func Set(uuid []byte, layout Layout) { - switch layout { - case NCS: - uuid[8] = (uuid[8] | 0x00) & 0x0f // Msb0=0 - case RFC4122: - uuid[8] = (uuid[8] | 0x80) & 0x8f // Msb0=1, Msb1=0 - case Microsoft: - uuid[8] = (uuid[8] | 0xc0) & 0xcf // Msb0=1, Msb1=1, Msb2=0 - case Future: - uuid[8] = (uuid[8] | 0xe0) & 0xef // Msb0=1, Msb1=1, Msb2=1 - default: - panic("uuid: layout is invalid") - } -} - -// Get returns layout of uuid. -func Get(uuid []byte) Layout { - switch { - case (uuid[8] & 0x80) == 0x00: - return NCS - case (uuid[8] & 0xc0) == 0x80: - return RFC4122 - case (uuid[8] & 0xe0) == 0xc0: - return Microsoft - case (uuid[8] & 0xe0) == 0xe0: - return Future - } - - return Invalid -} diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/md5/md5.go b/vendor/github.com/wayn3h0/go-uuid/internal/namebased/md5/md5.go deleted file mode 100644 index a03e6c71d68cd9f10cbe6591af938122ed803e71..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/md5/md5.go +++ /dev/null @@ -1,33 +0,0 @@ -package md5 - -import ( - "crypto/md5" - - "github.com/wayn3h0/go-uuid/internal/layout" - "github.com/wayn3h0/go-uuid/internal/version" -) - -// New returns a new name-based uses SHA-1 hashing uuid. -func New(namespace, name string) ([]byte, error) { - hash := md5.New() - _, err := hash.Write([]byte(namespace)) - if err != nil { - return nil, err - } - _, err = hash.Write([]byte(name)) - if err != nil { - return nil, err - } - - sum := hash.Sum(nil) - - uuid := make([]byte, 16) - copy(uuid, sum) - - // set version(v3) - version.Set(uuid, version.NameBasedMD5) - // set layout(RFC4122) - layout.Set(uuid, layout.RFC4122) - - return uuid, nil -} diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/namebased.go b/vendor/github.com/wayn3h0/go-uuid/internal/namebased/namebased.go deleted file mode 100644 index f4202676ad56349cf0dee76ef3adae53805f2b66..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/namebased.go +++ /dev/null @@ -1,9 +0,0 @@ -package namebased - -// Standard Namespaces -const ( - NamespaceDNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8" - NamespaceURL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8" - NamespaceOID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8" - NamespaceX500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8" -) diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/sha1/sha1.go b/vendor/github.com/wayn3h0/go-uuid/internal/namebased/sha1/sha1.go deleted file mode 100644 index 14a8eeb01c607720d0b2acfb230f3dc431e2d629..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/sha1/sha1.go +++ /dev/null @@ -1,33 +0,0 @@ -package sha1 - -import ( - "crypto/sha1" - - "github.com/wayn3h0/go-uuid/internal/layout" - "github.com/wayn3h0/go-uuid/internal/version" -) - -// New returns a new name-based uses SHA-1 hashing uuid. -func New(namespace, name string) ([]byte, error) { - hash := sha1.New() - _, err := hash.Write([]byte(namespace)) - if err != nil { - return nil, err - } - _, err = hash.Write([]byte(name)) - if err != nil { - return nil, err - } - - sum := hash.Sum(nil) - - uuid := make([]byte, 16) - copy(uuid, sum) - - // set version(v5) - version.Set(uuid, version.NameBasedSHA1) - // set layout(RFC4122) - layout.Set(uuid, layout.RFC4122) - - return uuid, nil -} diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/random/random.go b/vendor/github.com/wayn3h0/go-uuid/internal/random/random.go deleted file mode 100644 index 59354280800f18125241c15b9e941198ff2cc0e8..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/random/random.go +++ /dev/null @@ -1,27 +0,0 @@ -package random - -import ( - "crypto/rand" - - "github.com/wayn3h0/go-uuid/internal/layout" - "github.com/wayn3h0/go-uuid/internal/version" -) - -// New returns a new randomly uuid. -func New() ([]byte, error) { - uuid := make([]byte, 16) - n, err := rand.Read(uuid[:]) - if err != nil { - return nil, err - } - if n != len(uuid) { - return nil, err - } - - // set version(v4) - version.Set(uuid, version.Random) - // set layout(RFC4122) - layout.Set(uuid, layout.RFC4122) - - return uuid, nil -} diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/timebased/timebased.go b/vendor/github.com/wayn3h0/go-uuid/internal/timebased/timebased.go deleted file mode 100644 index 43541567cf1eaf24fdc4df388608f316e51da635..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/timebased/timebased.go +++ /dev/null @@ -1,92 +0,0 @@ -package timebased - -import ( - "crypto/rand" - "encoding/binary" - "net" - "sync" - "time" - - "github.com/wayn3h0/go-uuid/internal/layout" - "github.com/wayn3h0/go-uuid/internal/version" -) - -const ( - // Intervals bewteen 1/1/1970 and 15/10/1582 (Julain days of 1 Jan 1970 - Julain days of 15 Oct 1582) * 100-Nanoseconds Per Day - intervals = (2440587 - 2299160) * 86400 * 10000000 -) - -var ( - lastGenerated time.Time // last generated time - clockSequence uint16 // clock sequence for same tick - nodeID []byte // node id (MAC Address) - locker sync.Mutex // global lock -) - -// New returns a new time-based uuid. -func New() ([]byte, error) { - // Get and release a global lock - locker.Lock() - defer locker.Unlock() - - uuid := make([]byte, 16) - - // get timestamp - now := time.Now().UTC() - timestamp := uint64(now.UnixNano()/100) + intervals // get timestamp - if !now.After(lastGenerated) { - clockSequence++ // last generated time known, then just increment clock sequence - } else { - b := make([]byte, 2) - _, err := rand.Read(b) - if err != nil { - return nil, err - } - clockSequence = uint16(int(b[0])<<8 | int(b[1])) // set to a random value (network byte order) - } - - lastGenerated = now // remember the last generated time - - timeLow := uint32(timestamp & 0xffffffff) - timeMiddle := uint16((timestamp >> 32) & 0xffff) - timeHigh := uint16((timestamp >> 48) & 0xfff) - - // network byte order(BigEndian) - binary.BigEndian.PutUint32(uuid[0:], timeLow) - binary.BigEndian.PutUint16(uuid[4:], timeMiddle) - binary.BigEndian.PutUint16(uuid[6:], timeHigh) - binary.BigEndian.PutUint16(uuid[8:], clockSequence) - - // get node id(mac address) - if nodeID == nil { - interfaces, err := net.Interfaces() - if err != nil { - return nil, err - } - - for _, i := range interfaces { - if len(i.HardwareAddr) >= 6 { - nodeID = make([]byte, 6) - copy(nodeID, i.HardwareAddr) - break - } - } - - if nodeID == nil { - nodeID = make([]byte, 6) - _, err := rand.Read(nodeID) - if err != nil { - return nil, err - } - } - } - - copy(uuid[10:], nodeID) - - // set version(v1) - version.Set(uuid, version.TimeBased) - // set layout(RFC4122) - layout.Set(uuid, layout.RFC4122) - - return uuid, nil -} diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/version/utility.go b/vendor/github.com/wayn3h0/go-uuid/internal/version/utility.go deleted file mode 100644 index 2862711a022e9f06fa763ea6546700e7765f2aed..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/version/utility.go +++ /dev/null @@ -1,29 +0,0 @@ -package version - -// Set sets the version for uuid. -func Set(uuid []byte, version Version) { - switch version { - case TimeBased: - uuid[6] = (uuid[6] | 0x10) & 0x1f - case DCESecurity: - uuid[6] = (uuid[6] | 0x20) & 0x2f - case NameBasedMD5: - uuid[6] = (uuid[6] | 0x30) & 0x3f - case Random: - uuid[6] = (uuid[6] | 0x40) & 0x4f - case NameBasedSHA1: - uuid[6] = (uuid[6] | 0x50) & 0x5f - default: - panic("uuid: version is unknown") - } -} - -// Get gets the version of uuid. -func Get(uuid []byte) Version { - version := uuid[6] >> 4 - if version > 0 && version < 6 { - return Version(version) - } - - return Unknown -} diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/version/version.go b/vendor/github.com/wayn3h0/go-uuid/internal/version/version.go deleted file mode 100644 index 10ab52cfa15cde59be546f2c21dc49e24b79103c..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/internal/version/version.go +++ /dev/null @@ -1,14 +0,0 @@ -package version - -// Version represents the version of UUID. See page 7 in RFC 4122. -type Version byte - -// Version List -const ( - Unknown Version = iota // Unknwon - TimeBased // V1: The time-based version - DCESecurity // V2: The DCE security version, with embedded POSIX UIDs - NameBasedMD5 // V3: The name-based version that uses MD5 hashing - Random // V4: The randomly or pseudo-randomly generated version - NameBasedSHA1 // V5: The name-based version that uses SHA-1 hashing -) diff --git a/vendor/github.com/wayn3h0/go-uuid/layout.go b/vendor/github.com/wayn3h0/go-uuid/layout.go deleted file mode 100644 index 7656df5d163e6e15a85aeaef1d7ec9605d3885f0..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/layout.go +++ /dev/null @@ -1,33 +0,0 @@ -package uuid - -import ( - "github.com/wayn3h0/go-uuid/internal/layout" -) - -// Layout represents the layout of UUID. See page 5 in RFC 4122. -type Layout byte - -// Layouts. -const ( - LayoutInvalid = Layout(layout.Invalid) // Invalid - LayoutNCS = Layout(layout.NCS) // Reserved, NCS backward compatibility. (Values: 0x00-0x07) - LayoutRFC4122 = Layout(layout.RFC4122) // The variant specified in RFC 4122. (Values: 0x08-0x0b) - LayoutMicrosoft = Layout(layout.Microsoft) // Reserved, Microsoft Corporation backward compatibility. (Values: 0x0c-0x0d) - LayoutFuture = Layout(layout.Future) // Reserved for future definition. (Values: 0x0e-0x0f) -) - -// String returns English description of layout. -func (this Layout) String() string { - switch this { - case LayoutNCS: - return "Layout: Reserved For NCS" - case LayoutRFC4122: - return "Layout: RFC 4122" - case LayoutMicrosoft: - return "Layout: Reserved For Microsoft" - case LayoutFuture: - return "Layout: Reserved For Future" - default: - return "Layout: Invalid" - } -} diff --git a/vendor/github.com/wayn3h0/go-uuid/namespace.go b/vendor/github.com/wayn3h0/go-uuid/namespace.go deleted file mode 100644 index 23b314a56f84c63c6c9788a226d261d5b5545316..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/namespace.go +++ /dev/null @@ -1,13 +0,0 @@ -package uuid - -import ( - "github.com/wayn3h0/go-uuid/internal/namebased" -) - -// Imports namespaces. -const ( - NamespaceDNS = namebased.NamespaceDNS // "6ba7b810-9dad-11d1-80b4-00c04fd430c8" - NamespaceURL = namebased.NamespaceURL // "6ba7b811-9dad-11d1-80b4-00c04fd430c8" - NamespaceOID = namebased.NamespaceOID // "6ba7b812-9dad-11d1-80b4-00c04fd430c8" - NamespaceX500 = namebased.NamespaceX500 // "6ba7b814-9dad-11d1-80b4-00c04fd430c8" -) diff --git a/vendor/github.com/wayn3h0/go-uuid/parse.go b/vendor/github.com/wayn3h0/go-uuid/parse.go deleted file mode 100644 index 0847299c3cede87a69dea74f44860003d34b2722..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/parse.go +++ /dev/null @@ -1,47 +0,0 @@ -package uuid - -import ( - "encoding/hex" - "errors" - "fmt" -) - -// Parse parses the UUID string. -func Parse(str string) (UUID, error) { - length := len(str) - buffer := make([]byte, 16) - charIndexes := []int{} - switch length { - case 36: - if str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-' { - return Nil, fmt.Errorf("uuid: format of UUID string \"%s\" is invalid, it should be xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)", str) - } - charIndexes = []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} - case 32: - charIndexes = []int{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30} - default: - return Nil, fmt.Errorf("uuid: length of UUID string \"%s\" is invalid, it should be 36 (standard) or 32 (without dash)", str) - } - for i, v := range charIndexes { - if c, e := hex.DecodeString(str[v : v+2]); e != nil { - return Nil, fmt.Errorf("uuid: UUID string \"%s\" is invalid: %s", str, e.Error()) - } else { - buffer[i] = c[0] - } - } - - uuid := UUID{} - copy(uuid[:], buffer) - - if !uuid.Equal(Nil) { - if uuid.Layout() == LayoutInvalid { - return Nil, errors.New("uuid: layout is invalid") - } - - if uuid.Version() == VersionUnknown { - return Nil, errors.New("uuid: version is unknown") - } - } - - return uuid, nil -} diff --git a/vendor/github.com/wayn3h0/go-uuid/style.go b/vendor/github.com/wayn3h0/go-uuid/style.go deleted file mode 100644 index 17b816a75c1d1b9ce8c7142b15a7fbbc527d6597..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/style.go +++ /dev/null @@ -1,22 +0,0 @@ -package uuid - -// Style represents the style of UUID string. -type Style byte - -// Styles. -const ( - StyleStandard Style = iota + 1 // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12, length: 36) - StyleWithoutDash // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (length: 32) -) - -// String returns English description of style. -func (this Style) String() string { - switch this { - case StyleStandard: - return "Style: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)" - case StyleWithoutDash: - return "Style: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - default: - return "Style: Unknown" - } -} diff --git a/vendor/github.com/wayn3h0/go-uuid/uuid.go b/vendor/github.com/wayn3h0/go-uuid/uuid.go deleted file mode 100644 index ea17ec284621868df10e5b288a28ccb1b7a8476b..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/uuid.go +++ /dev/null @@ -1,147 +0,0 @@ -package uuid - -import ( - "bytes" - "fmt" - - "github.com/wayn3h0/go-uuid/internal/dcesecurity" - "github.com/wayn3h0/go-uuid/internal/layout" - "github.com/wayn3h0/go-uuid/internal/namebased/md5" - "github.com/wayn3h0/go-uuid/internal/namebased/sha1" - "github.com/wayn3h0/go-uuid/internal/random" - "github.com/wayn3h0/go-uuid/internal/timebased" - "github.com/wayn3h0/go-uuid/internal/version" -) - -var ( - Nil = UUID{} // Nil UUID -) - -// NewTimeBased returns a new time based UUID (version 1). -func NewTimeBased() (UUID, error) { - u, err := timebased.New() - if err != nil { - return Nil, err - } - - uuid := UUID{} - copy(uuid[:], u) - - return uuid, nil -} - -// NewV1 same as NewTimeBased. -func NewV1() (UUID, error) { - return NewTimeBased() -} - -// NewDCESecurity returns a new DCE security UUID (version 2). -func NewDCESecurity(domain Domain) (UUID, error) { - u, err := dcesecurity.New(dcesecurity.Domain(domain)) - if err != nil { - return Nil, err - } - - uuid := UUID{} - copy(uuid[:], u) - - return uuid, nil -} - -// NewV2 same as NewDCESecurity. -func NewV2(domain Domain) (UUID, error) { - return NewDCESecurity(domain) -} - -// NewNameBasedMD5 returns a new name based UUID with MD5 hash (version 3). -func NewNameBasedMD5(namespace, name string) (UUID, error) { - u, err := md5.New(namespace, name) - if err != nil { - return Nil, err - } - - uuid := UUID{} - copy(uuid[:], u) - - return uuid, nil -} - -// NewV3 same as NewNameBasedMD5. -func NewV3(namespace, name string) (UUID, error) { - return NewNameBasedMD5(namespace, name) -} - -// NewRandom returns a new random UUID (version 4). -func NewRandom() (UUID, error) { - u, err := random.New() - if err != nil { - return Nil, err - } - - uuid := UUID{} - copy(uuid[:], u) - - return uuid, nil -} - -// NewV4 same as NewRandom. -func NewV4() (UUID, error) { - return NewRandom() -} - -// New same as NewRandom. -func New() (UUID, error) { - return NewRandom() -} - -// NewNameBasedSHA1 returns a new name based UUID with SHA1 hash (version 5). -func NewNameBasedSHA1(namespace, name string) (UUID, error) { - u, err := sha1.New(namespace, name) - if err != nil { - return Nil, err - } - - uuid := UUID{} - copy(uuid[:], u) - - return uuid, nil -} - -// NewV5 same as NewNameBasedSHA1. -func NewV5(namespace, name string) (UUID, error) { - return NewNameBasedSHA1(namespace, name) -} - -// UUID respresents an UUID type compliant with specification in RFC 4122. -type UUID [16]byte - -// Layout returns layout of UUID. -func (this UUID) Layout() Layout { - return Layout(layout.Get(this[:])) -} - -// Version returns version of UUID. -func (this UUID) Version() Version { - return Version(version.Get(this[:])) -} - -// Equal returns true if current uuid equal to passed uuid. -func (this UUID) Equal(another UUID) bool { - return bytes.EqualFold(this[:], another[:]) -} - -// Format returns the formatted string of UUID. -func (this UUID) Format(style Style) string { - switch style { - case StyleWithoutDash: - return fmt.Sprintf("%x", this[:]) - //case StyleStandard: - default: - return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", this[:4], this[4:6], this[6:8], this[8:10], this[10:]) - } -} - -// String returns the string of UUID with standard style(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | 8-4-4-4-12). -func (this UUID) String() string { - return this.Format(StyleStandard) -} diff --git a/vendor/github.com/wayn3h0/go-uuid/version.go b/vendor/github.com/wayn3h0/go-uuid/version.go deleted file mode 100644 index af509e3a3bb170dc45576c415d38f3c6f0444ffe..0000000000000000000000000000000000000000 --- a/vendor/github.com/wayn3h0/go-uuid/version.go +++ /dev/null @@ -1,45 +0,0 @@ -package uuid - -import ( - "github.com/wayn3h0/go-uuid/internal/version" -) - -// Version represents the version of UUID. See page 7 in RFC 4122. -type Version byte - -// Versions. -const ( - VersionUnknown = Version(version.Unknown) // Unknown - VersionTimeBased = Version(version.TimeBased) // V1: The time-based version - VersionDCESecurity = Version(version.DCESecurity) // V2: The DCE security version, with embedded POSIX UIDs - VersionNameBasedMD5 = Version(version.NameBasedMD5) // V3: The name-based version that uses MD5 hashing - VersionRandom = Version(version.Random) // V4: The randomly or pseudo-randomly generated version - VersionNameBasedSHA1 = Version(version.NameBasedSHA1) // V5: The name-based version that uses SHA-1 hashing -) - -// Short names. -const ( - V1 = VersionTimeBased - V2 = VersionDCESecurity - V3 = VersionNameBasedMD5 - V4 = VersionRandom - V5 = VersionNameBasedSHA1 -) - -// String returns English description of version. -func (this Version) String() string { - switch this { - case VersionTimeBased: - return "Version 1: Time-Based" - case VersionDCESecurity: - return "Version 2: DCE Security With Embedded POSIX UIDs" - case VersionNameBasedMD5: - return "Version 3: Name-Based (MD5)" - case VersionRandom: - return "Version 4: Randomly OR Pseudo-Randomly Generated" - case VersionNameBasedSHA1: - return "Version 5: Name-Based (SHA-1)" - default: - return "Version: Unknown" - } -} diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go new file mode 100644 index 0000000000000000000000000000000000000000..593f6530084f246495fc42f2ce6d59a2bccb4c17 --- /dev/null +++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go @@ -0,0 +1,77 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC +2898 / PKCS #5 v2.0. + +A key derivation function is useful when encrypting data based on a password +or any other not-fully-random data. It uses a pseudorandom function to derive +a secure encryption key based on the password. + +While v2.0 of the standard defines only one pseudorandom function to use, +HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved +Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To +choose, you can pass the `New` functions from the different SHA packages to +pbkdf2.Key. +*/ +package pbkdf2 // import "golang.org/x/crypto/pbkdf2" + +import ( + "crypto/hmac" + "hash" +) + +// Key derives a key from the password, salt and iteration count, returning a +// []byte of length keylen that can be used as cryptographic key. The key is +// derived based on the method described as PBKDF2 with the HMAC variant using +// the supplied hash function. +// +// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you +// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by +// doing: +// +// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New) +// +// Remember to get a good random salt. At least 8 bytes is recommended by the +// RFC. +// +// Using a higher iteration count will increase the cost of an exhaustive +// search but will also make derivation proportionally slower. +func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { + prf := hmac.New(h, password) + hashLen := prf.Size() + numBlocks := (keyLen + hashLen - 1) / hashLen + + var buf [4]byte + dk := make([]byte, 0, numBlocks*hashLen) + U := make([]byte, hashLen) + for block := 1; block <= numBlocks; block++ { + // N.B.: || means concatenation, ^ means XOR + // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter + // U_1 = PRF(password, salt || uint(i)) + prf.Reset() + prf.Write(salt) + buf[0] = byte(block >> 24) + buf[1] = byte(block >> 16) + buf[2] = byte(block >> 8) + buf[3] = byte(block) + prf.Write(buf[:4]) + dk = prf.Sum(dk) + T := dk[len(dk)-hashLen:] + copy(U, T) + + // U_n = PRF(password, U_(n-1)) + for n := 2; n <= iter; n++ { + prf.Reset() + prf.Write(U) + U = U[:0] + U = prf.Sum(U) + for x := range U { + T[x] ^= U[x] + } + } + } + return dk[:keyLen] +} diff --git a/vendor/golang.org/x/crypto/scrypt/scrypt.go b/vendor/golang.org/x/crypto/scrypt/scrypt.go new file mode 100644 index 0000000000000000000000000000000000000000..ff28aaef6ff2f091efe8cdbae93da4c402908bd1 --- /dev/null +++ b/vendor/golang.org/x/crypto/scrypt/scrypt.go @@ -0,0 +1,244 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package scrypt implements the scrypt key derivation function as defined in +// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard +// Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf). +package scrypt // import "golang.org/x/crypto/scrypt" + +import ( + "crypto/sha256" + "errors" + + "golang.org/x/crypto/pbkdf2" +) + +const maxInt = int(^uint(0) >> 1) + +// blockCopy copies n numbers from src into dst. +func blockCopy(dst, src []uint32, n int) { + copy(dst, src[:n]) +} + +// blockXOR XORs numbers from dst with n numbers from src. +func blockXOR(dst, src []uint32, n int) { + for i, v := range src[:n] { + dst[i] ^= v + } +} + +// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in, +// and puts the result into both both tmp and out. +func salsaXOR(tmp *[16]uint32, in, out []uint32) { + w0 := tmp[0] ^ in[0] + w1 := tmp[1] ^ in[1] + w2 := tmp[2] ^ in[2] + w3 := tmp[3] ^ in[3] + w4 := tmp[4] ^ in[4] + w5 := tmp[5] ^ in[5] + w6 := tmp[6] ^ in[6] + w7 := tmp[7] ^ in[7] + w8 := tmp[8] ^ in[8] + w9 := tmp[9] ^ in[9] + w10 := tmp[10] ^ in[10] + w11 := tmp[11] ^ in[11] + w12 := tmp[12] ^ in[12] + w13 := tmp[13] ^ in[13] + w14 := tmp[14] ^ in[14] + w15 := tmp[15] ^ in[15] + + x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8 + x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15 + + for i := 0; i < 8; i += 2 { + u := x0 + x12 + x4 ^= u<<7 | u>>(32-7) + u = x4 + x0 + x8 ^= u<<9 | u>>(32-9) + u = x8 + x4 + x12 ^= u<<13 | u>>(32-13) + u = x12 + x8 + x0 ^= u<<18 | u>>(32-18) + + u = x5 + x1 + x9 ^= u<<7 | u>>(32-7) + u = x9 + x5 + x13 ^= u<<9 | u>>(32-9) + u = x13 + x9 + x1 ^= u<<13 | u>>(32-13) + u = x1 + x13 + x5 ^= u<<18 | u>>(32-18) + + u = x10 + x6 + x14 ^= u<<7 | u>>(32-7) + u = x14 + x10 + x2 ^= u<<9 | u>>(32-9) + u = x2 + x14 + x6 ^= u<<13 | u>>(32-13) + u = x6 + x2 + x10 ^= u<<18 | u>>(32-18) + + u = x15 + x11 + x3 ^= u<<7 | u>>(32-7) + u = x3 + x15 + x7 ^= u<<9 | u>>(32-9) + u = x7 + x3 + x11 ^= u<<13 | u>>(32-13) + u = x11 + x7 + x15 ^= u<<18 | u>>(32-18) + + u = x0 + x3 + x1 ^= u<<7 | u>>(32-7) + u = x1 + x0 + x2 ^= u<<9 | u>>(32-9) + u = x2 + x1 + x3 ^= u<<13 | u>>(32-13) + u = x3 + x2 + x0 ^= u<<18 | u>>(32-18) + + u = x5 + x4 + x6 ^= u<<7 | u>>(32-7) + u = x6 + x5 + x7 ^= u<<9 | u>>(32-9) + u = x7 + x6 + x4 ^= u<<13 | u>>(32-13) + u = x4 + x7 + x5 ^= u<<18 | u>>(32-18) + + u = x10 + x9 + x11 ^= u<<7 | u>>(32-7) + u = x11 + x10 + x8 ^= u<<9 | u>>(32-9) + u = x8 + x11 + x9 ^= u<<13 | u>>(32-13) + u = x9 + x8 + x10 ^= u<<18 | u>>(32-18) + + u = x15 + x14 + x12 ^= u<<7 | u>>(32-7) + u = x12 + x15 + x13 ^= u<<9 | u>>(32-9) + u = x13 + x12 + x14 ^= u<<13 | u>>(32-13) + u = x14 + x13 + x15 ^= u<<18 | u>>(32-18) + } + x0 += w0 + x1 += w1 + x2 += w2 + x3 += w3 + x4 += w4 + x5 += w5 + x6 += w6 + x7 += w7 + x8 += w8 + x9 += w9 + x10 += w10 + x11 += w11 + x12 += w12 + x13 += w13 + x14 += w14 + x15 += w15 + + out[0], tmp[0] = x0, x0 + out[1], tmp[1] = x1, x1 + out[2], tmp[2] = x2, x2 + out[3], tmp[3] = x3, x3 + out[4], tmp[4] = x4, x4 + out[5], tmp[5] = x5, x5 + out[6], tmp[6] = x6, x6 + out[7], tmp[7] = x7, x7 + out[8], tmp[8] = x8, x8 + out[9], tmp[9] = x9, x9 + out[10], tmp[10] = x10, x10 + out[11], tmp[11] = x11, x11 + out[12], tmp[12] = x12, x12 + out[13], tmp[13] = x13, x13 + out[14], tmp[14] = x14, x14 + out[15], tmp[15] = x15, x15 +} + +func blockMix(tmp *[16]uint32, in, out []uint32, r int) { + blockCopy(tmp[:], in[(2*r-1)*16:], 16) + for i := 0; i < 2*r; i += 2 { + salsaXOR(tmp, in[i*16:], out[i*8:]) + salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:]) + } +} + +func integer(b []uint32, r int) uint64 { + j := (2*r - 1) * 16 + return uint64(b[j]) | uint64(b[j+1])<<32 +} + +func smix(b []byte, r, N int, v, xy []uint32) { + var tmp [16]uint32 + x := xy + y := xy[32*r:] + + j := 0 + for i := 0; i < 32*r; i++ { + x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24 + j += 4 + } + for i := 0; i < N; i += 2 { + blockCopy(v[i*(32*r):], x, 32*r) + blockMix(&tmp, x, y, r) + + blockCopy(v[(i+1)*(32*r):], y, 32*r) + blockMix(&tmp, y, x, r) + } + for i := 0; i < N; i += 2 { + j := int(integer(x, r) & uint64(N-1)) + blockXOR(x, v[j*(32*r):], 32*r) + blockMix(&tmp, x, y, r) + + j = int(integer(y, r) & uint64(N-1)) + blockXOR(y, v[j*(32*r):], 32*r) + blockMix(&tmp, y, x, r) + } + j = 0 + for _, v := range x[:32*r] { + b[j+0] = byte(v >> 0) + b[j+1] = byte(v >> 8) + b[j+2] = byte(v >> 16) + b[j+3] = byte(v >> 24) + j += 4 + } +} + +// Key derives a key from the password, salt, and cost parameters, returning +// a byte slice of length keyLen that can be used as cryptographic key. +// +// N is a CPU/memory cost parameter, which must be a power of two greater than 1. +// r and p must satisfy r * p < 2³â°. If the parameters do not satisfy the +// limits, the function returns a nil byte slice and an error. +// +// For example, you can get a derived key for e.g. AES-256 (which needs a +// 32-byte key) by doing: +// +// dk, err := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32) +// +// The recommended parameters for interactive logins as of 2017 are N=32768, r=8 +// and p=1. The parameters N, r, and p should be increased as memory latency and +// CPU parallelism increases; consider setting N to the highest power of 2 you +// can derive within 100 milliseconds. Remember to get a good random salt. +func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) { + if N <= 1 || N&(N-1) != 0 { + return nil, errors.New("scrypt: N must be > 1 and a power of 2") + } + if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r { + return nil, errors.New("scrypt: parameters are too large") + } + + xy := make([]uint32, 64*r) + v := make([]uint32, 32*N*r) + b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New) + + for i := 0; i < p; i++ { + smix(b[i*128*r:], r, N, v, xy) + } + + return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go new file mode 100644 index 0000000000000000000000000000000000000000..9a887598ff40437dae4a6a85dd8502e428917450 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go @@ -0,0 +1,951 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package terminal + +import ( + "bytes" + "io" + "sync" + "unicode/utf8" +) + +// EscapeCodes contains escape sequences that can be written to the terminal in +// order to achieve different styles of text. +type EscapeCodes struct { + // Foreground colors + Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte + + // Reset all attributes + Reset []byte +} + +var vt100EscapeCodes = EscapeCodes{ + Black: []byte{keyEscape, '[', '3', '0', 'm'}, + Red: []byte{keyEscape, '[', '3', '1', 'm'}, + Green: []byte{keyEscape, '[', '3', '2', 'm'}, + Yellow: []byte{keyEscape, '[', '3', '3', 'm'}, + Blue: []byte{keyEscape, '[', '3', '4', 'm'}, + Magenta: []byte{keyEscape, '[', '3', '5', 'm'}, + Cyan: []byte{keyEscape, '[', '3', '6', 'm'}, + White: []byte{keyEscape, '[', '3', '7', 'm'}, + + Reset: []byte{keyEscape, '[', '0', 'm'}, +} + +// Terminal contains the state for running a VT100 terminal that is capable of +// reading lines of input. +type Terminal struct { + // AutoCompleteCallback, if non-null, is called for each keypress with + // the full input line and the current position of the cursor (in + // bytes, as an index into |line|). If it returns ok=false, the key + // press is processed normally. Otherwise it returns a replacement line + // and the new cursor position. + AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) + + // Escape contains a pointer to the escape codes for this terminal. + // It's always a valid pointer, although the escape codes themselves + // may be empty if the terminal doesn't support them. + Escape *EscapeCodes + + // lock protects the terminal and the state in this object from + // concurrent processing of a key press and a Write() call. + lock sync.Mutex + + c io.ReadWriter + prompt []rune + + // line is the current line being entered. + line []rune + // pos is the logical position of the cursor in line + pos int + // echo is true if local echo is enabled + echo bool + // pasteActive is true iff there is a bracketed paste operation in + // progress. + pasteActive bool + + // cursorX contains the current X value of the cursor where the left + // edge is 0. cursorY contains the row number where the first row of + // the current line is 0. + cursorX, cursorY int + // maxLine is the greatest value of cursorY so far. + maxLine int + + termWidth, termHeight int + + // outBuf contains the terminal data to be sent. + outBuf []byte + // remainder contains the remainder of any partial key sequences after + // a read. It aliases into inBuf. + remainder []byte + inBuf [256]byte + + // history contains previously entered commands so that they can be + // accessed with the up and down keys. + history stRingBuffer + // historyIndex stores the currently accessed history entry, where zero + // means the immediately previous entry. + historyIndex int + // When navigating up and down the history it's possible to return to + // the incomplete, initial line. That value is stored in + // historyPending. + historyPending string +} + +// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is +// a local terminal, that terminal must first have been put into raw mode. +// prompt is a string that is written at the start of each input line (i.e. +// "> "). +func NewTerminal(c io.ReadWriter, prompt string) *Terminal { + return &Terminal{ + Escape: &vt100EscapeCodes, + c: c, + prompt: []rune(prompt), + termWidth: 80, + termHeight: 24, + echo: true, + historyIndex: -1, + } +} + +const ( + keyCtrlD = 4 + keyCtrlU = 21 + keyEnter = '\r' + keyEscape = 27 + keyBackspace = 127 + keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota + keyUp + keyDown + keyLeft + keyRight + keyAltLeft + keyAltRight + keyHome + keyEnd + keyDeleteWord + keyDeleteLine + keyClearScreen + keyPasteStart + keyPasteEnd +) + +var ( + crlf = []byte{'\r', '\n'} + pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'} + pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'} +) + +// bytesToKey tries to parse a key sequence from b. If successful, it returns +// the key and the remainder of the input. Otherwise it returns utf8.RuneError. +func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { + if len(b) == 0 { + return utf8.RuneError, nil + } + + if !pasteActive { + switch b[0] { + case 1: // ^A + return keyHome, b[1:] + case 5: // ^E + return keyEnd, b[1:] + case 8: // ^H + return keyBackspace, b[1:] + case 11: // ^K + return keyDeleteLine, b[1:] + case 12: // ^L + return keyClearScreen, b[1:] + case 23: // ^W + return keyDeleteWord, b[1:] + } + } + + if b[0] != keyEscape { + if !utf8.FullRune(b) { + return utf8.RuneError, b + } + r, l := utf8.DecodeRune(b) + return r, b[l:] + } + + if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' { + switch b[2] { + case 'A': + return keyUp, b[3:] + case 'B': + return keyDown, b[3:] + case 'C': + return keyRight, b[3:] + case 'D': + return keyLeft, b[3:] + case 'H': + return keyHome, b[3:] + case 'F': + return keyEnd, b[3:] + } + } + + if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { + switch b[5] { + case 'C': + return keyAltRight, b[6:] + case 'D': + return keyAltLeft, b[6:] + } + } + + if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) { + return keyPasteStart, b[6:] + } + + if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) { + return keyPasteEnd, b[6:] + } + + // If we get here then we have a key that we don't recognise, or a + // partial sequence. It's not clear how one should find the end of a + // sequence without knowing them all, but it seems that [a-zA-Z~] only + // appears at the end of a sequence. + for i, c := range b[0:] { + if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' { + return keyUnknown, b[i+1:] + } + } + + return utf8.RuneError, b +} + +// queue appends data to the end of t.outBuf +func (t *Terminal) queue(data []rune) { + t.outBuf = append(t.outBuf, []byte(string(data))...) +} + +var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'} +var space = []rune{' '} + +func isPrintable(key rune) bool { + isInSurrogateArea := key >= 0xd800 && key <= 0xdbff + return key >= 32 && !isInSurrogateArea +} + +// moveCursorToPos appends data to t.outBuf which will move the cursor to the +// given, logical position in the text. +func (t *Terminal) moveCursorToPos(pos int) { + if !t.echo { + return + } + + x := visualLength(t.prompt) + pos + y := x / t.termWidth + x = x % t.termWidth + + up := 0 + if y < t.cursorY { + up = t.cursorY - y + } + + down := 0 + if y > t.cursorY { + down = y - t.cursorY + } + + left := 0 + if x < t.cursorX { + left = t.cursorX - x + } + + right := 0 + if x > t.cursorX { + right = x - t.cursorX + } + + t.cursorX = x + t.cursorY = y + t.move(up, down, left, right) +} + +func (t *Terminal) move(up, down, left, right int) { + movement := make([]rune, 3*(up+down+left+right)) + m := movement + for i := 0; i < up; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'A' + m = m[3:] + } + for i := 0; i < down; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'B' + m = m[3:] + } + for i := 0; i < left; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'D' + m = m[3:] + } + for i := 0; i < right; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'C' + m = m[3:] + } + + t.queue(movement) +} + +func (t *Terminal) clearLineToRight() { + op := []rune{keyEscape, '[', 'K'} + t.queue(op) +} + +const maxLineLength = 4096 + +func (t *Terminal) setLine(newLine []rune, newPos int) { + if t.echo { + t.moveCursorToPos(0) + t.writeLine(newLine) + for i := len(newLine); i < len(t.line); i++ { + t.writeLine(space) + } + t.moveCursorToPos(newPos) + } + t.line = newLine + t.pos = newPos +} + +func (t *Terminal) advanceCursor(places int) { + t.cursorX += places + t.cursorY += t.cursorX / t.termWidth + if t.cursorY > t.maxLine { + t.maxLine = t.cursorY + } + t.cursorX = t.cursorX % t.termWidth + + if places > 0 && t.cursorX == 0 { + // Normally terminals will advance the current position + // when writing a character. But that doesn't happen + // for the last character in a line. However, when + // writing a character (except a new line) that causes + // a line wrap, the position will be advanced two + // places. + // + // So, if we are stopping at the end of a line, we + // need to write a newline so that our cursor can be + // advanced to the next line. + t.outBuf = append(t.outBuf, '\r', '\n') + } +} + +func (t *Terminal) eraseNPreviousChars(n int) { + if n == 0 { + return + } + + if t.pos < n { + n = t.pos + } + t.pos -= n + t.moveCursorToPos(t.pos) + + copy(t.line[t.pos:], t.line[n+t.pos:]) + t.line = t.line[:len(t.line)-n] + if t.echo { + t.writeLine(t.line[t.pos:]) + for i := 0; i < n; i++ { + t.queue(space) + } + t.advanceCursor(n) + t.moveCursorToPos(t.pos) + } +} + +// countToLeftWord returns then number of characters from the cursor to the +// start of the previous word. +func (t *Terminal) countToLeftWord() int { + if t.pos == 0 { + return 0 + } + + pos := t.pos - 1 + for pos > 0 { + if t.line[pos] != ' ' { + break + } + pos-- + } + for pos > 0 { + if t.line[pos] == ' ' { + pos++ + break + } + pos-- + } + + return t.pos - pos +} + +// countToRightWord returns then number of characters from the cursor to the +// start of the next word. +func (t *Terminal) countToRightWord() int { + pos := t.pos + for pos < len(t.line) { + if t.line[pos] == ' ' { + break + } + pos++ + } + for pos < len(t.line) { + if t.line[pos] != ' ' { + break + } + pos++ + } + return pos - t.pos +} + +// visualLength returns the number of visible glyphs in s. +func visualLength(runes []rune) int { + inEscapeSeq := false + length := 0 + + for _, r := range runes { + switch { + case inEscapeSeq: + if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') { + inEscapeSeq = false + } + case r == '\x1b': + inEscapeSeq = true + default: + length++ + } + } + + return length +} + +// handleKey processes the given key and, optionally, returns a line of text +// that the user has entered. +func (t *Terminal) handleKey(key rune) (line string, ok bool) { + if t.pasteActive && key != keyEnter { + t.addKeyToLine(key) + return + } + + switch key { + case keyBackspace: + if t.pos == 0 { + return + } + t.eraseNPreviousChars(1) + case keyAltLeft: + // move left by a word. + t.pos -= t.countToLeftWord() + t.moveCursorToPos(t.pos) + case keyAltRight: + // move right by a word. + t.pos += t.countToRightWord() + t.moveCursorToPos(t.pos) + case keyLeft: + if t.pos == 0 { + return + } + t.pos-- + t.moveCursorToPos(t.pos) + case keyRight: + if t.pos == len(t.line) { + return + } + t.pos++ + t.moveCursorToPos(t.pos) + case keyHome: + if t.pos == 0 { + return + } + t.pos = 0 + t.moveCursorToPos(t.pos) + case keyEnd: + if t.pos == len(t.line) { + return + } + t.pos = len(t.line) + t.moveCursorToPos(t.pos) + case keyUp: + entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) + if !ok { + return "", false + } + if t.historyIndex == -1 { + t.historyPending = string(t.line) + } + t.historyIndex++ + runes := []rune(entry) + t.setLine(runes, len(runes)) + case keyDown: + switch t.historyIndex { + case -1: + return + case 0: + runes := []rune(t.historyPending) + t.setLine(runes, len(runes)) + t.historyIndex-- + default: + entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) + if ok { + t.historyIndex-- + runes := []rune(entry) + t.setLine(runes, len(runes)) + } + } + case keyEnter: + t.moveCursorToPos(len(t.line)) + t.queue([]rune("\r\n")) + line = string(t.line) + ok = true + t.line = t.line[:0] + t.pos = 0 + t.cursorX = 0 + t.cursorY = 0 + t.maxLine = 0 + case keyDeleteWord: + // Delete zero or more spaces and then one or more characters. + t.eraseNPreviousChars(t.countToLeftWord()) + case keyDeleteLine: + // Delete everything from the current cursor position to the + // end of line. + for i := t.pos; i < len(t.line); i++ { + t.queue(space) + t.advanceCursor(1) + } + t.line = t.line[:t.pos] + t.moveCursorToPos(t.pos) + case keyCtrlD: + // Erase the character under the current position. + // The EOF case when the line is empty is handled in + // readLine(). + if t.pos < len(t.line) { + t.pos++ + t.eraseNPreviousChars(1) + } + case keyCtrlU: + t.eraseNPreviousChars(t.pos) + case keyClearScreen: + // Erases the screen and moves the cursor to the home position. + t.queue([]rune("\x1b[2J\x1b[H")) + t.queue(t.prompt) + t.cursorX, t.cursorY = 0, 0 + t.advanceCursor(visualLength(t.prompt)) + t.setLine(t.line, t.pos) + default: + if t.AutoCompleteCallback != nil { + prefix := string(t.line[:t.pos]) + suffix := string(t.line[t.pos:]) + + t.lock.Unlock() + newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key) + t.lock.Lock() + + if completeOk { + t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos])) + return + } + } + if !isPrintable(key) { + return + } + if len(t.line) == maxLineLength { + return + } + t.addKeyToLine(key) + } + return +} + +// addKeyToLine inserts the given key at the current position in the current +// line. +func (t *Terminal) addKeyToLine(key rune) { + if len(t.line) == cap(t.line) { + newLine := make([]rune, len(t.line), 2*(1+len(t.line))) + copy(newLine, t.line) + t.line = newLine + } + t.line = t.line[:len(t.line)+1] + copy(t.line[t.pos+1:], t.line[t.pos:]) + t.line[t.pos] = key + if t.echo { + t.writeLine(t.line[t.pos:]) + } + t.pos++ + t.moveCursorToPos(t.pos) +} + +func (t *Terminal) writeLine(line []rune) { + for len(line) != 0 { + remainingOnLine := t.termWidth - t.cursorX + todo := len(line) + if todo > remainingOnLine { + todo = remainingOnLine + } + t.queue(line[:todo]) + t.advanceCursor(visualLength(line[:todo])) + line = line[todo:] + } +} + +// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n. +func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) { + for len(buf) > 0 { + i := bytes.IndexByte(buf, '\n') + todo := len(buf) + if i >= 0 { + todo = i + } + + var nn int + nn, err = w.Write(buf[:todo]) + n += nn + if err != nil { + return n, err + } + buf = buf[todo:] + + if i >= 0 { + if _, err = w.Write(crlf); err != nil { + return n, err + } + n++ + buf = buf[1:] + } + } + + return n, nil +} + +func (t *Terminal) Write(buf []byte) (n int, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + if t.cursorX == 0 && t.cursorY == 0 { + // This is the easy case: there's nothing on the screen that we + // have to move out of the way. + return writeWithCRLF(t.c, buf) + } + + // We have a prompt and possibly user input on the screen. We + // have to clear it first. + t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) + t.cursorX = 0 + t.clearLineToRight() + + for t.cursorY > 0 { + t.move(1 /* up */, 0, 0, 0) + t.cursorY-- + t.clearLineToRight() + } + + if _, err = t.c.Write(t.outBuf); err != nil { + return + } + t.outBuf = t.outBuf[:0] + + if n, err = writeWithCRLF(t.c, buf); err != nil { + return + } + + t.writeLine(t.prompt) + if t.echo { + t.writeLine(t.line) + } + + t.moveCursorToPos(t.pos) + + if _, err = t.c.Write(t.outBuf); err != nil { + return + } + t.outBuf = t.outBuf[:0] + return +} + +// ReadPassword temporarily changes the prompt and reads a password, without +// echo, from the terminal. +func (t *Terminal) ReadPassword(prompt string) (line string, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + oldPrompt := t.prompt + t.prompt = []rune(prompt) + t.echo = false + + line, err = t.readLine() + + t.prompt = oldPrompt + t.echo = true + + return +} + +// ReadLine returns a line of input from the terminal. +func (t *Terminal) ReadLine() (line string, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + return t.readLine() +} + +func (t *Terminal) readLine() (line string, err error) { + // t.lock must be held at this point + + if t.cursorX == 0 && t.cursorY == 0 { + t.writeLine(t.prompt) + t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + } + + lineIsPasted := t.pasteActive + + for { + rest := t.remainder + lineOk := false + for !lineOk { + var key rune + key, rest = bytesToKey(rest, t.pasteActive) + if key == utf8.RuneError { + break + } + if !t.pasteActive { + if key == keyCtrlD { + if len(t.line) == 0 { + return "", io.EOF + } + } + if key == keyPasteStart { + t.pasteActive = true + if len(t.line) == 0 { + lineIsPasted = true + } + continue + } + } else if key == keyPasteEnd { + t.pasteActive = false + continue + } + if !t.pasteActive { + lineIsPasted = false + } + line, lineOk = t.handleKey(key) + } + if len(rest) > 0 { + n := copy(t.inBuf[:], rest) + t.remainder = t.inBuf[:n] + } else { + t.remainder = nil + } + t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + if lineOk { + if t.echo { + t.historyIndex = -1 + t.history.Add(line) + } + if lineIsPasted { + err = ErrPasteIndicator + } + return + } + + // t.remainder is a slice at the beginning of t.inBuf + // containing a partial key sequence + readBuf := t.inBuf[len(t.remainder):] + var n int + + t.lock.Unlock() + n, err = t.c.Read(readBuf) + t.lock.Lock() + + if err != nil { + return + } + + t.remainder = t.inBuf[:n+len(t.remainder)] + } +} + +// SetPrompt sets the prompt to be used when reading subsequent lines. +func (t *Terminal) SetPrompt(prompt string) { + t.lock.Lock() + defer t.lock.Unlock() + + t.prompt = []rune(prompt) +} + +func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) { + // Move cursor to column zero at the start of the line. + t.move(t.cursorY, 0, t.cursorX, 0) + t.cursorX, t.cursorY = 0, 0 + t.clearLineToRight() + for t.cursorY < numPrevLines { + // Move down a line + t.move(0, 1, 0, 0) + t.cursorY++ + t.clearLineToRight() + } + // Move back to beginning. + t.move(t.cursorY, 0, 0, 0) + t.cursorX, t.cursorY = 0, 0 + + t.queue(t.prompt) + t.advanceCursor(visualLength(t.prompt)) + t.writeLine(t.line) + t.moveCursorToPos(t.pos) +} + +func (t *Terminal) SetSize(width, height int) error { + t.lock.Lock() + defer t.lock.Unlock() + + if width == 0 { + width = 1 + } + + oldWidth := t.termWidth + t.termWidth, t.termHeight = width, height + + switch { + case width == oldWidth: + // If the width didn't change then nothing else needs to be + // done. + return nil + case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0: + // If there is nothing on current line and no prompt printed, + // just do nothing + return nil + case width < oldWidth: + // Some terminals (e.g. xterm) will truncate lines that were + // too long when shinking. Others, (e.g. gnome-terminal) will + // attempt to wrap them. For the former, repainting t.maxLine + // works great, but that behaviour goes badly wrong in the case + // of the latter because they have doubled every full line. + + // We assume that we are working on a terminal that wraps lines + // and adjust the cursor position based on every previous line + // wrapping and turning into two. This causes the prompt on + // xterms to move upwards, which isn't great, but it avoids a + // huge mess with gnome-terminal. + if t.cursorX >= t.termWidth { + t.cursorX = t.termWidth - 1 + } + t.cursorY *= 2 + t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2) + case width > oldWidth: + // If the terminal expands then our position calculations will + // be wrong in the future because we think the cursor is + // |t.pos| chars into the string, but there will be a gap at + // the end of any wrapped line. + // + // But the position will actually be correct until we move, so + // we can move back to the beginning and repaint everything. + t.clearAndRepaintLinePlusNPrevious(t.maxLine) + } + + _, err := t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + return err +} + +type pasteIndicatorError struct{} + +func (pasteIndicatorError) Error() string { + return "terminal: ErrPasteIndicator not correctly handled" +} + +// ErrPasteIndicator may be returned from ReadLine as the error, in addition +// to valid line data. It indicates that bracketed paste mode is enabled and +// that the returned line consists only of pasted data. Programs may wish to +// interpret pasted data more literally than typed data. +var ErrPasteIndicator = pasteIndicatorError{} + +// SetBracketedPasteMode requests that the terminal bracket paste operations +// with markers. Not all terminals support this but, if it is supported, then +// enabling this mode will stop any autocomplete callback from running due to +// pastes. Additionally, any lines that are completely pasted will be returned +// from ReadLine with the error set to ErrPasteIndicator. +func (t *Terminal) SetBracketedPasteMode(on bool) { + if on { + io.WriteString(t.c, "\x1b[?2004h") + } else { + io.WriteString(t.c, "\x1b[?2004l") + } +} + +// stRingBuffer is a ring buffer of strings. +type stRingBuffer struct { + // entries contains max elements. + entries []string + max int + // head contains the index of the element most recently added to the ring. + head int + // size contains the number of elements in the ring. + size int +} + +func (s *stRingBuffer) Add(a string) { + if s.entries == nil { + const defaultNumEntries = 100 + s.entries = make([]string, defaultNumEntries) + s.max = defaultNumEntries + } + + s.head = (s.head + 1) % s.max + s.entries[s.head] = a + if s.size < s.max { + s.size++ + } +} + +// NthPreviousEntry returns the value passed to the nth previous call to Add. +// If n is zero then the immediately prior value is returned, if one, then the +// next most recent, and so on. If such an element doesn't exist then ok is +// false. +func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { + if n >= s.size { + return "", false + } + index := s.head - n + if index < 0 { + index += s.max + } + return s.entries[index], true +} + +// readPasswordLine reads from reader until it finds \n or io.EOF. +// The slice returned does not include the \n. +// readPasswordLine also ignores any \r it finds. +func readPasswordLine(reader io.Reader) ([]byte, error) { + var buf [1]byte + var ret []byte + + for { + n, err := reader.Read(buf[:]) + if n > 0 { + switch buf[0] { + case '\n': + return ret, nil + case '\r': + // remove \r from passwords on Windows + default: + ret = append(ret, buf[0]) + } + continue + } + if err != nil { + if err == io.EOF && len(ret) > 0 { + return ret, nil + } + return ret, err + } + } +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go new file mode 100644 index 0000000000000000000000000000000000000000..731c89a284a29f479297461539b17535ab5321d6 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util.go @@ -0,0 +1,114 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd + +// Package terminal provides support functions for dealing with terminals, as +// commonly found on UNIX systems. +// +// Putting a terminal into raw mode is the most common requirement: +// +// oldState, err := terminal.MakeRaw(0) +// if err != nil { +// panic(err) +// } +// defer terminal.Restore(0, oldState) +package terminal // import "golang.org/x/crypto/ssh/terminal" + +import ( + "golang.org/x/sys/unix" +) + +// State contains the state of a terminal. +type State struct { + termios unix.Termios +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + return err == nil +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { + return nil, err + } + + oldState := State{termios: *termios} + + // This attempts to replicate the behaviour documented for cfmakeraw in + // the termios(3) manpage. + termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON + termios.Oflag &^= unix.OPOST + termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN + termios.Cflag &^= unix.CSIZE | unix.PARENB + termios.Cflag |= unix.CS8 + termios.Cc[unix.VMIN] = 1 + termios.Cc[unix.VTIME] = 0 + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil { + return nil, err + } + + return &oldState, nil +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { + return nil, err + } + + return &State{termios: *termios}, nil +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, state *State) error { + return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios) +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { + return -1, -1, err + } + return int(ws.Col), int(ws.Row), nil +} + +// passwordReader is an io.Reader that reads from a specific file descriptor. +type passwordReader int + +func (r passwordReader) Read(buf []byte) (int, error) { + return unix.Read(int(r), buf) +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { + return nil, err + } + + newState := *termios + newState.Lflag &^= unix.ECHO + newState.Lflag |= unix.ICANON | unix.ISIG + newState.Iflag |= unix.ICRNL + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil { + return nil, err + } + + defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios) + + return readPasswordLine(passwordReader(fd)) +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go new file mode 100644 index 0000000000000000000000000000000000000000..cb23a590494015a5689166d40852762b777dd994 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go @@ -0,0 +1,12 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd netbsd openbsd + +package terminal + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TIOCGETA +const ioctlWriteTermios = unix.TIOCSETA diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..5fadfe8a1d50ba10d6d4fea349fe5c7a983eb5da --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go @@ -0,0 +1,10 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package terminal + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETS +const ioctlWriteTermios = unix.TCSETS diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go new file mode 100644 index 0000000000000000000000000000000000000000..799f049f04ea0ce665e44e018780921e2bed0d02 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go @@ -0,0 +1,58 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package terminal provides support functions for dealing with terminals, as +// commonly found on UNIX systems. +// +// Putting a terminal into raw mode is the most common requirement: +// +// oldState, err := terminal.MakeRaw(0) +// if err != nil { +// panic(err) +// } +// defer terminal.Restore(0, oldState) +package terminal + +import ( + "fmt" + "runtime" +) + +type State struct{} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + return false +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, state *State) error { + return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go new file mode 100644 index 0000000000000000000000000000000000000000..9e41b9f43f089fbefb87121d19378deef35558a3 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go @@ -0,0 +1,124 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build solaris + +package terminal // import "golang.org/x/crypto/ssh/terminal" + +import ( + "golang.org/x/sys/unix" + "io" + "syscall" +) + +// State contains the state of a terminal. +type State struct { + termios unix.Termios +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + _, err := unix.IoctlGetTermio(fd, unix.TCGETA) + return err == nil +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + // see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c + val, err := unix.IoctlGetTermios(fd, unix.TCGETS) + if err != nil { + return nil, err + } + oldState := *val + + newState := oldState + newState.Lflag &^= syscall.ECHO + newState.Lflag |= syscall.ICANON | syscall.ISIG + newState.Iflag |= syscall.ICRNL + err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState) + if err != nil { + return nil, err + } + + defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState) + + var buf [16]byte + var ret []byte + for { + n, err := syscall.Read(fd, buf[:]) + if err != nil { + return nil, err + } + if n == 0 { + if len(ret) == 0 { + return nil, io.EOF + } + break + } + if buf[n-1] == '\n' { + n-- + } + ret = append(ret, buf[:n]...) + if n < len(buf) { + break + } + } + + return ret, nil +} + +// MakeRaw puts the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +// see http://cr.illumos.org/~webrev/andy_js/1060/ +func MakeRaw(fd int) (*State, error) { + termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) + if err != nil { + return nil, err + } + + oldState := State{termios: *termios} + + termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON + termios.Oflag &^= unix.OPOST + termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN + termios.Cflag &^= unix.CSIZE | unix.PARENB + termios.Cflag |= unix.CS8 + termios.Cc[unix.VMIN] = 1 + termios.Cc[unix.VTIME] = 0 + + if err := unix.IoctlSetTermios(fd, unix.TCSETS, termios); err != nil { + return nil, err + } + + return &oldState, nil +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, oldState *State) error { + return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios) +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) + if err != nil { + return nil, err + } + + return &State{termios: *termios}, nil +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { + return 0, 0, err + } + return int(ws.Col), int(ws.Row), nil +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..8618955df7383cc1c33135befc356599a3be0199 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go @@ -0,0 +1,103 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +// Package terminal provides support functions for dealing with terminals, as +// commonly found on UNIX systems. +// +// Putting a terminal into raw mode is the most common requirement: +// +// oldState, err := terminal.MakeRaw(0) +// if err != nil { +// panic(err) +// } +// defer terminal.Restore(0, oldState) +package terminal + +import ( + "os" + + "golang.org/x/sys/windows" +) + +type State struct { + mode uint32 +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + var st uint32 + err := windows.GetConsoleMode(windows.Handle(fd), &st) + return err == nil +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + var st uint32 + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err + } + raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { + return nil, err + } + return &State{st}, nil +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + var st uint32 + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err + } + return &State{st}, nil +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, state *State) error { + return windows.SetConsoleMode(windows.Handle(fd), state.mode) +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + var info windows.ConsoleScreenBufferInfo + if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { + return 0, 0, err + } + return int(info.Size.X), int(info.Size.Y), nil +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + var st uint32 + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err + } + old := st + + st &^= (windows.ENABLE_ECHO_INPUT) + st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil { + return nil, err + } + + defer windows.SetConsoleMode(windows.Handle(fd), old) + + var h windows.Handle + p, _ := windows.GetCurrentProcess() + if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil { + return nil, err + } + + f := os.NewFile(uintptr(h), "stdin") + defer f.Close() + return readPasswordLine(f) +} diff --git a/vendor/golang.org/x/sys/windows/asm_windows_386.s b/vendor/golang.org/x/sys/windows/asm_windows_386.s new file mode 100644 index 0000000000000000000000000000000000000000..1c20dd2f897d021e9033f9a2d2da6bd9d1a97dca --- /dev/null +++ b/vendor/golang.org/x/sys/windows/asm_windows_386.s @@ -0,0 +1,13 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +// System calls for 386, Windows are implemented in runtime/syscall_windows.goc +// + +TEXT ·getprocaddress(SB), 7, $0-8 + JMP syscall·getprocaddress(SB) + +TEXT ·loadlibrary(SB), 7, $0-4 + JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/asm_windows_amd64.s b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s new file mode 100644 index 0000000000000000000000000000000000000000..4d025ab556dbe2c3f7e11924023fd0b3a8b35676 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s @@ -0,0 +1,13 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +// System calls for amd64, Windows are implemented in runtime/syscall_windows.goc +// + +TEXT ·getprocaddress(SB), 7, $0-32 + JMP syscall·getprocaddress(SB) + +TEXT ·loadlibrary(SB), 7, $0-8 + JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..e92c05b213c8f63d960bd9c1ceedb20bb798e15b --- /dev/null +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -0,0 +1,378 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "sync" + "sync/atomic" + "syscall" + "unsafe" +) + +// DLLError describes reasons for DLL load failures. +type DLLError struct { + Err error + ObjName string + Msg string +} + +func (e *DLLError) Error() string { return e.Msg } + +// Implemented in runtime/syscall_windows.goc; we provide jumps to them in our assembly file. +func loadlibrary(filename *uint16) (handle uintptr, err syscall.Errno) +func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err syscall.Errno) + +// A DLL implements access to a single DLL. +type DLL struct { + Name string + Handle Handle +} + +// LoadDLL loads DLL file into memory. +// +// Warning: using LoadDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use LazyDLL +// with System set to true, or use LoadLibraryEx directly. +func LoadDLL(name string) (dll *DLL, err error) { + namep, err := UTF16PtrFromString(name) + if err != nil { + return nil, err + } + h, e := loadlibrary(namep) + if e != 0 { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to load " + name + ": " + e.Error(), + } + } + d := &DLL{ + Name: name, + Handle: Handle(h), + } + return d, nil +} + +// MustLoadDLL is like LoadDLL but panics if load operation failes. +func MustLoadDLL(name string) *DLL { + d, e := LoadDLL(name) + if e != nil { + panic(e) + } + return d +} + +// FindProc searches DLL d for procedure named name and returns *Proc +// if found. It returns an error if search fails. +func (d *DLL) FindProc(name string) (proc *Proc, err error) { + namep, err := BytePtrFromString(name) + if err != nil { + return nil, err + } + a, e := getprocaddress(uintptr(d.Handle), namep) + if e != 0 { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(), + } + } + p := &Proc{ + Dll: d, + Name: name, + addr: a, + } + return p, nil +} + +// MustFindProc is like FindProc but panics if search fails. +func (d *DLL) MustFindProc(name string) *Proc { + p, e := d.FindProc(name) + if e != nil { + panic(e) + } + return p +} + +// Release unloads DLL d from memory. +func (d *DLL) Release() (err error) { + return FreeLibrary(d.Handle) +} + +// A Proc implements access to a procedure inside a DLL. +type Proc struct { + Dll *DLL + Name string + addr uintptr +} + +// Addr returns the address of the procedure represented by p. +// The return value can be passed to Syscall to run the procedure. +func (p *Proc) Addr() uintptr { + return p.addr +} + +//go:uintptrescapes + +// Call executes procedure p with arguments a. It will panic, if more than 15 arguments +// are supplied. +// +// The returned error is always non-nil, constructed from the result of GetLastError. +// Callers must inspect the primary return value to decide whether an error occurred +// (according to the semantics of the specific function being called) before consulting +// the error. The error will be guaranteed to contain windows.Errno. +func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { + switch len(a) { + case 0: + return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0) + case 1: + return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0) + case 2: + return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0) + case 3: + return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2]) + case 4: + return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0) + case 5: + return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0) + case 6: + return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5]) + case 7: + return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0) + case 8: + return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0) + case 9: + return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) + case 10: + return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0) + case 11: + return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0) + case 12: + return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) + case 13: + return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0) + case 14: + return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0) + case 15: + return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]) + default: + panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".") + } +} + +// A LazyDLL implements access to a single DLL. +// It will delay the load of the DLL until the first +// call to its Handle method or to one of its +// LazyProc's Addr method. +type LazyDLL struct { + Name string + + // System determines whether the DLL must be loaded from the + // Windows System directory, bypassing the normal DLL search + // path. + System bool + + mu sync.Mutex + dll *DLL // non nil once DLL is loaded +} + +// Load loads DLL file d.Name into memory. It returns an error if fails. +// Load will not try to load DLL, if it is already loaded into memory. +func (d *LazyDLL) Load() error { + // Non-racy version of: + // if d.dll != nil { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) != nil { + return nil + } + d.mu.Lock() + defer d.mu.Unlock() + if d.dll != nil { + return nil + } + + // kernel32.dll is special, since it's where LoadLibraryEx comes from. + // The kernel already special-cases its name, so it's always + // loaded from system32. + var dll *DLL + var err error + if d.Name == "kernel32.dll" { + dll, err = LoadDLL(d.Name) + } else { + dll, err = loadLibraryEx(d.Name, d.System) + } + if err != nil { + return err + } + + // Non-racy version of: + // d.dll = dll + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll)) + return nil +} + +// mustLoad is like Load but panics if search fails. +func (d *LazyDLL) mustLoad() { + e := d.Load() + if e != nil { + panic(e) + } +} + +// Handle returns d's module handle. +func (d *LazyDLL) Handle() uintptr { + d.mustLoad() + return uintptr(d.dll.Handle) +} + +// NewProc returns a LazyProc for accessing the named procedure in the DLL d. +func (d *LazyDLL) NewProc(name string) *LazyProc { + return &LazyProc{l: d, Name: name} +} + +// NewLazyDLL creates new LazyDLL associated with DLL file. +func NewLazyDLL(name string) *LazyDLL { + return &LazyDLL{Name: name} +} + +// NewLazySystemDLL is like NewLazyDLL, but will only +// search Windows System directory for the DLL if name is +// a base name (like "advapi32.dll"). +func NewLazySystemDLL(name string) *LazyDLL { + return &LazyDLL{Name: name, System: true} +} + +// A LazyProc implements access to a procedure inside a LazyDLL. +// It delays the lookup until the Addr method is called. +type LazyProc struct { + Name string + + mu sync.Mutex + l *LazyDLL + proc *Proc +} + +// Find searches DLL for procedure named p.Name. It returns +// an error if search fails. Find will not search procedure, +// if it is already found and loaded into memory. +func (p *LazyProc) Find() error { + // Non-racy version of: + // if p.proc == nil { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil { + p.mu.Lock() + defer p.mu.Unlock() + if p.proc == nil { + e := p.l.Load() + if e != nil { + return e + } + proc, e := p.l.dll.FindProc(p.Name) + if e != nil { + return e + } + // Non-racy version of: + // p.proc = proc + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc)) + } + } + return nil +} + +// mustFind is like Find but panics if search fails. +func (p *LazyProc) mustFind() { + e := p.Find() + if e != nil { + panic(e) + } +} + +// Addr returns the address of the procedure represented by p. +// The return value can be passed to Syscall to run the procedure. +// It will panic if the procedure cannot be found. +func (p *LazyProc) Addr() uintptr { + p.mustFind() + return p.proc.Addr() +} + +//go:uintptrescapes + +// Call executes procedure p with arguments a. It will panic, if more than 15 arguments +// are supplied. It will also panic if the procedure cannot be found. +// +// The returned error is always non-nil, constructed from the result of GetLastError. +// Callers must inspect the primary return value to decide whether an error occurred +// (according to the semantics of the specific function being called) before consulting +// the error. The error will be guaranteed to contain windows.Errno. +func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { + p.mustFind() + return p.proc.Call(a...) +} + +var canDoSearchSystem32Once struct { + sync.Once + v bool +} + +func initCanDoSearchSystem32() { + // https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: + // "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + // Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on + // systems that have KB2533623 installed. To determine whether the + // flags are available, use GetProcAddress to get the address of the + // AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories + // function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* + // flags can be used with LoadLibraryEx." + canDoSearchSystem32Once.v = (modkernel32.NewProc("AddDllDirectory").Find() == nil) +} + +func canDoSearchSystem32() bool { + canDoSearchSystem32Once.Do(initCanDoSearchSystem32) + return canDoSearchSystem32Once.v +} + +func isBaseName(name string) bool { + for _, c := range name { + if c == ':' || c == '/' || c == '\\' { + return false + } + } + return true +} + +// loadLibraryEx wraps the Windows LoadLibraryEx function. +// +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx +// +// If name is not an absolute path, LoadLibraryEx searches for the DLL +// in a variety of automatic locations unless constrained by flags. +// See: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx +func loadLibraryEx(name string, system bool) (*DLL, error) { + loadDLL := name + var flags uintptr + if system { + if canDoSearchSystem32() { + const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + flags = LOAD_LIBRARY_SEARCH_SYSTEM32 + } else if isBaseName(name) { + // WindowsXP or unpatched Windows machine + // trying to load "foo.dll" out of the system + // folder, but LoadLibraryEx doesn't support + // that yet on their system, so emulate it. + windir, _ := Getenv("WINDIR") // old var; apparently works on XP + if windir == "" { + return nil, errString("%WINDIR% not defined") + } + loadDLL = windir + "\\System32\\" + name + } + } + h, err := LoadLibraryEx(loadDLL, 0, flags) + if err != nil { + return nil, err + } + return &DLL{Name: name, Handle: h}, nil +} + +type errString string + +func (s errString) Error() string { return string(s) } diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..bdc71e241e0c6ee53c568a47377e9ea619393775 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -0,0 +1,29 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Windows environment variables. + +package windows + +import "syscall" + +func Getenv(key string) (value string, found bool) { + return syscall.Getenv(key) +} + +func Setenv(key, value string) error { + return syscall.Setenv(key, value) +} + +func Clearenv() { + syscall.Clearenv() +} + +func Environ() []string { + return syscall.Environ() +} + +func Unsetenv(key string) error { + return syscall.Unsetenv(key) +} diff --git a/vendor/golang.org/x/sys/windows/eventlog.go b/vendor/golang.org/x/sys/windows/eventlog.go new file mode 100644 index 0000000000000000000000000000000000000000..40af946e162f94306b65d77df160cdcd2b32ed72 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/eventlog.go @@ -0,0 +1,20 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package windows + +const ( + EVENTLOG_SUCCESS = 0 + EVENTLOG_ERROR_TYPE = 1 + EVENTLOG_WARNING_TYPE = 2 + EVENTLOG_INFORMATION_TYPE = 4 + EVENTLOG_AUDIT_SUCCESS = 8 + EVENTLOG_AUDIT_FAILURE = 16 +) + +//sys RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW +//sys DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource +//sys ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..3606c3a8b3690599c77bb0460f40dd9327786c05 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/exec_windows.go @@ -0,0 +1,97 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Fork, exec, wait, etc. + +package windows + +// EscapeArg rewrites command line argument s as prescribed +// in http://msdn.microsoft.com/en-us/library/ms880421. +// This function returns "" (2 double quotes) if s is empty. +// Alternatively, these transformations are done: +// - every back slash (\) is doubled, but only if immediately +// followed by double quote ("); +// - every double quote (") is escaped by back slash (\); +// - finally, s is wrapped with double quotes (arg -> "arg"), +// but only if there is space or tab inside s. +func EscapeArg(s string) string { + if len(s) == 0 { + return "\"\"" + } + n := len(s) + hasSpace := false + for i := 0; i < len(s); i++ { + switch s[i] { + case '"', '\\': + n++ + case ' ', '\t': + hasSpace = true + } + } + if hasSpace { + n += 2 + } + if n == len(s) { + return s + } + + qs := make([]byte, n) + j := 0 + if hasSpace { + qs[j] = '"' + j++ + } + slashes := 0 + for i := 0; i < len(s); i++ { + switch s[i] { + default: + slashes = 0 + qs[j] = s[i] + case '\\': + slashes++ + qs[j] = s[i] + case '"': + for ; slashes > 0; slashes-- { + qs[j] = '\\' + j++ + } + qs[j] = '\\' + j++ + qs[j] = s[i] + } + j++ + } + if hasSpace { + for ; slashes > 0; slashes-- { + qs[j] = '\\' + j++ + } + qs[j] = '"' + j++ + } + return string(qs[:j]) +} + +func CloseOnExec(fd Handle) { + SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0) +} + +// FullPath retrieves the full path of the specified file. +func FullPath(name string) (path string, err error) { + p, err := UTF16PtrFromString(name) + if err != nil { + return "", err + } + n := uint32(100) + for { + buf := make([]uint16, n) + n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil) + if err != nil { + return "", err + } + if n <= uint32(len(buf)) { + return UTF16ToString(buf[:n]), nil + } + } +} diff --git a/vendor/golang.org/x/sys/windows/memory_windows.go b/vendor/golang.org/x/sys/windows/memory_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..f80a4204f097d884b94ccb2324b8694863d6877f --- /dev/null +++ b/vendor/golang.org/x/sys/windows/memory_windows.go @@ -0,0 +1,26 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +const ( + MEM_COMMIT = 0x00001000 + MEM_RESERVE = 0x00002000 + MEM_DECOMMIT = 0x00004000 + MEM_RELEASE = 0x00008000 + MEM_RESET = 0x00080000 + MEM_TOP_DOWN = 0x00100000 + MEM_WRITE_WATCH = 0x00200000 + MEM_PHYSICAL = 0x00400000 + MEM_RESET_UNDO = 0x01000000 + MEM_LARGE_PAGES = 0x20000000 + + PAGE_NOACCESS = 0x01 + PAGE_READONLY = 0x02 + PAGE_READWRITE = 0x04 + PAGE_WRITECOPY = 0x08 + PAGE_EXECUTE_READ = 0x20 + PAGE_EXECUTE_READWRITE = 0x40 + PAGE_EXECUTE_WRITECOPY = 0x80 +) diff --git a/vendor/golang.org/x/sys/windows/mksyscall.go b/vendor/golang.org/x/sys/windows/mksyscall.go new file mode 100644 index 0000000000000000000000000000000000000000..fb7db0ef8d4af652fe6b62df59fb8808a32b4fae --- /dev/null +++ b/vendor/golang.org/x/sys/windows/mksyscall.go @@ -0,0 +1,7 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go diff --git a/vendor/golang.org/x/sys/windows/race.go b/vendor/golang.org/x/sys/windows/race.go new file mode 100644 index 0000000000000000000000000000000000000000..a74e3e24b557e9d99cb6643e0a274e14ba7654ba --- /dev/null +++ b/vendor/golang.org/x/sys/windows/race.go @@ -0,0 +1,30 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows,race + +package windows + +import ( + "runtime" + "unsafe" +) + +const raceenabled = true + +func raceAcquire(addr unsafe.Pointer) { + runtime.RaceAcquire(addr) +} + +func raceReleaseMerge(addr unsafe.Pointer) { + runtime.RaceReleaseMerge(addr) +} + +func raceReadRange(addr unsafe.Pointer, len int) { + runtime.RaceReadRange(addr, len) +} + +func raceWriteRange(addr unsafe.Pointer, len int) { + runtime.RaceWriteRange(addr, len) +} diff --git a/vendor/golang.org/x/sys/windows/race0.go b/vendor/golang.org/x/sys/windows/race0.go new file mode 100644 index 0000000000000000000000000000000000000000..e44a3cbf67994455be845fcb87fde02f01787c55 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/race0.go @@ -0,0 +1,25 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows,!race + +package windows + +import ( + "unsafe" +) + +const raceenabled = false + +func raceAcquire(addr unsafe.Pointer) { +} + +func raceReleaseMerge(addr unsafe.Pointer) { +} + +func raceReadRange(addr unsafe.Pointer, len int) { +} + +func raceWriteRange(addr unsafe.Pointer, len int) { +} diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..f1ec5dc4ee798dacc684d342b97c6b54fe538fa9 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -0,0 +1,476 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "syscall" + "unsafe" +) + +const ( + STANDARD_RIGHTS_REQUIRED = 0xf0000 + STANDARD_RIGHTS_READ = 0x20000 + STANDARD_RIGHTS_WRITE = 0x20000 + STANDARD_RIGHTS_EXECUTE = 0x20000 + STANDARD_RIGHTS_ALL = 0x1F0000 +) + +const ( + NameUnknown = 0 + NameFullyQualifiedDN = 1 + NameSamCompatible = 2 + NameDisplay = 3 + NameUniqueId = 6 + NameCanonical = 7 + NameUserPrincipal = 8 + NameCanonicalEx = 9 + NameServicePrincipal = 10 + NameDnsDomain = 12 +) + +// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. +// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx +//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW +//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW + +// TranslateAccountName converts a directory service +// object name from one format to another. +func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) { + u, e := UTF16PtrFromString(username) + if e != nil { + return "", e + } + n := uint32(50) + for { + b := make([]uint16, n) + e = TranslateName(u, from, to, &b[0], &n) + if e == nil { + return UTF16ToString(b[:n]), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", e + } + if n <= uint32(len(b)) { + return "", e + } + } +} + +const ( + // do not reorder + NetSetupUnknownStatus = iota + NetSetupUnjoined + NetSetupWorkgroupName + NetSetupDomainName +) + +type UserInfo10 struct { + Name *uint16 + Comment *uint16 + UsrComment *uint16 + FullName *uint16 +} + +//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo +//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation +//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree + +const ( + // do not reorder + SidTypeUser = 1 + iota + SidTypeGroup + SidTypeDomain + SidTypeAlias + SidTypeWellKnownGroup + SidTypeDeletedAccount + SidTypeInvalid + SidTypeUnknown + SidTypeComputer + SidTypeLabel +) + +type SidIdentifierAuthority struct { + Value [6]byte +} + +var ( + SECURITY_NULL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}} + SECURITY_WORLD_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}} + SECURITY_LOCAL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}} + SECURITY_CREATOR_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}} + SECURITY_NON_UNIQUE_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}} + SECURITY_NT_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}} + SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}} +) + +const ( + SECURITY_NULL_RID = 0 + SECURITY_WORLD_RID = 0 + SECURITY_LOCAL_RID = 0 + SECURITY_CREATOR_OWNER_RID = 0 + SECURITY_CREATOR_GROUP_RID = 1 + SECURITY_DIALUP_RID = 1 + SECURITY_NETWORK_RID = 2 + SECURITY_BATCH_RID = 3 + SECURITY_INTERACTIVE_RID = 4 + SECURITY_LOGON_IDS_RID = 5 + SECURITY_SERVICE_RID = 6 + SECURITY_LOCAL_SYSTEM_RID = 18 + SECURITY_BUILTIN_DOMAIN_RID = 32 + SECURITY_PRINCIPAL_SELF_RID = 10 + SECURITY_CREATOR_OWNER_SERVER_RID = 0x2 + SECURITY_CREATOR_GROUP_SERVER_RID = 0x3 + SECURITY_LOGON_IDS_RID_COUNT = 0x3 + SECURITY_ANONYMOUS_LOGON_RID = 0x7 + SECURITY_PROXY_RID = 0x8 + SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9 + SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID + SECURITY_AUTHENTICATED_USER_RID = 0xb + SECURITY_RESTRICTED_CODE_RID = 0xc + SECURITY_NT_NON_UNIQUE_RID = 0x15 +) + +// Predefined domain-relative RIDs for local groups. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx +const ( + DOMAIN_ALIAS_RID_ADMINS = 0x220 + DOMAIN_ALIAS_RID_USERS = 0x221 + DOMAIN_ALIAS_RID_GUESTS = 0x222 + DOMAIN_ALIAS_RID_POWER_USERS = 0x223 + DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224 + DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225 + DOMAIN_ALIAS_RID_PRINT_OPS = 0x226 + DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227 + DOMAIN_ALIAS_RID_REPLICATOR = 0x228 + DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229 + DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a + DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x22b + DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x22c + DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d + DOMAIN_ALIAS_RID_MONITORING_USERS = 0X22e + DOMAIN_ALIAS_RID_LOGGING_USERS = 0x22f + DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 0x230 + DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x231 + DOMAIN_ALIAS_RID_DCOM_USERS = 0x232 + DOMAIN_ALIAS_RID_IUSERS = 0x238 + DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 0x239 + DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 0x23b + DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c + DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 0x23d + DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP = 0x23e +) + +//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW +//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW +//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW +//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW +//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid +//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid +//sys AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid +//sys FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid +//sys EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid + +// The security identifier (SID) structure is a variable-length +// structure used to uniquely identify users or groups. +type SID struct{} + +// StringToSid converts a string-format security identifier +// sid into a valid, functional sid. +func StringToSid(s string) (*SID, error) { + var sid *SID + p, e := UTF16PtrFromString(s) + if e != nil { + return nil, e + } + e = ConvertStringSidToSid(p, &sid) + if e != nil { + return nil, e + } + defer LocalFree((Handle)(unsafe.Pointer(sid))) + return sid.Copy() +} + +// LookupSID retrieves a security identifier sid for the account +// and the name of the domain on which the account was found. +// System specify target computer to search. +func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) { + if len(account) == 0 { + return nil, "", 0, syscall.EINVAL + } + acc, e := UTF16PtrFromString(account) + if e != nil { + return nil, "", 0, e + } + var sys *uint16 + if len(system) > 0 { + sys, e = UTF16PtrFromString(system) + if e != nil { + return nil, "", 0, e + } + } + n := uint32(50) + dn := uint32(50) + for { + b := make([]byte, n) + db := make([]uint16, dn) + sid = (*SID)(unsafe.Pointer(&b[0])) + e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType) + if e == nil { + return sid, UTF16ToString(db), accType, nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return nil, "", 0, e + } + if n <= uint32(len(b)) { + return nil, "", 0, e + } + } +} + +// String converts sid to a string format +// suitable for display, storage, or transmission. +func (sid *SID) String() (string, error) { + var s *uint16 + e := ConvertSidToStringSid(sid, &s) + if e != nil { + return "", e + } + defer LocalFree((Handle)(unsafe.Pointer(s))) + return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil +} + +// Len returns the length, in bytes, of a valid security identifier sid. +func (sid *SID) Len() int { + return int(GetLengthSid(sid)) +} + +// Copy creates a duplicate of security identifier sid. +func (sid *SID) Copy() (*SID, error) { + b := make([]byte, sid.Len()) + sid2 := (*SID)(unsafe.Pointer(&b[0])) + e := CopySid(uint32(len(b)), sid2, sid) + if e != nil { + return nil, e + } + return sid2, nil +} + +// LookupAccount retrieves the name of the account for this sid +// and the name of the first domain on which this sid is found. +// System specify target computer to search for. +func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) { + var sys *uint16 + if len(system) > 0 { + sys, err = UTF16PtrFromString(system) + if err != nil { + return "", "", 0, err + } + } + n := uint32(50) + dn := uint32(50) + for { + b := make([]uint16, n) + db := make([]uint16, dn) + e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType) + if e == nil { + return UTF16ToString(b), UTF16ToString(db), accType, nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", "", 0, e + } + if n <= uint32(len(b)) { + return "", "", 0, e + } + } +} + +const ( + // do not reorder + TOKEN_ASSIGN_PRIMARY = 1 << iota + TOKEN_DUPLICATE + TOKEN_IMPERSONATE + TOKEN_QUERY + TOKEN_QUERY_SOURCE + TOKEN_ADJUST_PRIVILEGES + TOKEN_ADJUST_GROUPS + TOKEN_ADJUST_DEFAULT + + TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | + TOKEN_ASSIGN_PRIMARY | + TOKEN_DUPLICATE | + TOKEN_IMPERSONATE | + TOKEN_QUERY | + TOKEN_QUERY_SOURCE | + TOKEN_ADJUST_PRIVILEGES | + TOKEN_ADJUST_GROUPS | + TOKEN_ADJUST_DEFAULT + TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY + TOKEN_WRITE = STANDARD_RIGHTS_WRITE | + TOKEN_ADJUST_PRIVILEGES | + TOKEN_ADJUST_GROUPS | + TOKEN_ADJUST_DEFAULT + TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE +) + +const ( + // do not reorder + TokenUser = 1 + iota + TokenGroups + TokenPrivileges + TokenOwner + TokenPrimaryGroup + TokenDefaultDacl + TokenSource + TokenType + TokenImpersonationLevel + TokenStatistics + TokenRestrictedSids + TokenSessionId + TokenGroupsAndPrivileges + TokenSessionReference + TokenSandBoxInert + TokenAuditPolicy + TokenOrigin + TokenElevationType + TokenLinkedToken + TokenElevation + TokenHasRestrictions + TokenAccessInformation + TokenVirtualizationAllowed + TokenVirtualizationEnabled + TokenIntegrityLevel + TokenUIAccess + TokenMandatoryPolicy + TokenLogonSid + MaxTokenInfoClass +) + +type SIDAndAttributes struct { + Sid *SID + Attributes uint32 +} + +type Tokenuser struct { + User SIDAndAttributes +} + +type Tokenprimarygroup struct { + PrimaryGroup *SID +} + +type Tokengroups struct { + GroupCount uint32 + Groups [1]SIDAndAttributes +} + +// Authorization Functions +//sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership +//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken +//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation +//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW + +// An access token contains the security information for a logon session. +// The system creates an access token when a user logs on, and every +// process executed on behalf of the user has a copy of the token. +// The token identifies the user, the user's groups, and the user's +// privileges. The system uses the token to control access to securable +// objects and to control the ability of the user to perform various +// system-related operations on the local computer. +type Token Handle + +// OpenCurrentProcessToken opens the access token +// associated with current process. +func OpenCurrentProcessToken() (Token, error) { + p, e := GetCurrentProcess() + if e != nil { + return 0, e + } + var t Token + e = OpenProcessToken(p, TOKEN_QUERY, &t) + if e != nil { + return 0, e + } + return t, nil +} + +// Close releases access to access token. +func (t Token) Close() error { + return CloseHandle(Handle(t)) +} + +// getInfo retrieves a specified type of information about an access token. +func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) { + n := uint32(initSize) + for { + b := make([]byte, n) + e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) + if e == nil { + return unsafe.Pointer(&b[0]), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return nil, e + } + if n <= uint32(len(b)) { + return nil, e + } + } +} + +// GetTokenUser retrieves access token t user account information. +func (t Token) GetTokenUser() (*Tokenuser, error) { + i, e := t.getInfo(TokenUser, 50) + if e != nil { + return nil, e + } + return (*Tokenuser)(i), nil +} + +// GetTokenGroups retrieves group accounts associated with access token t. +func (t Token) GetTokenGroups() (*Tokengroups, error) { + i, e := t.getInfo(TokenGroups, 50) + if e != nil { + return nil, e + } + return (*Tokengroups)(i), nil +} + +// GetTokenPrimaryGroup retrieves access token t primary group information. +// A pointer to a SID structure representing a group that will become +// the primary group of any objects created by a process using this access token. +func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) { + i, e := t.getInfo(TokenPrimaryGroup, 50) + if e != nil { + return nil, e + } + return (*Tokenprimarygroup)(i), nil +} + +// GetUserProfileDirectory retrieves path to the +// root directory of the access token t user's profile. +func (t Token) GetUserProfileDirectory() (string, error) { + n := uint32(100) + for { + b := make([]uint16, n) + e := GetUserProfileDirectory(t, &b[0], &n) + if e == nil { + return UTF16ToString(b), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", e + } + if n <= uint32(len(b)) { + return "", e + } + } +} + +// IsMember reports whether the access token t is a member of the provided SID. +func (t Token) IsMember(sid *SID) (bool, error) { + var b int32 + if e := checkTokenMembership(t, sid, &b); e != nil { + return false, e + } + return b != 0, nil +} diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go new file mode 100644 index 0000000000000000000000000000000000000000..a500dd7dfcf0a164eded614c9a0d0dba81223fad --- /dev/null +++ b/vendor/golang.org/x/sys/windows/service.go @@ -0,0 +1,164 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package windows + +const ( + SC_MANAGER_CONNECT = 1 + SC_MANAGER_CREATE_SERVICE = 2 + SC_MANAGER_ENUMERATE_SERVICE = 4 + SC_MANAGER_LOCK = 8 + SC_MANAGER_QUERY_LOCK_STATUS = 16 + SC_MANAGER_MODIFY_BOOT_CONFIG = 32 + SC_MANAGER_ALL_ACCESS = 0xf003f +) + +//sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW + +const ( + SERVICE_KERNEL_DRIVER = 1 + SERVICE_FILE_SYSTEM_DRIVER = 2 + SERVICE_ADAPTER = 4 + SERVICE_RECOGNIZER_DRIVER = 8 + SERVICE_WIN32_OWN_PROCESS = 16 + SERVICE_WIN32_SHARE_PROCESS = 32 + SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS + SERVICE_INTERACTIVE_PROCESS = 256 + SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER + SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS + + SERVICE_BOOT_START = 0 + SERVICE_SYSTEM_START = 1 + SERVICE_AUTO_START = 2 + SERVICE_DEMAND_START = 3 + SERVICE_DISABLED = 4 + + SERVICE_ERROR_IGNORE = 0 + SERVICE_ERROR_NORMAL = 1 + SERVICE_ERROR_SEVERE = 2 + SERVICE_ERROR_CRITICAL = 3 + + SC_STATUS_PROCESS_INFO = 0 + + SERVICE_STOPPED = 1 + SERVICE_START_PENDING = 2 + SERVICE_STOP_PENDING = 3 + SERVICE_RUNNING = 4 + SERVICE_CONTINUE_PENDING = 5 + SERVICE_PAUSE_PENDING = 6 + SERVICE_PAUSED = 7 + SERVICE_NO_CHANGE = 0xffffffff + + SERVICE_ACCEPT_STOP = 1 + SERVICE_ACCEPT_PAUSE_CONTINUE = 2 + SERVICE_ACCEPT_SHUTDOWN = 4 + SERVICE_ACCEPT_PARAMCHANGE = 8 + SERVICE_ACCEPT_NETBINDCHANGE = 16 + SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32 + SERVICE_ACCEPT_POWEREVENT = 64 + SERVICE_ACCEPT_SESSIONCHANGE = 128 + + SERVICE_CONTROL_STOP = 1 + SERVICE_CONTROL_PAUSE = 2 + SERVICE_CONTROL_CONTINUE = 3 + SERVICE_CONTROL_INTERROGATE = 4 + SERVICE_CONTROL_SHUTDOWN = 5 + SERVICE_CONTROL_PARAMCHANGE = 6 + SERVICE_CONTROL_NETBINDADD = 7 + SERVICE_CONTROL_NETBINDREMOVE = 8 + SERVICE_CONTROL_NETBINDENABLE = 9 + SERVICE_CONTROL_NETBINDDISABLE = 10 + SERVICE_CONTROL_DEVICEEVENT = 11 + SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12 + SERVICE_CONTROL_POWEREVENT = 13 + SERVICE_CONTROL_SESSIONCHANGE = 14 + + SERVICE_ACTIVE = 1 + SERVICE_INACTIVE = 2 + SERVICE_STATE_ALL = 3 + + SERVICE_QUERY_CONFIG = 1 + SERVICE_CHANGE_CONFIG = 2 + SERVICE_QUERY_STATUS = 4 + SERVICE_ENUMERATE_DEPENDENTS = 8 + SERVICE_START = 16 + SERVICE_STOP = 32 + SERVICE_PAUSE_CONTINUE = 64 + SERVICE_INTERROGATE = 128 + SERVICE_USER_DEFINED_CONTROL = 256 + SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL + SERVICE_RUNS_IN_SYSTEM_PROCESS = 1 + SERVICE_CONFIG_DESCRIPTION = 1 + SERVICE_CONFIG_FAILURE_ACTIONS = 2 + + NO_ERROR = 0 + + SC_ENUM_PROCESS_INFO = 0 +) + +type SERVICE_STATUS struct { + ServiceType uint32 + CurrentState uint32 + ControlsAccepted uint32 + Win32ExitCode uint32 + ServiceSpecificExitCode uint32 + CheckPoint uint32 + WaitHint uint32 +} + +type SERVICE_TABLE_ENTRY struct { + ServiceName *uint16 + ServiceProc uintptr +} + +type QUERY_SERVICE_CONFIG struct { + ServiceType uint32 + StartType uint32 + ErrorControl uint32 + BinaryPathName *uint16 + LoadOrderGroup *uint16 + TagId uint32 + Dependencies *uint16 + ServiceStartName *uint16 + DisplayName *uint16 +} + +type SERVICE_DESCRIPTION struct { + Description *uint16 +} + +type SERVICE_STATUS_PROCESS struct { + ServiceType uint32 + CurrentState uint32 + ControlsAccepted uint32 + Win32ExitCode uint32 + ServiceSpecificExitCode uint32 + CheckPoint uint32 + WaitHint uint32 + ProcessId uint32 + ServiceFlags uint32 +} + +type ENUM_SERVICE_STATUS_PROCESS struct { + ServiceName *uint16 + DisplayName *uint16 + ServiceStatusProcess SERVICE_STATUS_PROCESS +} + +//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle +//sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW +//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW +//sys DeleteService(service Handle) (err error) = advapi32.DeleteService +//sys StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW +//sys QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus +//sys ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService +//sys StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW +//sys SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus +//sys ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW +//sys QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW +//sys ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W +//sys QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W +//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW diff --git a/vendor/golang.org/x/sys/windows/str.go b/vendor/golang.org/x/sys/windows/str.go new file mode 100644 index 0000000000000000000000000000000000000000..917cc2aae4e1b4163353fbdef21f591169977421 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/str.go @@ -0,0 +1,22 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package windows + +func itoa(val int) string { // do it here rather than with fmt to avoid dependency + if val < 0 { + return "-" + itoa(-val) + } + var buf [32]byte // big enough for int64 + i := len(buf) - 1 + for val >= 10 { + buf[i] = byte(val%10 + '0') + i-- + val /= 10 + } + buf[i] = byte(val + '0') + return string(buf[i:]) +} diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go new file mode 100644 index 0000000000000000000000000000000000000000..af828a91bcf3fe6e2cee28cada66753543d8a5c8 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -0,0 +1,74 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +// Package windows contains an interface to the low-level operating system +// primitives. OS details vary depending on the underlying system, and +// by default, godoc will display the OS-specific documentation for the current +// system. If you want godoc to display syscall documentation for another +// system, set $GOOS and $GOARCH to the desired system. For example, if +// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS +// to freebsd and $GOARCH to arm. +// +// The primary use of this package is inside other packages that provide a more +// portable interface to the system, such as "os", "time" and "net". Use +// those packages rather than this one if you can. +// +// For details of the functions and data types in this package consult +// the manuals for the appropriate operating system. +// +// These calls return err == nil to indicate success; otherwise +// err represents an operating system error describing the failure and +// holds a value of type syscall.Errno. +package windows // import "golang.org/x/sys/windows" + +import ( + "syscall" +) + +// ByteSliceFromString returns a NUL-terminated slice of bytes +// containing the text of s. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func ByteSliceFromString(s string) ([]byte, error) { + for i := 0; i < len(s); i++ { + if s[i] == 0 { + return nil, syscall.EINVAL + } + } + a := make([]byte, len(s)+1) + copy(a, s) + return a, nil +} + +// BytePtrFromString returns a pointer to a NUL-terminated array of +// bytes containing the text of s. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func BytePtrFromString(s string) (*byte, error) { + a, err := ByteSliceFromString(s) + if err != nil { + return nil, err + } + return &a[0], nil +} + +// Single-word zero for use when we need a valid pointer to 0 bytes. +// See mksyscall.pl. +var _zero uintptr + +func (ts *Timespec) Unix() (sec int64, nsec int64) { + return int64(ts.Sec), int64(ts.Nsec) +} + +func (tv *Timeval) Unix() (sec int64, nsec int64) { + return int64(tv.Sec), int64(tv.Usec) * 1000 +} + +func (ts *Timespec) Nano() int64 { + return int64(ts.Sec)*1e9 + int64(ts.Nsec) +} + +func (tv *Timeval) Nano() int64 { + return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 +} diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..1e9f4bb4a376285c9f1781e025d5b8e008fbc0d7 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -0,0 +1,1153 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Windows system calls. + +package windows + +import ( + errorspkg "errors" + "sync" + "syscall" + "unicode/utf16" + "unsafe" +) + +type Handle uintptr + +const ( + InvalidHandle = ^Handle(0) + + // Flags for DefineDosDevice. + DDD_EXACT_MATCH_ON_REMOVE = 0x00000004 + DDD_NO_BROADCAST_SYSTEM = 0x00000008 + DDD_RAW_TARGET_PATH = 0x00000001 + DDD_REMOVE_DEFINITION = 0x00000002 + + // Return values for GetDriveType. + DRIVE_UNKNOWN = 0 + DRIVE_NO_ROOT_DIR = 1 + DRIVE_REMOVABLE = 2 + DRIVE_FIXED = 3 + DRIVE_REMOTE = 4 + DRIVE_CDROM = 5 + DRIVE_RAMDISK = 6 + + // File system flags from GetVolumeInformation and GetVolumeInformationByHandle. + FILE_CASE_SENSITIVE_SEARCH = 0x00000001 + FILE_CASE_PRESERVED_NAMES = 0x00000002 + FILE_FILE_COMPRESSION = 0x00000010 + FILE_DAX_VOLUME = 0x20000000 + FILE_NAMED_STREAMS = 0x00040000 + FILE_PERSISTENT_ACLS = 0x00000008 + FILE_READ_ONLY_VOLUME = 0x00080000 + FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000 + FILE_SUPPORTS_ENCRYPTION = 0x00020000 + FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000 + FILE_SUPPORTS_HARD_LINKS = 0x00400000 + FILE_SUPPORTS_OBJECT_IDS = 0x00010000 + FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000 + FILE_SUPPORTS_REPARSE_POINTS = 0x00000080 + FILE_SUPPORTS_SPARSE_FILES = 0x00000040 + FILE_SUPPORTS_TRANSACTIONS = 0x00200000 + FILE_SUPPORTS_USN_JOURNAL = 0x02000000 + FILE_UNICODE_ON_DISK = 0x00000004 + FILE_VOLUME_IS_COMPRESSED = 0x00008000 + FILE_VOLUME_QUOTAS = 0x00000020 +) + +// StringToUTF16 is deprecated. Use UTF16FromString instead. +// If s contains a NUL byte this function panics instead of +// returning an error. +func StringToUTF16(s string) []uint16 { + a, err := UTF16FromString(s) + if err != nil { + panic("windows: string with NUL passed to StringToUTF16") + } + return a +} + +// UTF16FromString returns the UTF-16 encoding of the UTF-8 string +// s, with a terminating NUL added. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func UTF16FromString(s string) ([]uint16, error) { + for i := 0; i < len(s); i++ { + if s[i] == 0 { + return nil, syscall.EINVAL + } + } + return utf16.Encode([]rune(s + "\x00")), nil +} + +// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, +// with a terminating NUL removed. +func UTF16ToString(s []uint16) string { + for i, v := range s { + if v == 0 { + s = s[0:i] + break + } + } + return string(utf16.Decode(s)) +} + +// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead. +// If s contains a NUL byte this function panics instead of +// returning an error. +func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] } + +// UTF16PtrFromString returns pointer to the UTF-16 encoding of +// the UTF-8 string s, with a terminating NUL added. If s +// contains a NUL byte at any location, it returns (nil, syscall.EINVAL). +func UTF16PtrFromString(s string) (*uint16, error) { + a, err := UTF16FromString(s) + if err != nil { + return nil, err + } + return &a[0], nil +} + +func Getpagesize() int { return 4096 } + +// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. +// This is useful when interoperating with Windows code requiring callbacks. +func NewCallback(fn interface{}) uintptr { + return syscall.NewCallback(fn) +} + +// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. +// This is useful when interoperating with Windows code requiring callbacks. +func NewCallbackCDecl(fn interface{}) uintptr { + return syscall.NewCallbackCDecl(fn) +} + +// windows api calls + +//sys GetLastError() (lasterr error) +//sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW +//sys LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) = LoadLibraryExW +//sys FreeLibrary(handle Handle) (err error) +//sys GetProcAddress(module Handle, procname string) (proc uintptr, err error) +//sys GetVersion() (ver uint32, err error) +//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW +//sys ExitProcess(exitcode uint32) +//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW +//sys ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) +//sys WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) +//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff] +//sys CloseHandle(handle Handle) (err error) +//sys GetStdHandle(stdhandle uint32) (handle Handle, err error) [failretval==InvalidHandle] +//sys SetStdHandle(stdhandle uint32, handle Handle) (err error) +//sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW +//sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW +//sys FindClose(handle Handle) (err error) +//sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) +//sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW +//sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW +//sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW +//sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW +//sys DeleteFile(path *uint16) (err error) = DeleteFileW +//sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW +//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW +//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW +//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW +//sys SetEndOfFile(handle Handle) (err error) +//sys GetSystemTimeAsFileTime(time *Filetime) +//sys GetSystemTimePreciseAsFileTime(time *Filetime) +//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] +//sys CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) +//sys GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) +//sys PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) +//sys CancelIo(s Handle) (err error) +//sys CancelIoEx(s Handle, o *Overlapped) (err error) +//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW +//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) +//sys TerminateProcess(handle Handle, exitcode uint32) (err error) +//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) +//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW +//sys GetCurrentProcess() (pseudoHandle Handle, err error) +//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) +//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) +//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] +//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW +//sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) +//sys GetFileType(filehandle Handle) (n uint32, err error) +//sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW +//sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext +//sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom +//sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW +//sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW +//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW +//sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW +//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) +//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW +//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW +//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW +//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW +//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW +//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0] +//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) +//sys FlushFileBuffers(handle Handle) (err error) +//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW +//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW +//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW +//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW +//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) +//sys UnmapViewOfFile(addr uintptr) (err error) +//sys FlushViewOfFile(addr uintptr, length uintptr) (err error) +//sys VirtualLock(addr uintptr, length uintptr) (err error) +//sys VirtualUnlock(addr uintptr, length uintptr) (err error) +//sys VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc +//sys VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree +//sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect +//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile +//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW +//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW +//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore +//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore +//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore +//sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore +//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain +//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain +//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext +//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext +//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy +//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW +//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey +//sys RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW +//sys RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW +//sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW +//sys getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId +//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode +//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode +//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo +//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW +//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot +//sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW +//sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW +//sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) +// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. +//sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW +//sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW +//sys GetCurrentThreadId() (id uint32) +//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW +//sys CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateEventExW +//sys OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW +//sys SetEvent(event Handle) (err error) = kernel32.SetEvent +//sys ResetEvent(event Handle) (err error) = kernel32.ResetEvent +//sys PulseEvent(event Handle) (err error) = kernel32.PulseEvent + +// Volume Management Functions +//sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW +//sys DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) = DeleteVolumeMountPointW +//sys FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeW +//sys FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeMountPointW +//sys FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) = FindNextVolumeW +//sys FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW +//sys FindVolumeClose(findVolume Handle) (err error) +//sys FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) +//sys GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW +//sys GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0] +//sys GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW +//sys GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationW +//sys GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW +//sys GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW +//sys GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) = GetVolumePathNameW +//sys GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) = GetVolumePathNamesForVolumeNameW +//sys QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW +//sys SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW +//sys SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW + +// syscall interface implementation for other packages + +// GetProcAddressByOrdinal retrieves the address of the exported +// function from module by ordinal. +func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) { + r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0) + proc = uintptr(r0) + if proc == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Exit(code int) { ExitProcess(uint32(code)) } + +func makeInheritSa() *SecurityAttributes { + var sa SecurityAttributes + sa.Length = uint32(unsafe.Sizeof(sa)) + sa.InheritHandle = 1 + return &sa +} + +func Open(path string, mode int, perm uint32) (fd Handle, err error) { + if len(path) == 0 { + return InvalidHandle, ERROR_FILE_NOT_FOUND + } + pathp, err := UTF16PtrFromString(path) + if err != nil { + return InvalidHandle, err + } + var access uint32 + switch mode & (O_RDONLY | O_WRONLY | O_RDWR) { + case O_RDONLY: + access = GENERIC_READ + case O_WRONLY: + access = GENERIC_WRITE + case O_RDWR: + access = GENERIC_READ | GENERIC_WRITE + } + if mode&O_CREAT != 0 { + access |= GENERIC_WRITE + } + if mode&O_APPEND != 0 { + access &^= GENERIC_WRITE + access |= FILE_APPEND_DATA + } + sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE) + var sa *SecurityAttributes + if mode&O_CLOEXEC == 0 { + sa = makeInheritSa() + } + var createmode uint32 + switch { + case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): + createmode = CREATE_NEW + case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC): + createmode = CREATE_ALWAYS + case mode&O_CREAT == O_CREAT: + createmode = OPEN_ALWAYS + case mode&O_TRUNC == O_TRUNC: + createmode = TRUNCATE_EXISTING + default: + createmode = OPEN_EXISTING + } + h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0) + return h, e +} + +func Read(fd Handle, p []byte) (n int, err error) { + var done uint32 + e := ReadFile(fd, p, &done, nil) + if e != nil { + if e == ERROR_BROKEN_PIPE { + // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin + return 0, nil + } + return 0, e + } + if raceenabled { + if done > 0 { + raceWriteRange(unsafe.Pointer(&p[0]), int(done)) + } + raceAcquire(unsafe.Pointer(&ioSync)) + } + return int(done), nil +} + +func Write(fd Handle, p []byte) (n int, err error) { + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + var done uint32 + e := WriteFile(fd, p, &done, nil) + if e != nil { + return 0, e + } + if raceenabled && done > 0 { + raceReadRange(unsafe.Pointer(&p[0]), int(done)) + } + return int(done), nil +} + +var ioSync int64 + +func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) { + var w uint32 + switch whence { + case 0: + w = FILE_BEGIN + case 1: + w = FILE_CURRENT + case 2: + w = FILE_END + } + hi := int32(offset >> 32) + lo := int32(offset) + // use GetFileType to check pipe, pipe can't do seek + ft, _ := GetFileType(fd) + if ft == FILE_TYPE_PIPE { + return 0, syscall.EPIPE + } + rlo, e := SetFilePointer(fd, lo, &hi, w) + if e != nil { + return 0, e + } + return int64(hi)<<32 + int64(rlo), nil +} + +func Close(fd Handle) (err error) { + return CloseHandle(fd) +} + +var ( + Stdin = getStdHandle(STD_INPUT_HANDLE) + Stdout = getStdHandle(STD_OUTPUT_HANDLE) + Stderr = getStdHandle(STD_ERROR_HANDLE) +) + +func getStdHandle(stdhandle uint32) (fd Handle) { + r, _ := GetStdHandle(stdhandle) + CloseOnExec(r) + return r +} + +const ImplementsGetwd = true + +func Getwd() (wd string, err error) { + b := make([]uint16, 300) + n, e := GetCurrentDirectory(uint32(len(b)), &b[0]) + if e != nil { + return "", e + } + return string(utf16.Decode(b[0:n])), nil +} + +func Chdir(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return SetCurrentDirectory(pathp) +} + +func Mkdir(path string, mode uint32) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return CreateDirectory(pathp, nil) +} + +func Rmdir(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return RemoveDirectory(pathp) +} + +func Unlink(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return DeleteFile(pathp) +} + +func Rename(oldpath, newpath string) (err error) { + from, err := UTF16PtrFromString(oldpath) + if err != nil { + return err + } + to, err := UTF16PtrFromString(newpath) + if err != nil { + return err + } + return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) +} + +func ComputerName() (name string, err error) { + var n uint32 = MAX_COMPUTERNAME_LENGTH + 1 + b := make([]uint16, n) + e := GetComputerName(&b[0], &n) + if e != nil { + return "", e + } + return string(utf16.Decode(b[0:n])), nil +} + +func Ftruncate(fd Handle, length int64) (err error) { + curoffset, e := Seek(fd, 0, 1) + if e != nil { + return e + } + defer Seek(fd, curoffset, 0) + _, e = Seek(fd, length, 0) + if e != nil { + return e + } + e = SetEndOfFile(fd) + if e != nil { + return e + } + return nil +} + +func Gettimeofday(tv *Timeval) (err error) { + var ft Filetime + GetSystemTimeAsFileTime(&ft) + *tv = NsecToTimeval(ft.Nanoseconds()) + return nil +} + +func Pipe(p []Handle) (err error) { + if len(p) != 2 { + return syscall.EINVAL + } + var r, w Handle + e := CreatePipe(&r, &w, makeInheritSa(), 0) + if e != nil { + return e + } + p[0] = r + p[1] = w + return nil +} + +func Utimes(path string, tv []Timeval) (err error) { + if len(tv) != 2 { + return syscall.EINVAL + } + pathp, e := UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := CreateFile(pathp, + FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer Close(h) + a := NsecToFiletime(tv[0].Nanoseconds()) + w := NsecToFiletime(tv[1].Nanoseconds()) + return SetFileTime(h, nil, &a, &w) +} + +func UtimesNano(path string, ts []Timespec) (err error) { + if len(ts) != 2 { + return syscall.EINVAL + } + pathp, e := UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := CreateFile(pathp, + FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer Close(h) + a := NsecToFiletime(TimespecToNsec(ts[0])) + w := NsecToFiletime(TimespecToNsec(ts[1])) + return SetFileTime(h, nil, &a, &w) +} + +func Fsync(fd Handle) (err error) { + return FlushFileBuffers(fd) +} + +func Chmod(path string, mode uint32) (err error) { + if mode == 0 { + return syscall.EINVAL + } + p, e := UTF16PtrFromString(path) + if e != nil { + return e + } + attrs, e := GetFileAttributes(p) + if e != nil { + return e + } + if mode&S_IWRITE != 0 { + attrs &^= FILE_ATTRIBUTE_READONLY + } else { + attrs |= FILE_ATTRIBUTE_READONLY + } + return SetFileAttributes(p, attrs) +} + +func LoadGetSystemTimePreciseAsFileTime() error { + return procGetSystemTimePreciseAsFileTime.Find() +} + +func LoadCancelIoEx() error { + return procCancelIoEx.Find() +} + +func LoadSetFileCompletionNotificationModes() error { + return procSetFileCompletionNotificationModes.Find() +} + +// net api calls + +const socket_error = uintptr(^uint32(0)) + +//sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup +//sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup +//sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl +//sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket +//sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt +//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt +//sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind +//sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect +//sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname +//sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername +//sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen +//sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown +//sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket +//sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx +//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs +//sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv +//sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend +//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom +//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo +//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname +//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname +//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs +//sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname +//sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W +//sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree +//sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W +//sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW +//sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW +//sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry +//sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo +//sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes +//sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW +//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses +//sys GetACP() (acp uint32) = kernel32.GetACP +//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar + +// For testing: clients can set this flag to force +// creation of IPv6 sockets to return EAFNOSUPPORT. +var SocketDisableIPv6 bool + +type RawSockaddrInet4 struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]uint8 +} + +type RawSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddr struct { + Family uint16 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [96]int8 +} + +type Sockaddr interface { + sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs +} + +type SockaddrInet4 struct { + Port int + Addr [4]byte + raw RawSockaddrInet4 +} + +func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_INET + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Addr[i] = sa.Addr[i] + } + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + +type SockaddrInet6 struct { + Port int + ZoneId uint32 + Addr [16]byte + raw RawSockaddrInet6 +} + +func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_INET6 + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + sa.raw.Scope_id = sa.ZoneId + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Addr[i] = sa.Addr[i] + } + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + +type SockaddrUnix struct { + Name string +} + +func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { + // TODO(brainman): implement SockaddrUnix.sockaddr() + return nil, 0, syscall.EWINDOWS +} + +func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { + switch rsa.Addr.Family { + case AF_UNIX: + return nil, syscall.EWINDOWS + + case AF_INET: + pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) + sa := new(SockaddrInet4) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i] + } + return sa, nil + + case AF_INET6: + pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) + sa := new(SockaddrInet6) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + sa.ZoneId = pp.Scope_id + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i] + } + return sa, nil + } + return nil, syscall.EAFNOSUPPORT +} + +func Socket(domain, typ, proto int) (fd Handle, err error) { + if domain == AF_INET6 && SocketDisableIPv6 { + return InvalidHandle, syscall.EAFNOSUPPORT + } + return socket(int32(domain), int32(typ), int32(proto)) +} + +func SetsockoptInt(fd Handle, level, opt int, value int) (err error) { + v := int32(value) + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v))) +} + +func Bind(fd Handle, sa Sockaddr) (err error) { + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return bind(fd, ptr, n) +} + +func Connect(fd Handle, sa Sockaddr) (err error) { + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return connect(fd, ptr, n) +} + +func Getsockname(fd Handle) (sa Sockaddr, err error) { + var rsa RawSockaddrAny + l := int32(unsafe.Sizeof(rsa)) + if err = getsockname(fd, &rsa, &l); err != nil { + return + } + return rsa.Sockaddr() +} + +func Getpeername(fd Handle) (sa Sockaddr, err error) { + var rsa RawSockaddrAny + l := int32(unsafe.Sizeof(rsa)) + if err = getpeername(fd, &rsa, &l); err != nil { + return + } + return rsa.Sockaddr() +} + +func Listen(s Handle, n int) (err error) { + return listen(s, int32(n)) +} + +func Shutdown(fd Handle, how int) (err error) { + return shutdown(fd, int32(how)) +} + +func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) { + rsa, l, err := to.sockaddr() + if err != nil { + return err + } + return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine) +} + +func LoadGetAddrInfo() error { + return procGetAddrInfoW.Find() +} + +var connectExFunc struct { + once sync.Once + addr uintptr + err error +} + +func LoadConnectEx() error { + connectExFunc.once.Do(func() { + var s Handle + s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + if connectExFunc.err != nil { + return + } + defer CloseHandle(s) + var n uint32 + connectExFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)), + uint32(unsafe.Sizeof(WSAID_CONNECTEX)), + (*byte)(unsafe.Pointer(&connectExFunc.addr)), + uint32(unsafe.Sizeof(connectExFunc.addr)), + &n, nil, 0) + }) + return connectExFunc.err +} + +func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error { + err := LoadConnectEx() + if err != nil { + return errorspkg.New("failed to find ConnectEx: " + err.Error()) + } + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped) +} + +var sendRecvMsgFunc struct { + once sync.Once + sendAddr uintptr + recvAddr uintptr + err error +} + +func loadWSASendRecvMsg() error { + sendRecvMsgFunc.once.Do(func() { + var s Handle + s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) + if sendRecvMsgFunc.err != nil { + return + } + defer CloseHandle(s) + var n uint32 + sendRecvMsgFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), + uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), + (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), + uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), + &n, nil, 0) + if sendRecvMsgFunc.err != nil { + return + } + sendRecvMsgFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), + uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), + (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), + uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), + &n, nil, 0) + }) + return sendRecvMsgFunc.err +} + +func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error { + err := loadWSASendRecvMsg() + if err != nil { + return err + } + r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return err +} + +func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error { + err := loadWSASendRecvMsg() + if err != nil { + return err + } + r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return err +} + +// Invented structures to support what package os expects. +type Rusage struct { + CreationTime Filetime + ExitTime Filetime + KernelTime Filetime + UserTime Filetime +} + +type WaitStatus struct { + ExitCode uint32 +} + +func (w WaitStatus) Exited() bool { return true } + +func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) } + +func (w WaitStatus) Signal() Signal { return -1 } + +func (w WaitStatus) CoreDump() bool { return false } + +func (w WaitStatus) Stopped() bool { return false } + +func (w WaitStatus) Continued() bool { return false } + +func (w WaitStatus) StopSignal() Signal { return -1 } + +func (w WaitStatus) Signaled() bool { return false } + +func (w WaitStatus) TrapCause() int { return -1 } + +// Timespec is an invented structure on Windows, but here for +// consistency with the corresponding package for other operating systems. +type Timespec struct { + Sec int64 + Nsec int64 +} + +func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } + +func NsecToTimespec(nsec int64) (ts Timespec) { + ts.Sec = nsec / 1e9 + ts.Nsec = nsec % 1e9 + return +} + +// TODO(brainman): fix all needed for net + +func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS } +func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) { + return 0, nil, syscall.EWINDOWS +} +func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return syscall.EWINDOWS } +func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS } + +// The Linger struct is wrong but we only noticed after Go 1. +// sysLinger is the real system call structure. + +// BUG(brainman): The definition of Linger is not appropriate for direct use +// with Setsockopt and Getsockopt. +// Use SetsockoptLinger instead. + +type Linger struct { + Onoff int32 + Linger int32 +} + +type sysLinger struct { + Onoff uint16 + Linger uint16 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS } + +func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { + sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys))) +} + +func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) +} +func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) +} +func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { + return syscall.EWINDOWS +} + +func Getpid() (pid int) { return int(getCurrentProcessId()) } + +func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) { + // NOTE(rsc): The Win32finddata struct is wrong for the system call: + // the two paths are each one uint16 short. Use the correct struct, + // a win32finddata1, and then copy the results out. + // There is no loss of expressivity here, because the final + // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that. + // For Go 1.1, we might avoid the allocation of win32finddata1 here + // by adding a final Bug [2]uint16 field to the struct and then + // adjusting the fields in the result directly. + var data1 win32finddata1 + handle, err = findFirstFile1(name, &data1) + if err == nil { + copyFindData(data, &data1) + } + return +} + +func FindNextFile(handle Handle, data *Win32finddata) (err error) { + var data1 win32finddata1 + err = findNextFile1(handle, &data1) + if err == nil { + copyFindData(data, &data1) + } + return +} + +func getProcessEntry(pid int) (*ProcessEntry32, error) { + snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) + if err != nil { + return nil, err + } + defer CloseHandle(snapshot) + var procEntry ProcessEntry32 + procEntry.Size = uint32(unsafe.Sizeof(procEntry)) + if err = Process32First(snapshot, &procEntry); err != nil { + return nil, err + } + for { + if procEntry.ProcessID == uint32(pid) { + return &procEntry, nil + } + err = Process32Next(snapshot, &procEntry) + if err != nil { + return nil, err + } + } +} + +func Getppid() (ppid int) { + pe, err := getProcessEntry(Getpid()) + if err != nil { + return -1 + } + return int(pe.ParentProcessID) +} + +// TODO(brainman): fix all needed for os +func Fchdir(fd Handle) (err error) { return syscall.EWINDOWS } +func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS } +func Symlink(path, link string) (err error) { return syscall.EWINDOWS } + +func Fchmod(fd Handle, mode uint32) (err error) { return syscall.EWINDOWS } +func Chown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } +func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } +func Fchown(fd Handle, uid int, gid int) (err error) { return syscall.EWINDOWS } + +func Getuid() (uid int) { return -1 } +func Geteuid() (euid int) { return -1 } +func Getgid() (gid int) { return -1 } +func Getegid() (egid int) { return -1 } +func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS } + +type Signal int + +func (s Signal) Signal() {} + +func (s Signal) String() string { + if 0 <= s && int(s) < len(signals) { + str := signals[s] + if str != "" { + return str + } + } + return "signal " + itoa(int(s)) +} + +func LoadCreateSymbolicLink() error { + return procCreateSymbolicLinkW.Find() +} + +// Readlink returns the destination of the named symbolic link. +func Readlink(path string, buf []byte) (n int, err error) { + fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0) + if err != nil { + return -1, err + } + defer CloseHandle(fd) + + rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE) + var bytesReturned uint32 + err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) + if err != nil { + return -1, err + } + + rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0])) + var s string + switch rdb.ReparseTag { + case IO_REPARSE_TAG_SYMLINK: + data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) + p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) + s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + case IO_REPARSE_TAG_MOUNT_POINT: + data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) + p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) + s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + default: + // the path is not a symlink or junction but another type of reparse + // point + return -1, syscall.ENOENT + } + n = copy(buf, []byte(s)) + + return n, nil +} diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..52c2037b68edb05750eca08ff8233f295caa48c3 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -0,0 +1,1333 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import "syscall" + +const ( + // Windows errors. + ERROR_FILE_NOT_FOUND syscall.Errno = 2 + ERROR_PATH_NOT_FOUND syscall.Errno = 3 + ERROR_ACCESS_DENIED syscall.Errno = 5 + ERROR_NO_MORE_FILES syscall.Errno = 18 + ERROR_HANDLE_EOF syscall.Errno = 38 + ERROR_NETNAME_DELETED syscall.Errno = 64 + ERROR_FILE_EXISTS syscall.Errno = 80 + ERROR_BROKEN_PIPE syscall.Errno = 109 + ERROR_BUFFER_OVERFLOW syscall.Errno = 111 + ERROR_INSUFFICIENT_BUFFER syscall.Errno = 122 + ERROR_MOD_NOT_FOUND syscall.Errno = 126 + ERROR_PROC_NOT_FOUND syscall.Errno = 127 + ERROR_ALREADY_EXISTS syscall.Errno = 183 + ERROR_ENVVAR_NOT_FOUND syscall.Errno = 203 + ERROR_MORE_DATA syscall.Errno = 234 + ERROR_OPERATION_ABORTED syscall.Errno = 995 + ERROR_IO_PENDING syscall.Errno = 997 + ERROR_SERVICE_SPECIFIC_ERROR syscall.Errno = 1066 + ERROR_NOT_FOUND syscall.Errno = 1168 + ERROR_PRIVILEGE_NOT_HELD syscall.Errno = 1314 + WSAEACCES syscall.Errno = 10013 + WSAEMSGSIZE syscall.Errno = 10040 + WSAECONNRESET syscall.Errno = 10054 +) + +const ( + // Invented values to support what package os expects. + O_RDONLY = 0x00000 + O_WRONLY = 0x00001 + O_RDWR = 0x00002 + O_CREAT = 0x00040 + O_EXCL = 0x00080 + O_NOCTTY = 0x00100 + O_TRUNC = 0x00200 + O_NONBLOCK = 0x00800 + O_APPEND = 0x00400 + O_SYNC = 0x01000 + O_ASYNC = 0x02000 + O_CLOEXEC = 0x80000 +) + +const ( + // More invented values for signals + SIGHUP = Signal(0x1) + SIGINT = Signal(0x2) + SIGQUIT = Signal(0x3) + SIGILL = Signal(0x4) + SIGTRAP = Signal(0x5) + SIGABRT = Signal(0x6) + SIGBUS = Signal(0x7) + SIGFPE = Signal(0x8) + SIGKILL = Signal(0x9) + SIGSEGV = Signal(0xb) + SIGPIPE = Signal(0xd) + SIGALRM = Signal(0xe) + SIGTERM = Signal(0xf) +) + +var signals = [...]string{ + 1: "hangup", + 2: "interrupt", + 3: "quit", + 4: "illegal instruction", + 5: "trace/breakpoint trap", + 6: "aborted", + 7: "bus error", + 8: "floating point exception", + 9: "killed", + 10: "user defined signal 1", + 11: "segmentation fault", + 12: "user defined signal 2", + 13: "broken pipe", + 14: "alarm clock", + 15: "terminated", +} + +const ( + GENERIC_READ = 0x80000000 + GENERIC_WRITE = 0x40000000 + GENERIC_EXECUTE = 0x20000000 + GENERIC_ALL = 0x10000000 + + FILE_LIST_DIRECTORY = 0x00000001 + FILE_APPEND_DATA = 0x00000004 + FILE_WRITE_ATTRIBUTES = 0x00000100 + + FILE_SHARE_READ = 0x00000001 + FILE_SHARE_WRITE = 0x00000002 + FILE_SHARE_DELETE = 0x00000004 + FILE_ATTRIBUTE_READONLY = 0x00000001 + FILE_ATTRIBUTE_HIDDEN = 0x00000002 + FILE_ATTRIBUTE_SYSTEM = 0x00000004 + FILE_ATTRIBUTE_DIRECTORY = 0x00000010 + FILE_ATTRIBUTE_ARCHIVE = 0x00000020 + FILE_ATTRIBUTE_NORMAL = 0x00000080 + FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400 + + INVALID_FILE_ATTRIBUTES = 0xffffffff + + CREATE_NEW = 1 + CREATE_ALWAYS = 2 + OPEN_EXISTING = 3 + OPEN_ALWAYS = 4 + TRUNCATE_EXISTING = 5 + + FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000 + FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 + FILE_FLAG_OVERLAPPED = 0x40000000 + + HANDLE_FLAG_INHERIT = 0x00000001 + STARTF_USESTDHANDLES = 0x00000100 + STARTF_USESHOWWINDOW = 0x00000001 + DUPLICATE_CLOSE_SOURCE = 0x00000001 + DUPLICATE_SAME_ACCESS = 0x00000002 + + STD_INPUT_HANDLE = -10 & (1<<32 - 1) + STD_OUTPUT_HANDLE = -11 & (1<<32 - 1) + STD_ERROR_HANDLE = -12 & (1<<32 - 1) + + FILE_BEGIN = 0 + FILE_CURRENT = 1 + FILE_END = 2 + + LANG_ENGLISH = 0x09 + SUBLANG_ENGLISH_US = 0x01 + + FORMAT_MESSAGE_ALLOCATE_BUFFER = 256 + FORMAT_MESSAGE_IGNORE_INSERTS = 512 + FORMAT_MESSAGE_FROM_STRING = 1024 + FORMAT_MESSAGE_FROM_HMODULE = 2048 + FORMAT_MESSAGE_FROM_SYSTEM = 4096 + FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192 + FORMAT_MESSAGE_MAX_WIDTH_MASK = 255 + + MAX_PATH = 260 + MAX_LONG_PATH = 32768 + + MAX_COMPUTERNAME_LENGTH = 15 + + TIME_ZONE_ID_UNKNOWN = 0 + TIME_ZONE_ID_STANDARD = 1 + + TIME_ZONE_ID_DAYLIGHT = 2 + IGNORE = 0 + INFINITE = 0xffffffff + + WAIT_TIMEOUT = 258 + WAIT_ABANDONED = 0x00000080 + WAIT_OBJECT_0 = 0x00000000 + WAIT_FAILED = 0xFFFFFFFF + + PROCESS_TERMINATE = 1 + PROCESS_QUERY_INFORMATION = 0x00000400 + SYNCHRONIZE = 0x00100000 + + FILE_MAP_COPY = 0x01 + FILE_MAP_WRITE = 0x02 + FILE_MAP_READ = 0x04 + FILE_MAP_EXECUTE = 0x20 + + CTRL_C_EVENT = 0 + CTRL_BREAK_EVENT = 1 + + // Windows reserves errors >= 1<<29 for application use. + APPLICATION_ERROR = 1 << 29 +) + +const ( + // Process creation flags. + CREATE_BREAKAWAY_FROM_JOB = 0x01000000 + CREATE_DEFAULT_ERROR_MODE = 0x04000000 + CREATE_NEW_CONSOLE = 0x00000010 + CREATE_NEW_PROCESS_GROUP = 0x00000200 + CREATE_NO_WINDOW = 0x08000000 + CREATE_PROTECTED_PROCESS = 0x00040000 + CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 + CREATE_SEPARATE_WOW_VDM = 0x00000800 + CREATE_SHARED_WOW_VDM = 0x00001000 + CREATE_SUSPENDED = 0x00000004 + CREATE_UNICODE_ENVIRONMENT = 0x00000400 + DEBUG_ONLY_THIS_PROCESS = 0x00000002 + DEBUG_PROCESS = 0x00000001 + DETACHED_PROCESS = 0x00000008 + EXTENDED_STARTUPINFO_PRESENT = 0x00080000 + INHERIT_PARENT_AFFINITY = 0x00010000 +) + +const ( + // flags for CreateToolhelp32Snapshot + TH32CS_SNAPHEAPLIST = 0x01 + TH32CS_SNAPPROCESS = 0x02 + TH32CS_SNAPTHREAD = 0x04 + TH32CS_SNAPMODULE = 0x08 + TH32CS_SNAPMODULE32 = 0x10 + TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD + TH32CS_INHERIT = 0x80000000 +) + +const ( + // filters for ReadDirectoryChangesW + FILE_NOTIFY_CHANGE_FILE_NAME = 0x001 + FILE_NOTIFY_CHANGE_DIR_NAME = 0x002 + FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x004 + FILE_NOTIFY_CHANGE_SIZE = 0x008 + FILE_NOTIFY_CHANGE_LAST_WRITE = 0x010 + FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020 + FILE_NOTIFY_CHANGE_CREATION = 0x040 + FILE_NOTIFY_CHANGE_SECURITY = 0x100 +) + +const ( + // do not reorder + FILE_ACTION_ADDED = iota + 1 + FILE_ACTION_REMOVED + FILE_ACTION_MODIFIED + FILE_ACTION_RENAMED_OLD_NAME + FILE_ACTION_RENAMED_NEW_NAME +) + +const ( + // wincrypt.h + PROV_RSA_FULL = 1 + PROV_RSA_SIG = 2 + PROV_DSS = 3 + PROV_FORTEZZA = 4 + PROV_MS_EXCHANGE = 5 + PROV_SSL = 6 + PROV_RSA_SCHANNEL = 12 + PROV_DSS_DH = 13 + PROV_EC_ECDSA_SIG = 14 + PROV_EC_ECNRA_SIG = 15 + PROV_EC_ECDSA_FULL = 16 + PROV_EC_ECNRA_FULL = 17 + PROV_DH_SCHANNEL = 18 + PROV_SPYRUS_LYNKS = 20 + PROV_RNG = 21 + PROV_INTEL_SEC = 22 + PROV_REPLACE_OWF = 23 + PROV_RSA_AES = 24 + CRYPT_VERIFYCONTEXT = 0xF0000000 + CRYPT_NEWKEYSET = 0x00000008 + CRYPT_DELETEKEYSET = 0x00000010 + CRYPT_MACHINE_KEYSET = 0x00000020 + CRYPT_SILENT = 0x00000040 + CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080 + + USAGE_MATCH_TYPE_AND = 0 + USAGE_MATCH_TYPE_OR = 1 + + X509_ASN_ENCODING = 0x00000001 + PKCS_7_ASN_ENCODING = 0x00010000 + + CERT_STORE_PROV_MEMORY = 2 + + CERT_STORE_ADD_ALWAYS = 4 + + CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004 + + CERT_TRUST_NO_ERROR = 0x00000000 + CERT_TRUST_IS_NOT_TIME_VALID = 0x00000001 + CERT_TRUST_IS_REVOKED = 0x00000004 + CERT_TRUST_IS_NOT_SIGNATURE_VALID = 0x00000008 + CERT_TRUST_IS_NOT_VALID_FOR_USAGE = 0x00000010 + CERT_TRUST_IS_UNTRUSTED_ROOT = 0x00000020 + CERT_TRUST_REVOCATION_STATUS_UNKNOWN = 0x00000040 + CERT_TRUST_IS_CYCLIC = 0x00000080 + CERT_TRUST_INVALID_EXTENSION = 0x00000100 + CERT_TRUST_INVALID_POLICY_CONSTRAINTS = 0x00000200 + CERT_TRUST_INVALID_BASIC_CONSTRAINTS = 0x00000400 + CERT_TRUST_INVALID_NAME_CONSTRAINTS = 0x00000800 + CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000 + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT = 0x00002000 + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000 + CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT = 0x00008000 + CERT_TRUST_IS_OFFLINE_REVOCATION = 0x01000000 + CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY = 0x02000000 + CERT_TRUST_IS_EXPLICIT_DISTRUST = 0x04000000 + CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT = 0x08000000 + + CERT_CHAIN_POLICY_BASE = 1 + CERT_CHAIN_POLICY_AUTHENTICODE = 2 + CERT_CHAIN_POLICY_AUTHENTICODE_TS = 3 + CERT_CHAIN_POLICY_SSL = 4 + CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5 + CERT_CHAIN_POLICY_NT_AUTH = 6 + CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7 + CERT_CHAIN_POLICY_EV = 8 + + CERT_E_EXPIRED = 0x800B0101 + CERT_E_ROLE = 0x800B0103 + CERT_E_PURPOSE = 0x800B0106 + CERT_E_UNTRUSTEDROOT = 0x800B0109 + CERT_E_CN_NO_MATCH = 0x800B010F + + AUTHTYPE_CLIENT = 1 + AUTHTYPE_SERVER = 2 +) + +var ( + OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00") + OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00") + OID_SGC_NETSCAPE = []byte("2.16.840.1.113730.4.1\x00") +) + +// Invented values to support what package os expects. +type Timeval struct { + Sec int32 + Usec int32 +} + +func (tv *Timeval) Nanoseconds() int64 { + return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3 +} + +func NsecToTimeval(nsec int64) (tv Timeval) { + tv.Sec = int32(nsec / 1e9) + tv.Usec = int32(nsec % 1e9 / 1e3) + return +} + +type SecurityAttributes struct { + Length uint32 + SecurityDescriptor uintptr + InheritHandle uint32 +} + +type Overlapped struct { + Internal uintptr + InternalHigh uintptr + Offset uint32 + OffsetHigh uint32 + HEvent Handle +} + +type FileNotifyInformation struct { + NextEntryOffset uint32 + Action uint32 + FileNameLength uint32 + FileName uint16 +} + +type Filetime struct { + LowDateTime uint32 + HighDateTime uint32 +} + +// Nanoseconds returns Filetime ft in nanoseconds +// since Epoch (00:00:00 UTC, January 1, 1970). +func (ft *Filetime) Nanoseconds() int64 { + // 100-nanosecond intervals since January 1, 1601 + nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) + // change starting time to the Epoch (00:00:00 UTC, January 1, 1970) + nsec -= 116444736000000000 + // convert into nanoseconds + nsec *= 100 + return nsec +} + +func NsecToFiletime(nsec int64) (ft Filetime) { + // convert into 100-nanosecond + nsec /= 100 + // change starting time to January 1, 1601 + nsec += 116444736000000000 + // split into high / low + ft.LowDateTime = uint32(nsec & 0xffffffff) + ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff) + return ft +} + +type Win32finddata struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 + Reserved0 uint32 + Reserved1 uint32 + FileName [MAX_PATH - 1]uint16 + AlternateFileName [13]uint16 +} + +// This is the actual system call structure. +// Win32finddata is what we committed to in Go 1. +type win32finddata1 struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 + Reserved0 uint32 + Reserved1 uint32 + FileName [MAX_PATH]uint16 + AlternateFileName [14]uint16 +} + +func copyFindData(dst *Win32finddata, src *win32finddata1) { + dst.FileAttributes = src.FileAttributes + dst.CreationTime = src.CreationTime + dst.LastAccessTime = src.LastAccessTime + dst.LastWriteTime = src.LastWriteTime + dst.FileSizeHigh = src.FileSizeHigh + dst.FileSizeLow = src.FileSizeLow + dst.Reserved0 = src.Reserved0 + dst.Reserved1 = src.Reserved1 + + // The src is 1 element bigger than dst, but it must be NUL. + copy(dst.FileName[:], src.FileName[:]) + copy(dst.AlternateFileName[:], src.AlternateFileName[:]) +} + +type ByHandleFileInformation struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + VolumeSerialNumber uint32 + FileSizeHigh uint32 + FileSizeLow uint32 + NumberOfLinks uint32 + FileIndexHigh uint32 + FileIndexLow uint32 +} + +const ( + GetFileExInfoStandard = 0 + GetFileExMaxInfoLevel = 1 +) + +type Win32FileAttributeData struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 +} + +// ShowWindow constants +const ( + // winuser.h + SW_HIDE = 0 + SW_NORMAL = 1 + SW_SHOWNORMAL = 1 + SW_SHOWMINIMIZED = 2 + SW_SHOWMAXIMIZED = 3 + SW_MAXIMIZE = 3 + SW_SHOWNOACTIVATE = 4 + SW_SHOW = 5 + SW_MINIMIZE = 6 + SW_SHOWMINNOACTIVE = 7 + SW_SHOWNA = 8 + SW_RESTORE = 9 + SW_SHOWDEFAULT = 10 + SW_FORCEMINIMIZE = 11 +) + +type StartupInfo struct { + Cb uint32 + _ *uint16 + Desktop *uint16 + Title *uint16 + X uint32 + Y uint32 + XSize uint32 + YSize uint32 + XCountChars uint32 + YCountChars uint32 + FillAttribute uint32 + Flags uint32 + ShowWindow uint16 + _ uint16 + _ *byte + StdInput Handle + StdOutput Handle + StdErr Handle +} + +type ProcessInformation struct { + Process Handle + Thread Handle + ProcessId uint32 + ThreadId uint32 +} + +type ProcessEntry32 struct { + Size uint32 + Usage uint32 + ProcessID uint32 + DefaultHeapID uintptr + ModuleID uint32 + Threads uint32 + ParentProcessID uint32 + PriClassBase int32 + Flags uint32 + ExeFile [MAX_PATH]uint16 +} + +type Systemtime struct { + Year uint16 + Month uint16 + DayOfWeek uint16 + Day uint16 + Hour uint16 + Minute uint16 + Second uint16 + Milliseconds uint16 +} + +type Timezoneinformation struct { + Bias int32 + StandardName [32]uint16 + StandardDate Systemtime + StandardBias int32 + DaylightName [32]uint16 + DaylightDate Systemtime + DaylightBias int32 +} + +// Socket related. + +const ( + AF_UNSPEC = 0 + AF_UNIX = 1 + AF_INET = 2 + AF_INET6 = 23 + AF_NETBIOS = 17 + + SOCK_STREAM = 1 + SOCK_DGRAM = 2 + SOCK_RAW = 3 + SOCK_SEQPACKET = 5 + + IPPROTO_IP = 0 + IPPROTO_IPV6 = 0x29 + IPPROTO_TCP = 6 + IPPROTO_UDP = 17 + + SOL_SOCKET = 0xffff + SO_REUSEADDR = 4 + SO_KEEPALIVE = 8 + SO_DONTROUTE = 16 + SO_BROADCAST = 32 + SO_LINGER = 128 + SO_RCVBUF = 0x1002 + SO_SNDBUF = 0x1001 + SO_UPDATE_ACCEPT_CONTEXT = 0x700b + SO_UPDATE_CONNECT_CONTEXT = 0x7010 + + IOC_OUT = 0x40000000 + IOC_IN = 0x80000000 + IOC_VENDOR = 0x18000000 + IOC_INOUT = IOC_IN | IOC_OUT + IOC_WS2 = 0x08000000 + SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 + SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 + SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 + + // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 + + IP_TOS = 0x3 + IP_TTL = 0x4 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_TTL = 0xa + IP_MULTICAST_LOOP = 0xb + IP_ADD_MEMBERSHIP = 0xc + IP_DROP_MEMBERSHIP = 0xd + + IPV6_V6ONLY = 0x1b + IPV6_UNICAST_HOPS = 0x4 + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_LOOP = 0xb + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_DONTROUTE = 0x4 + MSG_WAITALL = 0x8 + + MSG_TRUNC = 0x0100 + MSG_CTRUNC = 0x0200 + MSG_BCAST = 0x0400 + MSG_MCAST = 0x0800 + + SOMAXCONN = 0x7fffffff + + TCP_NODELAY = 1 + + SHUT_RD = 0 + SHUT_WR = 1 + SHUT_RDWR = 2 + + WSADESCRIPTION_LEN = 256 + WSASYS_STATUS_LEN = 128 +) + +type WSABuf struct { + Len uint32 + Buf *byte +} + +type WSAMsg struct { + Name *syscall.RawSockaddrAny + Namelen int32 + Buffers *WSABuf + BufferCount uint32 + Control WSABuf + Flags uint32 +} + +// Invented values to support what package os expects. +const ( + S_IFMT = 0x1f000 + S_IFIFO = 0x1000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFBLK = 0x6000 + S_IFREG = 0x8000 + S_IFLNK = 0xa000 + S_IFSOCK = 0xc000 + S_ISUID = 0x800 + S_ISGID = 0x400 + S_ISVTX = 0x200 + S_IRUSR = 0x100 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXUSR = 0x40 +) + +const ( + FILE_TYPE_CHAR = 0x0002 + FILE_TYPE_DISK = 0x0001 + FILE_TYPE_PIPE = 0x0003 + FILE_TYPE_REMOTE = 0x8000 + FILE_TYPE_UNKNOWN = 0x0000 +) + +type Hostent struct { + Name *byte + Aliases **byte + AddrType uint16 + Length uint16 + AddrList **byte +} + +type Protoent struct { + Name *byte + Aliases **byte + Proto uint16 +} + +const ( + DNS_TYPE_A = 0x0001 + DNS_TYPE_NS = 0x0002 + DNS_TYPE_MD = 0x0003 + DNS_TYPE_MF = 0x0004 + DNS_TYPE_CNAME = 0x0005 + DNS_TYPE_SOA = 0x0006 + DNS_TYPE_MB = 0x0007 + DNS_TYPE_MG = 0x0008 + DNS_TYPE_MR = 0x0009 + DNS_TYPE_NULL = 0x000a + DNS_TYPE_WKS = 0x000b + DNS_TYPE_PTR = 0x000c + DNS_TYPE_HINFO = 0x000d + DNS_TYPE_MINFO = 0x000e + DNS_TYPE_MX = 0x000f + DNS_TYPE_TEXT = 0x0010 + DNS_TYPE_RP = 0x0011 + DNS_TYPE_AFSDB = 0x0012 + DNS_TYPE_X25 = 0x0013 + DNS_TYPE_ISDN = 0x0014 + DNS_TYPE_RT = 0x0015 + DNS_TYPE_NSAP = 0x0016 + DNS_TYPE_NSAPPTR = 0x0017 + DNS_TYPE_SIG = 0x0018 + DNS_TYPE_KEY = 0x0019 + DNS_TYPE_PX = 0x001a + DNS_TYPE_GPOS = 0x001b + DNS_TYPE_AAAA = 0x001c + DNS_TYPE_LOC = 0x001d + DNS_TYPE_NXT = 0x001e + DNS_TYPE_EID = 0x001f + DNS_TYPE_NIMLOC = 0x0020 + DNS_TYPE_SRV = 0x0021 + DNS_TYPE_ATMA = 0x0022 + DNS_TYPE_NAPTR = 0x0023 + DNS_TYPE_KX = 0x0024 + DNS_TYPE_CERT = 0x0025 + DNS_TYPE_A6 = 0x0026 + DNS_TYPE_DNAME = 0x0027 + DNS_TYPE_SINK = 0x0028 + DNS_TYPE_OPT = 0x0029 + DNS_TYPE_DS = 0x002B + DNS_TYPE_RRSIG = 0x002E + DNS_TYPE_NSEC = 0x002F + DNS_TYPE_DNSKEY = 0x0030 + DNS_TYPE_DHCID = 0x0031 + DNS_TYPE_UINFO = 0x0064 + DNS_TYPE_UID = 0x0065 + DNS_TYPE_GID = 0x0066 + DNS_TYPE_UNSPEC = 0x0067 + DNS_TYPE_ADDRS = 0x00f8 + DNS_TYPE_TKEY = 0x00f9 + DNS_TYPE_TSIG = 0x00fa + DNS_TYPE_IXFR = 0x00fb + DNS_TYPE_AXFR = 0x00fc + DNS_TYPE_MAILB = 0x00fd + DNS_TYPE_MAILA = 0x00fe + DNS_TYPE_ALL = 0x00ff + DNS_TYPE_ANY = 0x00ff + DNS_TYPE_WINS = 0xff01 + DNS_TYPE_WINSR = 0xff02 + DNS_TYPE_NBSTAT = 0xff01 +) + +const ( + DNS_INFO_NO_RECORDS = 0x251D +) + +const ( + // flags inside DNSRecord.Dw + DnsSectionQuestion = 0x0000 + DnsSectionAnswer = 0x0001 + DnsSectionAuthority = 0x0002 + DnsSectionAdditional = 0x0003 +) + +type DNSSRVData struct { + Target *uint16 + Priority uint16 + Weight uint16 + Port uint16 + Pad uint16 +} + +type DNSPTRData struct { + Host *uint16 +} + +type DNSMXData struct { + NameExchange *uint16 + Preference uint16 + Pad uint16 +} + +type DNSTXTData struct { + StringCount uint16 + StringArray [1]*uint16 +} + +type DNSRecord struct { + Next *DNSRecord + Name *uint16 + Type uint16 + Length uint16 + Dw uint32 + Ttl uint32 + Reserved uint32 + Data [40]byte +} + +const ( + TF_DISCONNECT = 1 + TF_REUSE_SOCKET = 2 + TF_WRITE_BEHIND = 4 + TF_USE_DEFAULT_WORKER = 0 + TF_USE_SYSTEM_THREAD = 16 + TF_USE_KERNEL_APC = 32 +) + +type TransmitFileBuffers struct { + Head uintptr + HeadLength uint32 + Tail uintptr + TailLength uint32 +} + +const ( + IFF_UP = 1 + IFF_BROADCAST = 2 + IFF_LOOPBACK = 4 + IFF_POINTTOPOINT = 8 + IFF_MULTICAST = 16 +) + +const SIO_GET_INTERFACE_LIST = 0x4004747F + +// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old. +// will be fixed to change variable type as suitable. + +type SockaddrGen [24]byte + +type InterfaceInfo struct { + Flags uint32 + Address SockaddrGen + BroadcastAddress SockaddrGen + Netmask SockaddrGen +} + +type IpAddressString struct { + String [16]byte +} + +type IpMaskString IpAddressString + +type IpAddrString struct { + Next *IpAddrString + IpAddress IpAddressString + IpMask IpMaskString + Context uint32 +} + +const MAX_ADAPTER_NAME_LENGTH = 256 +const MAX_ADAPTER_DESCRIPTION_LENGTH = 128 +const MAX_ADAPTER_ADDRESS_LENGTH = 8 + +type IpAdapterInfo struct { + Next *IpAdapterInfo + ComboIndex uint32 + AdapterName [MAX_ADAPTER_NAME_LENGTH + 4]byte + Description [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte + AddressLength uint32 + Address [MAX_ADAPTER_ADDRESS_LENGTH]byte + Index uint32 + Type uint32 + DhcpEnabled uint32 + CurrentIpAddress *IpAddrString + IpAddressList IpAddrString + GatewayList IpAddrString + DhcpServer IpAddrString + HaveWins bool + PrimaryWinsServer IpAddrString + SecondaryWinsServer IpAddrString + LeaseObtained int64 + LeaseExpires int64 +} + +const MAXLEN_PHYSADDR = 8 +const MAX_INTERFACE_NAME_LEN = 256 +const MAXLEN_IFDESCR = 256 + +type MibIfRow struct { + Name [MAX_INTERFACE_NAME_LEN]uint16 + Index uint32 + Type uint32 + Mtu uint32 + Speed uint32 + PhysAddrLen uint32 + PhysAddr [MAXLEN_PHYSADDR]byte + AdminStatus uint32 + OperStatus uint32 + LastChange uint32 + InOctets uint32 + InUcastPkts uint32 + InNUcastPkts uint32 + InDiscards uint32 + InErrors uint32 + InUnknownProtos uint32 + OutOctets uint32 + OutUcastPkts uint32 + OutNUcastPkts uint32 + OutDiscards uint32 + OutErrors uint32 + OutQLen uint32 + DescrLen uint32 + Descr [MAXLEN_IFDESCR]byte +} + +type CertContext struct { + EncodingType uint32 + EncodedCert *byte + Length uint32 + CertInfo uintptr + Store Handle +} + +type CertChainContext struct { + Size uint32 + TrustStatus CertTrustStatus + ChainCount uint32 + Chains **CertSimpleChain + LowerQualityChainCount uint32 + LowerQualityChains **CertChainContext + HasRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 +} + +type CertSimpleChain struct { + Size uint32 + TrustStatus CertTrustStatus + NumElements uint32 + Elements **CertChainElement + TrustListInfo uintptr + HasRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 +} + +type CertChainElement struct { + Size uint32 + CertContext *CertContext + TrustStatus CertTrustStatus + RevocationInfo *CertRevocationInfo + IssuanceUsage *CertEnhKeyUsage + ApplicationUsage *CertEnhKeyUsage + ExtendedErrorInfo *uint16 +} + +type CertRevocationInfo struct { + Size uint32 + RevocationResult uint32 + RevocationOid *byte + OidSpecificInfo uintptr + HasFreshnessTime uint32 + FreshnessTime uint32 + CrlInfo uintptr // *CertRevocationCrlInfo +} + +type CertTrustStatus struct { + ErrorStatus uint32 + InfoStatus uint32 +} + +type CertUsageMatch struct { + Type uint32 + Usage CertEnhKeyUsage +} + +type CertEnhKeyUsage struct { + Length uint32 + UsageIdentifiers **byte +} + +type CertChainPara struct { + Size uint32 + RequestedUsage CertUsageMatch + RequstedIssuancePolicy CertUsageMatch + URLRetrievalTimeout uint32 + CheckRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 + CacheResync *Filetime +} + +type CertChainPolicyPara struct { + Size uint32 + Flags uint32 + ExtraPolicyPara uintptr +} + +type SSLExtraCertChainPolicyPara struct { + Size uint32 + AuthType uint32 + Checks uint32 + ServerName *uint16 +} + +type CertChainPolicyStatus struct { + Size uint32 + Error uint32 + ChainIndex uint32 + ElementIndex uint32 + ExtraPolicyStatus uintptr +} + +const ( + // do not reorder + HKEY_CLASSES_ROOT = 0x80000000 + iota + HKEY_CURRENT_USER + HKEY_LOCAL_MACHINE + HKEY_USERS + HKEY_PERFORMANCE_DATA + HKEY_CURRENT_CONFIG + HKEY_DYN_DATA + + KEY_QUERY_VALUE = 1 + KEY_SET_VALUE = 2 + KEY_CREATE_SUB_KEY = 4 + KEY_ENUMERATE_SUB_KEYS = 8 + KEY_NOTIFY = 16 + KEY_CREATE_LINK = 32 + KEY_WRITE = 0x20006 + KEY_EXECUTE = 0x20019 + KEY_READ = 0x20019 + KEY_WOW64_64KEY = 0x0100 + KEY_WOW64_32KEY = 0x0200 + KEY_ALL_ACCESS = 0xf003f +) + +const ( + // do not reorder + REG_NONE = iota + REG_SZ + REG_EXPAND_SZ + REG_BINARY + REG_DWORD_LITTLE_ENDIAN + REG_DWORD_BIG_ENDIAN + REG_LINK + REG_MULTI_SZ + REG_RESOURCE_LIST + REG_FULL_RESOURCE_DESCRIPTOR + REG_RESOURCE_REQUIREMENTS_LIST + REG_QWORD_LITTLE_ENDIAN + REG_DWORD = REG_DWORD_LITTLE_ENDIAN + REG_QWORD = REG_QWORD_LITTLE_ENDIAN +) + +type AddrinfoW struct { + Flags int32 + Family int32 + Socktype int32 + Protocol int32 + Addrlen uintptr + Canonname *uint16 + Addr uintptr + Next *AddrinfoW +} + +const ( + AI_PASSIVE = 1 + AI_CANONNAME = 2 + AI_NUMERICHOST = 4 +) + +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +var WSAID_CONNECTEX = GUID{ + 0x25a207b9, + 0xddf3, + 0x4660, + [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}, +} + +var WSAID_WSASENDMSG = GUID{ + 0xa441e712, + 0x754f, + 0x43ca, + [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}, +} + +var WSAID_WSARECVMSG = GUID{ + 0xf689d7c8, + 0x6f1f, + 0x436b, + [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}, +} + +const ( + FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 + FILE_SKIP_SET_EVENT_ON_HANDLE = 2 +) + +const ( + WSAPROTOCOL_LEN = 255 + MAX_PROTOCOL_CHAIN = 7 + BASE_PROTOCOL = 1 + LAYERED_PROTOCOL = 0 + + XP1_CONNECTIONLESS = 0x00000001 + XP1_GUARANTEED_DELIVERY = 0x00000002 + XP1_GUARANTEED_ORDER = 0x00000004 + XP1_MESSAGE_ORIENTED = 0x00000008 + XP1_PSEUDO_STREAM = 0x00000010 + XP1_GRACEFUL_CLOSE = 0x00000020 + XP1_EXPEDITED_DATA = 0x00000040 + XP1_CONNECT_DATA = 0x00000080 + XP1_DISCONNECT_DATA = 0x00000100 + XP1_SUPPORT_BROADCAST = 0x00000200 + XP1_SUPPORT_MULTIPOINT = 0x00000400 + XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800 + XP1_MULTIPOINT_DATA_PLANE = 0x00001000 + XP1_QOS_SUPPORTED = 0x00002000 + XP1_UNI_SEND = 0x00008000 + XP1_UNI_RECV = 0x00010000 + XP1_IFS_HANDLES = 0x00020000 + XP1_PARTIAL_MESSAGE = 0x00040000 + XP1_SAN_SUPPORT_SDP = 0x00080000 + + PFL_MULTIPLE_PROTO_ENTRIES = 0x00000001 + PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002 + PFL_HIDDEN = 0x00000004 + PFL_MATCHES_PROTOCOL_ZERO = 0x00000008 + PFL_NETWORKDIRECT_PROVIDER = 0x00000010 +) + +type WSAProtocolInfo struct { + ServiceFlags1 uint32 + ServiceFlags2 uint32 + ServiceFlags3 uint32 + ServiceFlags4 uint32 + ProviderFlags uint32 + ProviderId GUID + CatalogEntryId uint32 + ProtocolChain WSAProtocolChain + Version int32 + AddressFamily int32 + MaxSockAddr int32 + MinSockAddr int32 + SocketType int32 + Protocol int32 + ProtocolMaxOffset int32 + NetworkByteOrder int32 + SecurityScheme int32 + MessageSize uint32 + ProviderReserved uint32 + ProtocolName [WSAPROTOCOL_LEN + 1]uint16 +} + +type WSAProtocolChain struct { + ChainLen int32 + ChainEntries [MAX_PROTOCOL_CHAIN]uint32 +} + +type TCPKeepalive struct { + OnOff uint32 + Time uint32 + Interval uint32 +} + +type symbolicLinkReparseBuffer struct { + SubstituteNameOffset uint16 + SubstituteNameLength uint16 + PrintNameOffset uint16 + PrintNameLength uint16 + Flags uint32 + PathBuffer [1]uint16 +} + +type mountPointReparseBuffer struct { + SubstituteNameOffset uint16 + SubstituteNameLength uint16 + PrintNameOffset uint16 + PrintNameLength uint16 + PathBuffer [1]uint16 +} + +type reparseDataBuffer struct { + ReparseTag uint32 + ReparseDataLength uint16 + Reserved uint16 + + // GenericReparseBuffer + reparseBuffer byte +} + +const ( + FSCTL_GET_REPARSE_POINT = 0x900A8 + MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024 + IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 + IO_REPARSE_TAG_SYMLINK = 0xA000000C + SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 +) + +const ( + ComputerNameNetBIOS = 0 + ComputerNameDnsHostname = 1 + ComputerNameDnsDomain = 2 + ComputerNameDnsFullyQualified = 3 + ComputerNamePhysicalNetBIOS = 4 + ComputerNamePhysicalDnsHostname = 5 + ComputerNamePhysicalDnsDomain = 6 + ComputerNamePhysicalDnsFullyQualified = 7 + ComputerNameMax = 8 +) + +const ( + MOVEFILE_REPLACE_EXISTING = 0x1 + MOVEFILE_COPY_ALLOWED = 0x2 + MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 + MOVEFILE_WRITE_THROUGH = 0x8 + MOVEFILE_CREATE_HARDLINK = 0x10 + MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 +) + +const GAA_FLAG_INCLUDE_PREFIX = 0x00000010 + +const ( + IF_TYPE_OTHER = 1 + IF_TYPE_ETHERNET_CSMACD = 6 + IF_TYPE_ISO88025_TOKENRING = 9 + IF_TYPE_PPP = 23 + IF_TYPE_SOFTWARE_LOOPBACK = 24 + IF_TYPE_ATM = 37 + IF_TYPE_IEEE80211 = 71 + IF_TYPE_TUNNEL = 131 + IF_TYPE_IEEE1394 = 144 +) + +type SocketAddress struct { + Sockaddr *syscall.RawSockaddrAny + SockaddrLength int32 +} + +type IpAdapterUnicastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterUnicastAddress + Address SocketAddress + PrefixOrigin int32 + SuffixOrigin int32 + DadState int32 + ValidLifetime uint32 + PreferredLifetime uint32 + LeaseLifetime uint32 + OnLinkPrefixLength uint8 +} + +type IpAdapterAnycastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterAnycastAddress + Address SocketAddress +} + +type IpAdapterMulticastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterMulticastAddress + Address SocketAddress +} + +type IpAdapterDnsServerAdapter struct { + Length uint32 + Reserved uint32 + Next *IpAdapterDnsServerAdapter + Address SocketAddress +} + +type IpAdapterPrefix struct { + Length uint32 + Flags uint32 + Next *IpAdapterPrefix + Address SocketAddress + PrefixLength uint32 +} + +type IpAdapterAddresses struct { + Length uint32 + IfIndex uint32 + Next *IpAdapterAddresses + AdapterName *byte + FirstUnicastAddress *IpAdapterUnicastAddress + FirstAnycastAddress *IpAdapterAnycastAddress + FirstMulticastAddress *IpAdapterMulticastAddress + FirstDnsServerAddress *IpAdapterDnsServerAdapter + DnsSuffix *uint16 + Description *uint16 + FriendlyName *uint16 + PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte + PhysicalAddressLength uint32 + Flags uint32 + Mtu uint32 + IfType uint32 + OperStatus uint32 + Ipv6IfIndex uint32 + ZoneIndices [16]uint32 + FirstPrefix *IpAdapterPrefix + /* more fields might be present here. */ +} + +const ( + IfOperStatusUp = 1 + IfOperStatusDown = 2 + IfOperStatusTesting = 3 + IfOperStatusUnknown = 4 + IfOperStatusDormant = 5 + IfOperStatusNotPresent = 6 + IfOperStatusLowerLayerDown = 7 +) + +// Console related constants used for the mode parameter to SetConsoleMode. See +// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details. + +const ( + ENABLE_PROCESSED_INPUT = 0x1 + ENABLE_LINE_INPUT = 0x2 + ENABLE_ECHO_INPUT = 0x4 + ENABLE_WINDOW_INPUT = 0x8 + ENABLE_MOUSE_INPUT = 0x10 + ENABLE_INSERT_MODE = 0x20 + ENABLE_QUICK_EDIT_MODE = 0x40 + ENABLE_EXTENDED_FLAGS = 0x80 + ENABLE_AUTO_POSITION = 0x100 + ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200 + + ENABLE_PROCESSED_OUTPUT = 0x1 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x2 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 + DISABLE_NEWLINE_AUTO_RETURN = 0x8 + ENABLE_LVB_GRID_WORLDWIDE = 0x10 +) + +type Coord struct { + X int16 + Y int16 +} + +type SmallRect struct { + Left int16 + Top int16 + Right int16 + Bottom int16 +} + +// Used with GetConsoleScreenBuffer to retreive information about a console +// screen buffer. See +// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str +// for details. + +type ConsoleScreenBufferInfo struct { + Size Coord + CursorPosition Coord + Attributes uint16 + Window SmallRect + MaximumWindowSize Coord +} diff --git a/vendor/golang.org/x/sys/windows/types_windows_386.go b/vendor/golang.org/x/sys/windows/types_windows_386.go new file mode 100644 index 0000000000000000000000000000000000000000..fe0ddd0316019285881af8d34dcda8138f9c86d4 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows_386.go @@ -0,0 +1,22 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +type WSAData struct { + Version uint16 + HighVersion uint16 + Description [WSADESCRIPTION_LEN + 1]byte + SystemStatus [WSASYS_STATUS_LEN + 1]byte + MaxSockets uint16 + MaxUdpDg uint16 + VendorInfo *byte +} + +type Servent struct { + Name *byte + Aliases **byte + Port uint16 + Proto *byte +} diff --git a/vendor/golang.org/x/sys/windows/types_windows_amd64.go b/vendor/golang.org/x/sys/windows/types_windows_amd64.go new file mode 100644 index 0000000000000000000000000000000000000000..7e154c2df2df6cc56597e45cceec0d84ac975980 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows_amd64.go @@ -0,0 +1,22 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +type WSAData struct { + Version uint16 + HighVersion uint16 + MaxSockets uint16 + MaxUdpDg uint16 + VendorInfo *byte + Description [WSADESCRIPTION_LEN + 1]byte + SystemStatus [WSASYS_STATUS_LEN + 1]byte +} + +type Servent struct { + Name *byte + Aliases **byte + Proto *byte + Port uint16 +} diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go new file mode 100644 index 0000000000000000000000000000000000000000..c7b3b15eadb9211c1c1d9067293e4d14426c6cf0 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -0,0 +1,2687 @@ +// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT + +package windows + +import ( + "syscall" + "unsafe" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return nil + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modadvapi32 = NewLazySystemDLL("advapi32.dll") + modkernel32 = NewLazySystemDLL("kernel32.dll") + modshell32 = NewLazySystemDLL("shell32.dll") + modmswsock = NewLazySystemDLL("mswsock.dll") + modcrypt32 = NewLazySystemDLL("crypt32.dll") + modws2_32 = NewLazySystemDLL("ws2_32.dll") + moddnsapi = NewLazySystemDLL("dnsapi.dll") + modiphlpapi = NewLazySystemDLL("iphlpapi.dll") + modsecur32 = NewLazySystemDLL("secur32.dll") + modnetapi32 = NewLazySystemDLL("netapi32.dll") + moduserenv = NewLazySystemDLL("userenv.dll") + + procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") + procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") + procReportEventW = modadvapi32.NewProc("ReportEventW") + procOpenSCManagerW = modadvapi32.NewProc("OpenSCManagerW") + procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") + procCreateServiceW = modadvapi32.NewProc("CreateServiceW") + procOpenServiceW = modadvapi32.NewProc("OpenServiceW") + procDeleteService = modadvapi32.NewProc("DeleteService") + procStartServiceW = modadvapi32.NewProc("StartServiceW") + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procControlService = modadvapi32.NewProc("ControlService") + procStartServiceCtrlDispatcherW = modadvapi32.NewProc("StartServiceCtrlDispatcherW") + procSetServiceStatus = modadvapi32.NewProc("SetServiceStatus") + procChangeServiceConfigW = modadvapi32.NewProc("ChangeServiceConfigW") + procQueryServiceConfigW = modadvapi32.NewProc("QueryServiceConfigW") + procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W") + procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W") + procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") + procGetLastError = modkernel32.NewProc("GetLastError") + procLoadLibraryW = modkernel32.NewProc("LoadLibraryW") + procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") + procFreeLibrary = modkernel32.NewProc("FreeLibrary") + procGetProcAddress = modkernel32.NewProc("GetProcAddress") + procGetVersion = modkernel32.NewProc("GetVersion") + procFormatMessageW = modkernel32.NewProc("FormatMessageW") + procExitProcess = modkernel32.NewProc("ExitProcess") + procCreateFileW = modkernel32.NewProc("CreateFileW") + procReadFile = modkernel32.NewProc("ReadFile") + procWriteFile = modkernel32.NewProc("WriteFile") + procSetFilePointer = modkernel32.NewProc("SetFilePointer") + procCloseHandle = modkernel32.NewProc("CloseHandle") + procGetStdHandle = modkernel32.NewProc("GetStdHandle") + procSetStdHandle = modkernel32.NewProc("SetStdHandle") + procFindFirstFileW = modkernel32.NewProc("FindFirstFileW") + procFindNextFileW = modkernel32.NewProc("FindNextFileW") + procFindClose = modkernel32.NewProc("FindClose") + procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle") + procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") + procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") + procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW") + procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") + procDeleteFileW = modkernel32.NewProc("DeleteFileW") + procMoveFileW = modkernel32.NewProc("MoveFileW") + procMoveFileExW = modkernel32.NewProc("MoveFileExW") + procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") + procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") + procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime") + procGetSystemTimePreciseAsFileTime = modkernel32.NewProc("GetSystemTimePreciseAsFileTime") + procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") + procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") + procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus") + procCancelIo = modkernel32.NewProc("CancelIo") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procCreateProcessW = modkernel32.NewProc("CreateProcessW") + procOpenProcess = modkernel32.NewProc("OpenProcess") + procTerminateProcess = modkernel32.NewProc("TerminateProcess") + procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") + procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") + procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess") + procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") + procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") + procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") + procGetTempPathW = modkernel32.NewProc("GetTempPathW") + procCreatePipe = modkernel32.NewProc("CreatePipe") + procGetFileType = modkernel32.NewProc("GetFileType") + procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW") + procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext") + procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom") + procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW") + procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW") + procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW") + procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") + procSetFileTime = modkernel32.NewProc("SetFileTime") + procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW") + procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW") + procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW") + procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") + procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") + procLocalFree = modkernel32.NewProc("LocalFree") + procSetHandleInformation = modkernel32.NewProc("SetHandleInformation") + procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") + procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") + procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW") + procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW") + procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW") + procMapViewOfFile = modkernel32.NewProc("MapViewOfFile") + procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile") + procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") + procVirtualLock = modkernel32.NewProc("VirtualLock") + procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") + procVirtualAlloc = modkernel32.NewProc("VirtualAlloc") + procVirtualFree = modkernel32.NewProc("VirtualFree") + procVirtualProtect = modkernel32.NewProc("VirtualProtect") + procTransmitFile = modmswsock.NewProc("TransmitFile") + procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW") + procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") + procCertOpenStore = modcrypt32.NewProc("CertOpenStore") + procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") + procCertAddCertificateContextToStore = modcrypt32.NewProc("CertAddCertificateContextToStore") + procCertCloseStore = modcrypt32.NewProc("CertCloseStore") + procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain") + procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") + procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext") + procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext") + procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") + procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW") + procRegCloseKey = modadvapi32.NewProc("RegCloseKey") + procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") + procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") + procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") + procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") + procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") + procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") + procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") + procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") + procReadConsoleW = modkernel32.NewProc("ReadConsoleW") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") + procProcess32FirstW = modkernel32.NewProc("Process32FirstW") + procProcess32NextW = modkernel32.NewProc("Process32NextW") + procDeviceIoControl = modkernel32.NewProc("DeviceIoControl") + procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW") + procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW") + procGetCurrentThreadId = modkernel32.NewProc("GetCurrentThreadId") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateEventExW = modkernel32.NewProc("CreateEventExW") + procOpenEventW = modkernel32.NewProc("OpenEventW") + procSetEvent = modkernel32.NewProc("SetEvent") + procResetEvent = modkernel32.NewProc("ResetEvent") + procPulseEvent = modkernel32.NewProc("PulseEvent") + procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW") + procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW") + procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procFindFirstVolumeMountPointW = modkernel32.NewProc("FindFirstVolumeMountPointW") + procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") + procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW") + procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") + procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") + procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") + procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") + procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW") + procGetVolumeInformationByHandleW = modkernel32.NewProc("GetVolumeInformationByHandleW") + procGetVolumeNameForVolumeMountPointW = modkernel32.NewProc("GetVolumeNameForVolumeMountPointW") + procGetVolumePathNameW = modkernel32.NewProc("GetVolumePathNameW") + procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") + procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW") + procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW") + procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW") + procWSAStartup = modws2_32.NewProc("WSAStartup") + procWSACleanup = modws2_32.NewProc("WSACleanup") + procWSAIoctl = modws2_32.NewProc("WSAIoctl") + procsocket = modws2_32.NewProc("socket") + procsetsockopt = modws2_32.NewProc("setsockopt") + procgetsockopt = modws2_32.NewProc("getsockopt") + procbind = modws2_32.NewProc("bind") + procconnect = modws2_32.NewProc("connect") + procgetsockname = modws2_32.NewProc("getsockname") + procgetpeername = modws2_32.NewProc("getpeername") + proclisten = modws2_32.NewProc("listen") + procshutdown = modws2_32.NewProc("shutdown") + procclosesocket = modws2_32.NewProc("closesocket") + procAcceptEx = modmswsock.NewProc("AcceptEx") + procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs") + procWSARecv = modws2_32.NewProc("WSARecv") + procWSASend = modws2_32.NewProc("WSASend") + procWSARecvFrom = modws2_32.NewProc("WSARecvFrom") + procWSASendTo = modws2_32.NewProc("WSASendTo") + procgethostbyname = modws2_32.NewProc("gethostbyname") + procgetservbyname = modws2_32.NewProc("getservbyname") + procntohs = modws2_32.NewProc("ntohs") + procgetprotobyname = modws2_32.NewProc("getprotobyname") + procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") + procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") + procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") + procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") + procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") + procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") + procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") + procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procGetACP = modkernel32.NewProc("GetACP") + procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") + procTranslateNameW = modsecur32.NewProc("TranslateNameW") + procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") + procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") + procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") + procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree") + procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") + procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") + procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") + procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") + procGetLengthSid = modadvapi32.NewProc("GetLengthSid") + procCopySid = modadvapi32.NewProc("CopySid") + procAllocateAndInitializeSid = modadvapi32.NewProc("AllocateAndInitializeSid") + procFreeSid = modadvapi32.NewProc("FreeSid") + procEqualSid = modadvapi32.NewProc("EqualSid") + procCheckTokenMembership = modadvapi32.NewProc("CheckTokenMembership") + procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") + procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") + procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") +) + +func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeregisterEventSource(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CloseServiceHandle(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeleteService(service Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { + r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { + r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { + r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { + r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { + r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLastError() (lasterr error) { + r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) + if r0 != 0 { + lasterr = syscall.Errno(r0) + } + return +} + +func LoadLibrary(libname string) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return + } + return _LoadLibrary(_p0) +} + +func _LoadLibrary(libname *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return + } + return _LoadLibraryEx(_p0, zero, flags) +} + +func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FreeLibrary(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(procname) + if err != nil { + return + } + return _GetProcAddress(module, _p0) +} + +func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { + r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0) + proc = uintptr(r0) + if proc == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVersion() (ver uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0) + ver = uint32(r0) + if ver == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { + var _p0 *uint16 + if len(buf) > 0 { + _p0 = &buf[0] + } + r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ExitProcess(exitcode uint32) { + syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) + return +} + +func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { + r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0) + newlowoffset = uint32(r0) + if newlowoffset == 0xffffffff { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CloseHandle(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetStdHandle(stdhandle uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetStdHandle(stdhandle uint32, handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func findNextFile1(handle Handle, data *win32finddata1) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindClose(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { + r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetCurrentDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { + r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func RemoveDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeleteFile(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func MoveFile(from *uint16, to *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetComputerName(buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetEndOfFile(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetSystemTimeAsFileTime(time *Filetime) { + syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + return +} + +func GetSystemTimePreciseAsFileTime(time *Filetime) { + syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + return +} + +func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0) + rc = uint32(r0) + if rc == 0xffffffff { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CancelIo(s Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CancelIoEx(s Handle, o *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { + var _p0 uint32 + if inheritHandles { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } else { + _p0 = 0 + } + r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func TerminateProcess(handle Handle, exitcode uint32) (err error) { + r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetStartupInfo(startupInfo *StartupInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCurrentProcess() (pseudoHandle Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0) + pseudoHandle = Handle(r0) + if pseudoHandle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { + r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { + var _p0 uint32 + if bInheritHandle { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { + r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0) + event = uint32(r0) + if event == 0xffffffff { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileType(filehandle Handle) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { + r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetEnvironmentStrings() (envs *uint16, err error) { + r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0) + envs = (*uint16)(unsafe.Pointer(r0)) + if envs == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FreeEnvironmentStrings(envs *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { + r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileAttributes(name *uint16) (attrs uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + attrs = uint32(r0) + if attrs == INVALID_FILE_ATTRIBUTES { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetFileAttributes(name *uint16, attrs uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { + r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCommandLine() (cmd *uint16) { + r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) + cmd = (*uint16)(unsafe.Pointer(r0)) + return +} + +func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { + r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) + argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0)) + if argv == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func LocalFree(hmem Handle) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0) + handle = Handle(r0) + if handle != 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FlushFileBuffers(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { + r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0) + addr = uintptr(r0) + if addr == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func UnmapViewOfFile(addr uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FlushViewOfFile(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualLock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualUnlock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { + r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0) + value = uintptr(r0) + if value == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + var _p0 uint32 + if watchSubTree { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { + r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0) + store = Handle(r0) + if store == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { + r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { + r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertCloseStore(store Handle, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { + r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertFreeCertificateChain(ctx *CertChainContext) { + syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + return +} + +func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { + r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertFreeCertificateContext(ctx *CertContext) (err error) { + r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { + r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegCloseKey(key Handle) (regerrno error) { + r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func getCurrentProcessId() (pid uint32) { + r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) + pid = uint32(r0) + return +} + +func GetConsoleMode(console Handle, mode *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetConsoleMode(console Handle, mode uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { + r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { + r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCurrentThreadId() (id uint32) { + r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0) + id = uint32(r0) + return +} + +func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } else { + _p0 = 0 + } + r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ResetEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func PulseEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindVolumeClose(findVolume Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetDriveType(rootPathName *uint16) (driveType uint32) { + r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) + driveType = uint32(r0) + return +} + +func GetLogicalDrives() (drivesBitMask uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0) + drivesBitMask = uint32(r0) + if drivesBitMask == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procGetVolumeInformationByHandleW.Addr(), 8, uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetVolumeNameForVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetVolumePathNameW.Addr(), 3, uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { + r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) + if r0 != 0 { + sockerr = syscall.Errno(r0) + } + return +} + +func WSACleanup() (err error) { + r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol)) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { + r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { + r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func listen(s Handle, backlog int32) (err error) { + r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func shutdown(s Handle, how int32) (err error) { + r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Closesocket(s Handle) (err error) { + r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { + syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) + return +} + +func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetHostByName(name string) (h *Hostent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + return _GetHostByName(_p0) +} + +func _GetHostByName(name *byte) (h *Hostent, err error) { + r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + h = (*Hostent)(unsafe.Pointer(r0)) + if h == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetServByName(name string, proto string) (s *Servent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + var _p1 *byte + _p1, err = syscall.BytePtrFromString(proto) + if err != nil { + return + } + return _GetServByName(_p0, _p1) +} + +func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { + r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0) + s = (*Servent)(unsafe.Pointer(r0)) + if s == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Ntohs(netshort uint16) (u uint16) { + r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0) + u = uint16(r0) + return +} + +func GetProtoByName(name string) (p *Protoent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + return _GetProtoByName(_p0) +} + +func _GetProtoByName(name *byte) (p *Protoent, err error) { + r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + p = (*Protoent)(unsafe.Pointer(r0)) + if p == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + var _p0 *uint16 + _p0, status = syscall.UTF16PtrFromString(name) + if status != nil { + return + } + return _DnsQuery(_p0, qtype, options, extra, qrs, pr) +} + +func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) + if r0 != 0 { + status = syscall.Errno(r0) + } + return +} + +func DnsRecordListFree(rl *DNSRecord, freetype uint32) { + syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0) + return +} + +func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { + r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) + same = r0 != 0 + return +} + +func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { + r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0) + if r0 != 0 { + sockerr = syscall.Errno(r0) + } + return +} + +func FreeAddrInfoW(addrinfo *AddrinfoW) { + syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) + return +} + +func GetIfEntry(pIfRow *MibIfRow) (errcode error) { + r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { + r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { + r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) + n = int32(r0) + if n == -1 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { + r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetACP() (acp uint32) { + r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) + acp = uint32(r0) + return +} + +func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { + r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) + nwrite = int32(r0) + if nwrite == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { + r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { + r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NetApiBufferFree(buf *byte) (neterr error) { + r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { + r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { + r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLengthSid(sid *SID) (len uint32) { + r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + len = uint32(r0) + return +} + +func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { + r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { + r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FreeSid(sid *SID) (err error) { + r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + if r1 != 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { + r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0) + isEqual = r0 != 0 + return +} + +func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { + r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenProcessToken(h Handle, access uint32, token *Token) (err error) { + r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +}