diff --git a/lib/frontend/frontends/v0/auth/md5.go b/lib/frontend/frontends/v0/auth/md5.go new file mode 100644 index 0000000000000000000000000000000000000000..5ec1f5814ee5f643cccaf0bd042f5fcd2b16cf52 --- /dev/null +++ b/lib/frontend/frontends/v0/auth/md5.go @@ -0,0 +1,36 @@ +package auth + +import ( + "crypto/md5" + "encoding/hex" + "strings" +) + +func EncodeMD5(username, password string, salt [4]byte) string { + hash := md5.New() + hash.Write([]byte(password)) + hash.Write([]byte(username)) + sum1 := hash.Sum(nil) + hexEncoded := make([]byte, hex.EncodedLen(len(sum1))) + hex.Encode(hexEncoded, sum1) + hash.Reset() + + hash.Write(hexEncoded) + hash.Write(salt[:]) + sum2 := hash.Sum(nil) + hexEncoded = hexEncoded[:0] + for i := 0; i < hex.EncodedLen(len(sum2)); i++ { + hexEncoded = append(hexEncoded, 0) + } + hex.Encode(hexEncoded, sum2) + + var out strings.Builder + out.Grow(3 + len(hexEncoded)) + out.WriteString("md5") + out.Write(hexEncoded) + return out.String() +} + +func CheckMD5(username, password string, salt [4]byte, encoded string) bool { + return EncodeMD5(username, password, salt) == encoded +} diff --git a/lib/frontend/frontends/v0/client.go b/lib/frontend/frontends/v0/client.go index ac193052e47952a7ec01551e4396b958b89790d8..44fac2d4d7bcb01f9fd16ddb7046392107d9a7ea 100644 --- a/lib/frontend/frontends/v0/client.go +++ b/lib/frontend/frontends/v0/client.go @@ -6,13 +6,14 @@ import ( "net" "pggat2/lib/frontend" + "pggat2/lib/frontend/frontends/v0/auth" "pggat2/lib/perror" "pggat2/lib/pnet" "pggat2/lib/pnet/packet" ) var ErrBadPacketFormat = perror.New( - perror.ERROR, + perror.FATAL, perror.ProtocolViolation, "Bad packet format", ) @@ -63,7 +64,7 @@ func (T *Client) accept() error { case 5678: // Cancel err = T.Error(perror.New( - perror.ERROR, + perror.FATAL, perror.FeatureNotSupported, "Cancel is not supported yet", )) @@ -87,7 +88,7 @@ func (T *Client) accept() error { continue default: err = T.Error(perror.New( - perror.ERROR, + perror.FATAL, perror.ProtocolViolation, "Unknown request code", )) @@ -100,7 +101,7 @@ func (T *Client) accept() error { if majorVersion != 3 || minorVersion != 0 { err = T.Error(perror.New( - perror.ERROR, + perror.FATAL, perror.ProtocolViolation, "Unsupported protocol version", )) @@ -128,19 +129,19 @@ func (T *Client) accept() error { T.database = value case "options": return T.Error(perror.New( - perror.ERROR, + perror.FATAL, perror.FeatureNotSupported, "Startup options are not supported yet", )) case "replication": return T.Error(perror.New( - perror.ERROR, + perror.FATAL, perror.FeatureNotSupported, "Replication mode is not supported yet", )) default: return T.Error(perror.New( - perror.ERROR, + perror.FATAL, perror.ProtocolViolation, "Unsupported startup parameter", )) @@ -149,8 +150,8 @@ func (T *Client) accept() error { if T.user == "" { return T.Error(perror.New( - perror.ERROR, - perror.InvalidPassword, + perror.FATAL, + perror.InvalidAuthorizationSpecification, "User is required", )) } @@ -190,7 +191,7 @@ func (T *Client) accept() error { reader := packet.MakeReader(password) if reader.Type() != packet.AuthenticationResponse { return T.Error(perror.New( - perror.ERROR, + perror.FATAL, perror.ProtocolViolation, "Expected password", )) @@ -202,6 +203,13 @@ func (T *Client) accept() error { } log.Print("password=", pw) + if !auth.CheckMD5("test", "password", salt, pw) { + return T.Error(perror.New( + perror.FATAL, + perror.InvalidPassword, + "Invalid password", + )) + } return nil } diff --git a/lib/frontend/frontends/v0/frontend.go b/lib/frontend/frontends/v0/frontend.go index 17020e8f95f9f13a964d452d0a3778a1d6dbd68a..ac982a7356006ef1cd96ebfab9e35dacd301b8cd 100644 --- a/lib/frontend/frontends/v0/frontend.go +++ b/lib/frontend/frontends/v0/frontend.go @@ -1,6 +1,7 @@ package frontends import ( + "log" "net" "pggat2/lib/frontend" @@ -30,9 +31,10 @@ func (T *Frontend) Run() error { client, err := NewClient(conn) if err != nil { - return err + log.Println("rejected client:", err) + } else { + T.clients = append(T.clients, client) } - T.clients = append(T.clients, client) } }