Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PasswordMessage passed to postgres instance returns 'insufficient data left in message' #2166

Open
joram opened this issue Nov 16, 2024 · 2 comments
Labels

Comments

@joram
Copy link

joram commented Nov 16, 2024

Describe the bug
When proxying messages from the psql cli to a postgres instance (using a Backend for the client and a Frontend for the DB, I can successfully pass most messages back and forth until it gets to the PasswordMessage. When I proxy that to the database, it returns the error:
FATAL 08P01 insufficient data left in message

To Reproduce
Steps to reproduce the behavior:

If possible, please provide runnable example such as:

package main

# the code has a channel of the messages going back and forth, so it can keep the sequence in order.
# I'd be happy to spin up an example codebase with a working copy of the code or something, but it feels too big to drop in a bug report

switch msg := unCast.(type) {

case *pgproto3.SSLRequest:
    _, err := p.clientConn.Write([]byte("N"))
    if err != nil {
	    return err
    }

case *pgproto3.StartupMessage:
    p.username = msg.Parameters["user"]
    p.databaseFrontend.Send(msg)
    p.databaseFrontend.Flush()

case *pgproto3.AuthenticationSASL:
    p.clientBackend.Send(msg)
    p.clientBackend.Flush()

case *pgproto3.PasswordMessage:
    p.databaseFrontend.Send(msg)
    p.databaseFrontend.Flush()

case *pgproto3.ErrorResponse:
    p.clientBackend.Send(msg)
    p.clientBackend.Flush()

}

Expected behavior
I expect the message from the client to be received without error by the postgres database, and for the initialization handshake to continue.

Actual behavior

 msg c->db (*pgproto3.SSLRequest): &{}
 msg c->db (*pgproto3.StartupMessage): ....
msg db->c (*pgproto3.AuthenticationSASL): &{[SCRAM-SHA-256]}
 msg c->db (*pgproto3.PasswordMessage): &{SCRAM-SHA-256}
 msg db->c (*pgproto3.ErrorResponse): &{FATAL FATAL 08P01 insufficient data left in message   %!!(MISSING)s(int32=0) %!!(MISSING)s(int32=0)        pqformat.c %!!(MISSING)s(int32=531) pq_copymsgbytes map[]}

Version

  • Go: go version go1.23.2 linux/amd64
  • PostgreSQL: postgres:17 docker image
  • pgx: github.com/jackc/pgx/v5 v5.7.1
@joram joram added the bug label Nov 16, 2024
@jackc
Copy link
Owner

jackc commented Nov 16, 2024

I've proxied the PG protocol before, but I've never done it with SSL or SASL. I would suggest trying it without SSL and maybe with a simpler password type. I wonder if psql is trying to use channel binding or something else not supported by pgx.

@joram
Copy link
Author

joram commented Nov 16, 2024

Good info, thanks.

I'm currently injecting a N to ssl requests, but I'll give a simpler auth method a try.

Interestingly im able to make it work by proxying net.Conn communication, then when I see a Q message, i wrap those connections with pgproto3 frontend/backend, and operate at a higher level. I was just hoping to keep it with the nice higher level library. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants