mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-12-23 08:45:39 +00:00
Report errors during handshake stage (#1091)
Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com>
This commit is contained in:
parent
ae997a5acb
commit
ddb75700a0
@ -546,8 +546,9 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn) e
|
|||||||
}
|
}
|
||||||
meta = version_metadata{}
|
meta = version_metadata{}
|
||||||
base := version_getBaseMetadata()
|
base := version_getBaseMetadata()
|
||||||
if !meta.decode(conn, options.password) {
|
if err := meta.decode(conn, options.password); err != nil {
|
||||||
return conn.Close()
|
_ = conn.Close()
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if !meta.check() {
|
if !meta.check() {
|
||||||
return fmt.Errorf("remote node incompatible version (local %s, remote %s)",
|
return fmt.Errorf("remote node incompatible version (local %s, remote %s)",
|
||||||
|
@ -87,22 +87,22 @@ func (m *version_metadata) encode(privateKey ed25519.PrivateKey, password []byte
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decodes version metadata from its wire format into the struct.
|
// Decodes version metadata from its wire format into the struct.
|
||||||
func (m *version_metadata) decode(r io.Reader, password []byte) bool {
|
func (m *version_metadata) decode(r io.Reader, password []byte) error {
|
||||||
bh := [6]byte{}
|
bh := [6]byte{}
|
||||||
if _, err := io.ReadFull(r, bh[:]); err != nil {
|
if _, err := io.ReadFull(r, bh[:]); err != nil {
|
||||||
return false
|
return err
|
||||||
}
|
}
|
||||||
meta := [4]byte{'m', 'e', 't', 'a'}
|
meta := [4]byte{'m', 'e', 't', 'a'}
|
||||||
if !bytes.Equal(bh[:4], meta[:]) {
|
if !bytes.Equal(bh[:4], meta[:]) {
|
||||||
return false
|
return fmt.Errorf("invalid handshake preamble")
|
||||||
}
|
}
|
||||||
bs := make([]byte, binary.BigEndian.Uint16(bh[4:6]))
|
hl := binary.BigEndian.Uint16(bh[4:6])
|
||||||
|
if hl < ed25519.SignatureSize {
|
||||||
|
return fmt.Errorf("invalid handshake length")
|
||||||
|
}
|
||||||
|
bs := make([]byte, hl)
|
||||||
if _, err := io.ReadFull(r, bs); err != nil {
|
if _, err := io.ReadFull(r, bs); err != nil {
|
||||||
return false
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
if len(bs) < ed25519.SignatureSize {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
sig := bs[len(bs)-ed25519.SignatureSize:]
|
sig := bs[len(bs)-ed25519.SignatureSize:]
|
||||||
bs = bs[:len(bs)-ed25519.SignatureSize]
|
bs = bs[:len(bs)-ed25519.SignatureSize]
|
||||||
@ -132,14 +132,17 @@ func (m *version_metadata) decode(r io.Reader, password []byte) bool {
|
|||||||
|
|
||||||
hasher, err := blake2b.New512(password)
|
hasher, err := blake2b.New512(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return fmt.Errorf("invalid password supplied")
|
||||||
}
|
}
|
||||||
n, err := hasher.Write(m.publicKey)
|
n, err := hasher.Write(m.publicKey)
|
||||||
if err != nil || n != ed25519.PublicKeySize {
|
if err != nil || n != ed25519.PublicKeySize {
|
||||||
return false
|
return fmt.Errorf("failed to generate hash")
|
||||||
}
|
}
|
||||||
hash := hasher.Sum(nil)
|
hash := hasher.Sum(nil)
|
||||||
return ed25519.Verify(m.publicKey, hash, sig)
|
if !ed25519.Verify(m.publicKey, hash, sig) {
|
||||||
|
return fmt.Errorf("password is incorrect")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that the "meta" bytes and the version numbers are the expected values.
|
// Checks that the "meta" bytes and the version numbers are the expected values.
|
||||||
|
@ -34,7 +34,7 @@ func TestVersionPasswordAuth(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var decoded version_metadata
|
var decoded version_metadata
|
||||||
if allowed := decoded.decode(bytes.NewBuffer(encoded), tt.password2); allowed != tt.allowed {
|
if allowed := decoded.decode(bytes.NewBuffer(encoded), tt.password2) == nil; allowed != tt.allowed {
|
||||||
t.Fatalf("Permutation %q -> %q should have been %v but was %v", tt.password1, tt.password2, tt.allowed, allowed)
|
t.Fatalf("Permutation %q -> %q should have been %v but was %v", tt.password1, tt.password2, tt.allowed, allowed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,8 +67,8 @@ func TestVersionRoundtrip(t *testing.T) {
|
|||||||
}
|
}
|
||||||
encoded := bytes.NewBuffer(meta)
|
encoded := bytes.NewBuffer(meta)
|
||||||
decoded := &version_metadata{}
|
decoded := &version_metadata{}
|
||||||
if !decoded.decode(encoded, password) {
|
if err := decoded.decode(encoded, password); err != nil {
|
||||||
t.Fatalf("failed to decode")
|
t.Fatalf("failed to decode: %s", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(test, decoded) {
|
if !reflect.DeepEqual(test, decoded) {
|
||||||
t.Fatalf("round-trip failed\nwant: %+v\n got: %+v", test, decoded)
|
t.Fatalf("round-trip failed\nwant: %+v\n got: %+v", test, decoded)
|
||||||
|
Loading…
Reference in New Issue
Block a user