>From 212af2998f87734e4d057d26db3c5221e0f7432f Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 10 Apr 2017 15:49:04 +0300
Subject: [PATCH 1/1] Add docs for SASL authentication in protocol.

---
 doc/src/sgml/protocol.sgml | 260 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 258 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 4e8bb32d33..3bc62a4b82 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -1326,6 +1326,119 @@
   </sect2>
  </sect1>
 
+<sect1 id="sasl-authentication">
+<title>SASL Authentication</title>
+
+<para>
+SASL is a framework for authentication in connection-oriented protocols.
+At the moment, PostgreSQL implements only one SASL authentication mechanism,
+SCRAM-SHA-256, but more might be added in the future. The below steps
+illustrate how SASL authentication is performed in general, while the next
+subsection gives more details on SCRAM-SHA-256.
+</para>
+
+<procedure>
+<title>SASL Authentication Message Flow</title>
+<step id="sasl-auth-begin">
+<para>  
+  To begin an SASL authentication exchange, the server sends the client an
+  AuthenticationSASL message. It includes a list of SASL authentication
+  mechanisms that the server can accept, in the server's preferred order.
+</para>
+<step id="sasl-auth-initial-response">
+<para>
+  The client selects one of the supported mechanisms from the list, and sends
+  a SASLInitialResponse message to the server. The message includes the name
+  of the selected mechanism, and possibly an Initial Client Response, if the
+  selected mechanism supports that.
+</para>
+
+<step id="sasl-auth-continue">
+<para>
+  One or more server-challenge and client-response message will follow. Each
+  server-challenge is sent in an AuthenticationSASLContinue message, followed
+  by a response from client in an SASLResponse  message. The particulars of
+  the messages are mechanism specific.
+</para>
+
+<step id="sasl-auth-end">
+<para>
+  Finally, when the authentication exchange is completed successfully, the
+  server sends an AuthenticationOK message. The AuthenticationOK message can
+  include an "additional data" field, whose content is particular to the
+  selected authentication mechanism.
+</para>
+
+ <sect2 id="sasl-scram-sha256">
+  <title>SCRAM-SHA-256 authentication</title>
+
+  <para>
+    SCRAM-SHA-256 is the only implemented SASL mechanism, at the moment. It is
+    described in detail in [RFC7677] and [RFC5741]. (called just SCRAM from now on)
+  </para>
+
+  <para>
+When SCRAM-SHA-256 is used in PostgreSQL, the server will ignore the username
+that the client sends in the client-first-message. The username that was
+already sent in the startup message is used instead. PostgreSQL supports
+multiple character encodings, while SCRAM dictates UTF-8 to be used for the
+username, so it might be impossible to represent the PostgreSQL username in
+UTF-8. To avoid confusion, the client should use an empty string as the
+username in the client-first-message.
+  </para>
+
+  <para>
+The SCRAM specification dictates that the password is also in UTF-8, and is
+processed with the SASLprep algorithm. PostgreSQL, however, does not require
+UTF-8 to be used for the password. When a user's password is set, it is
+processed with SASLprep as if it was in UTF-8, regardless of the actual
+encoding used. However, if it is not a legal UTF-8 byte sequence, or it
+contains UTF-8 byte sequences that are prohibited by the SASLprep algorithm,
+the raw password will be used without SASLprep processing, instead of
+throwing an error. This allows the password to be normalized when it is in
+UTF-8, but still allows a non-UTF-8 password to be used, and doesn't require
+the system to know which encoding the password is in.
+  </para>
+
+  <para>
+Channel binding has not been implemented yet.
+  </para>
+
+  <para>
+Example:
+
+<procedure>
+<step id="scram-begin">
+<para>
+  The server sends an AuthenticationSASL message. It includes of a
+  list of SASL authentication mechanisms that the server can accept.
+</para>
+<step id="scram-client-first">
+<para>
+  The client responds by sending a SASLInitialResponse message, which
+  indicates the chosen mechanism, <literal>SCRAM-SHA-256</>. In the Initial
+  Client response field, the message containts a SCRAM
+  <literal>client-first-message</>, as specified by [RFC5802] and [RFC7677].
+</para>
+<step id="scram-server-first">
+<para>
+  Server sends an AuthenticationSASLContinue message, with a SCRAM
+  <literal>server-first message</literal> as the content.
+</para>
+<step id="scram-client-final">
+<para>
+  Client sends a SASLResponse messsage, with SCRAM
+  <literal>client-final-message</literal> as the content.
+</para>
+<step id="scram-server-final">
+<para>
+  Server sends an AuthenticationOK message, with the SCRAM
+  <literal>server-final-message</> in the "additional data" field.
+</para>
+
+</sect2>
+  
+  
 <sect1 id="protocol-replication">
 <title>Streaming Replication Protocol</title>
 
@@ -2501,7 +2614,7 @@ AuthenticationOk (B)
 </varlistentry>
 <varlistentry>
 <term>
-        Int32(8)
+        Int32
 </term>
 <listitem>
 <para>
@@ -2519,6 +2632,29 @@ AuthenticationOk (B)
 </para>
 </listitem>
 </varlistentry>
+<varlistentry>
+<term>
+        Int32
+</term>
+<listitem>
+<para>
+                Length of authentication method specific "additional
+                data" that follows. If this message contains no additional
+                data, this field is omitted.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+        Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+                Authentication method specific "additional data". If this
+                message contains no additional data, this field is omitted.
+</para>
+</listitem>
+</varlistentry>
 </variablelist>
 
 </para>
@@ -2894,13 +3030,19 @@ AuthenticationSASL (B)
 </para>
 </listitem>
 </varlistentry>
+</variablelist>
+The message body is a list of SASL authentication mechanisms, in the
+server's order of preference. A zero byte is required as terminator after
+the last authentication mechanism name. For each mechanism, there is the
+following:
+<variablelist>
 <varlistentry>
 <term>
         String
 </term>
 <listitem>
 <para>
-                Name of a SASL authentication mechanism.
+                Name of SASL authentication mechanism.
 </para>
 </listitem>
 </varlistentry>
@@ -4761,6 +4903,120 @@ PasswordMessage (F)
 
 <varlistentry>
 <term>
+SASLInitialresponse (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+        Byte1('p')
+</term>
+<listitem>
+<para>
+                Identifies the message as an initial SASL response. Note that
+                this is also used for GSSAPI, SSPI and password response messages.
+                The message type is deduced from the context.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+        Int32
+</term>
+<listitem>
+<para>
+                Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+        String
+</term>
+<listitem>
+<para>
+                Name of the SASL authentication mechanism that the client
+                selected.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+        Int32
+</term>
+<listitem>
+<para>
+                Length of SASL mechanism specific "Initial Response" that
+                follows, or -1 if there is no Initial Response.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+        Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+                SASL mechanism specific "Initial Response".
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+SASLResponse (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+        Byte1('p')
+</term>
+<listitem>
+<para>
+                Identifies the message as a SASL response. Note that
+                this is also used for GSSAPI, SSPI and password response messages.
+                The message type can be deduced from the context.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+        Int32
+</term>
+<listitem>
+<para>
+                Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+        Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+                SASL mechanism specific message data.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
 PortalSuspended (B)
 </term>
 <listitem>
-- 
2.11.0

