Re: Letting the client choose the protocol to use during a SASL exchange
Álvaro Hernández Tortosa <aht@8kdata.com>
From: Álvaro Hernández Tortosa <aht@8kdata.com>
To: Heikki Linnakangas <hlinnaka@iki.fi>,
Michael Paquier <michael.paquier@gmail.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>, Simon Riggs <simon@2ndquadrant.com>,
PostgreSQL mailing lists <pgsql-hackers@postgresql.org>
Date: 2017-04-11T08:55:36Z
Lists: pgsql-hackers
On 11/04/17 08:50, Heikki Linnakangas wrote:
> On 04/10/2017 11:03 PM, Álvaro Hernández Tortosa wrote:
>> Channel binding needs to specify actually three things:
>> - The mechanism, which is indeed suffixed "-PLUS".
>> - The channel binding name, which is described here:
>> https://tools.ietf.org/html/rfc5056. Types are also IANA-registered (see
>> https://www.iana.org/assignments/channel-binding-types/channel-binding-types.xhtml).
>>
>> SCRAM mandates to implement 'tls-unique', but other channel binding
>> types could be supported (like 'tls-server-end-point' for example).
>> - The channel binding data, which is channel binding mechanism
>> dependent, and is sent as part of the client last message.
>>
>> What I'm talking about here is the second one, the channel binding
>> type (name).
>
> Oh, I see. According to the SCRAM RFC, "tls-unique" is used by
> default. I don't see us implementing anything else any time soon.
> PostgreSQL doesn't support any other "channel type" than TLS, and
> tls-unique is the only one that makes sense for TLS.
>
> If we do need it after all, the server could advertise the additional
> channel binding types as additional SASL mechanisms in the
> AuthenticationSASL message, maybe something like:
>
> "SCRAM-SHA-256"
> "SCRAM-SHA-256-PLUS" (for tls-unique)
> "SCRAM-SHA-256-PLUS ssh-unique" (for hypothetical ssh channel binding)
>
> The same trick can be used to advertise any other SASL mechanism
> specific options, if needed in the future.
Why not add an extra field to the message? This scheme has in my
opinion some disadvantages:
- You assume no extensibility. Maybe Postgres will implement other
mechanisms for channel binding. Maybe not. But why limit ourselves?
- Apart from tls-unique there are others today, like
tls-server-end-point and who knows if in the future TLS 1.x comes with
something like 'tls-unique-1.x'
- Why have to parse the string (separated by spaces) when you could use
different fields and have no parsing at all?
- How do you advertise different SCRAM mechanisms with different channel
binding types? And a mix of SCRAM mechanisms with and without channel
binding? If I got it right, with your proposal it would be something like:
Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS tls-unique,SCRAM-SHA-1-PLUS
tls-unique,SCRAM-SHA-512-PLUS tls-unique
(which is basically a CSV of pairs where the right part of the pair
might be empty; too much IMHO for a single field)
vs
Field 1:
SCRAM-SHA-256,SCRAM-SHA-256-PLUS,SCRAM-SHA-1-PLUS,SCRAM-SHA-512-PLUS
(simple CSV)
Field 2: tls-unique (String)
Is there any reason not to use two fields? AuthenticationSASL is a
new message, I guess we can freely choose its format, right?
>
>>> I'm not sure I follow. The username is sent from client to server, and
>>> currently, the server will ignore it. If you're writing a client
>>> library, it can send whatever it wants. (Although again I would
>>> recommend an empty string, to avoid confusion. Sending the same
>>> username as in the startup packet, as long as it's in UTF-8, seems
>>> reasonable too.)
>>
>> OK, understood. I will not let then the SCRAM implementation I'm
>> writing to allow for empty string as the user name, but in the pgjdbc
>> glue code send "ignore" as the user name or something like that ;P
>
> Hmm, so the SASL library you're using doesn't like sending an empty
> string as the username? Now that I look at RFC5802 more closely, it says:
>
>> If the preparation of the username fails or results in an empty
>> string, the server SHOULD abort the authentication exchange.
>
> Perhaps we should reserve a magic user name to mean "same as startup
> message", in addition or instead of the empty string. We actually
> discussed that already at [1], but we forgot about it since.
That works. Please let me know what is the "magic constant" chosen ;P
Thanks,
Álvaro
--
Álvaro Hernández Tortosa
-----------
<8K>data
Commits
-
Improve the SASL authentication protocol.
- 4f3b87ab780b 10.0 landed
-
Refactor libpq authentication request processing.
- 61bf96cab063 10.0 landed
-
Minor cleanup of backend SCRAM code.
- 00707fa58275 10.0 landed