Thread: Re: Re: Proposal for encrypting pg_shadow passwords

Re: Re: Proposal for encrypting pg_shadow passwords

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> We aren't.  I can do that, but have not discussed it yet.  If we do it
> is clearly a protocol change.  How will old clients handle longer salt,
> and how do I know if they are older if I don't bump up the protocol
> version number?

All of this is under the aegis of a new auth method code, so it doesn't
matter.  Either clients handle the new auth method, or they don't.

The problem with bumping the protocol version number is that it breaks
client-to-server compatibility *whether or not a particular connection
needs the new auth method*.  Eg, a new client will be unable to talk to
an old server.  This is not good.

            regards, tom lane

Re: Re: Proposal for encrypting pg_shadow passwords

From
Bruce Momjian
Date:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > We aren't.  I can do that, but have not discussed it yet.  If we do it
> > is clearly a protocol change.  How will old clients handle longer salt,
> > and how do I know if they are older if I don't bump up the protocol
> > version number?
>
> All of this is under the aegis of a new auth method code, so it doesn't
> matter.  Either clients handle the new auth method, or they don't.

OK, here is a new patch that creates a new md5 keyword on pg_hba.conf.
That certainly makes my coding easier, and when I apply the patch to use
larger salt for MD5, there is now a good reason to have a different
keyword.  With the old system, they could have used an old client to
reply a sniffed packet, while now, if the host is set to MD5, they have
a much larger namespace with no fallback to crypt.

Applied.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
Index: doc/src/sgml/client-auth.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v
retrieving revision 1.16
diff -c -r1.16 client-auth.sgml
*** doc/src/sgml/client-auth.sgml    2001/08/15 18:42:14    1.16
--- doc/src/sgml/client-auth.sgml    2001/08/16 16:14:28
***************
*** 194,219 ****

           <para>
            The password is sent over the wire in clear text. For better
!           protection, use the <literal>crypt</literal> method.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term>crypt</>
          <listitem>
           <para>
            Like the <literal>password</literal> method, but the password
            is sent over the wire encrypted using a simple
            challenge-response protocol. This protects against incidental
            wire-sniffing. The name of a file may follow the
!           <literal>crypt</literal> keyword.  It contains a list of users
            for this record.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
          <term>krb4</>
          <listitem>
           <para>
--- 194,230 ----

           <para>
            The password is sent over the wire in clear text. For better
!           protection, use the <literal>md5</literal> or
!           <literal>crypt</literal> methods.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term>md5</>
          <listitem>
           <para>
            Like the <literal>password</literal> method, but the password
            is sent over the wire encrypted using a simple
            challenge-response protocol. This protects against incidental
            wire-sniffing. The name of a file may follow the
!           <literal>md5</literal> keyword.  It contains a list of users
            for this record.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
+         <term>crypt</>
+         <listitem>
+          <para>
+           Like the <literal>md5</literal> method but uses older crypt
+           authentication for pre-7.2 clients.
+          </para>
+         </listitem>
+        </varlistentry>
+
+        <varlistentry>
          <term>krb4</>
          <listitem>
           <para>
***************
*** 328,334 ****
  # Allow a user from host 192.168.12.10 to connect to database "template1"
  # if the user's password in pg_shadow is correctly supplied:

! host         template1   192.168.12.10 255.255.255.255    crypt

  # In the absence of preceding "host" lines, these two lines will reject
  # all connection attempts from 192.168.54.1 (since that entry will be
--- 339,345 ----
  # Allow a user from host 192.168.12.10 to connect to database "template1"
  # if the user's password in pg_shadow is correctly supplied:

! host         template1   192.168.12.10 255.255.255.255    md5

  # In the absence of preceding "host" lines, these two lines will reject
  # all connection attempts from 192.168.54.1 (since that entry will be
***************
*** 377,387 ****
     </para>

     <para>
!     To restrict the set of users that are allowed to connect to
!     certain databases, list the set of users in a separate file (one
!     user name per line) in the same directory that
!     <filename>pg_hba.conf</> is in, and mention the (base) name of the
!     file after the <literal>password</> or <literal>crypt</> keyword,
      respectively, in <filename>pg_hba.conf</>. If you do not use this
      feature, then any user that is known to the database system can
      connect to any database (so long as he passes password
--- 388,398 ----
     </para>

     <para>
!     To restrict the set of users that are allowed to connect to certain
!     databases, list the set of users in a separate file (one user name
!     per line) in the same directory that <filename>pg_hba.conf</> is in,
!     and mention the (base) name of the file after the
!     <literal>password</>, <literal>md5</>, or <literal>crypt</> keyword,
      respectively, in <filename>pg_hba.conf</>. If you do not use this
      feature, then any user that is known to the database system can
      connect to any database (so long as he passes password
***************
*** 414,421 ****
     </para>

     <para>
!     Alternative passwords cannot be used when using the
!     <literal>crypt</> method. The file will still be evaluated as
      usual but the password field will simply be ignored and the
      <literal>pg_shadow</> password will be used.
     </para>
--- 425,432 ----
     </para>

     <para>
!     Alternative passwords cannot be used when using the <literal>md5</>
!     or <literal>crypt</> methods. The file will still be evaluated as
      usual but the password field will simply be ignored and the
      <literal>pg_shadow</> password will be used.
     </para>
Index: doc/src/sgml/jdbc.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/jdbc.sgml,v
retrieving revision 1.20
diff -c -r1.20 jdbc.sgml
*** doc/src/sgml/jdbc.sgml    2001/03/11 11:06:59    1.20
--- doc/src/sgml/jdbc.sgml    2001/08/16 16:14:34
***************
*** 162,168 ****
      <filename>pg_hba.conf</filename> file may need to be configured.
      Refer to the <citetitle>Administrator's Guide</citetitle> for
      details.  The <acronym>JDBC</acronym> Driver supports trust,
!     ident, password, and crypt authentication methods.
     </para>
    </sect2>
   </sect1>
--- 162,168 ----
      <filename>pg_hba.conf</filename> file may need to be configured.
      Refer to the <citetitle>Administrator's Guide</citetitle> for
      details.  The <acronym>JDBC</acronym> Driver supports trust,
!     ident, password, and md5, crypt authentication methods.
     </para>
    </sect2>
   </sect1>
Index: src/backend/libpq/auth.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/auth.c,v
retrieving revision 1.58
diff -c -r1.58 auth.c
*** src/backend/libpq/auth.c    2001/08/16 04:27:18    1.58
--- src/backend/libpq/auth.c    2001/08/16 16:14:34
***************
*** 501,516 ****
              status = recv_and_check_password_packet(port);
              break;

-         case uaMD5:
-             sendAuthRequest(port, AUTH_REQ_MD5);
-             if ((status = recv_and_check_password_packet(port)) == STATUS_OK)
-                 break;
-             port->auth_method = uaCrypt;
-             /* Try crypt() for old client */
-             /* FALL THROUGH */
-
          case uaCrypt:
              sendAuthRequest(port, AUTH_REQ_CRYPT);
              status = recv_and_check_password_packet(port);
              break;

--- 501,513 ----
              status = recv_and_check_password_packet(port);
              break;

          case uaCrypt:
              sendAuthRequest(port, AUTH_REQ_CRYPT);
+             status = recv_and_check_password_packet(port);
+             break;
+
+         case uaMD5:
+             sendAuthRequest(port, AUTH_REQ_MD5);
              status = recv_and_check_password_packet(port);
              break;

Index: src/backend/libpq/hba.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/hba.c,v
retrieving revision 1.63
diff -c -r1.63 hba.c
*** src/backend/libpq/hba.c    2001/08/16 04:27:18    1.63
--- src/backend/libpq/hba.c    2001/08/16 16:14:35
***************
*** 226,234 ****
              *userauth_p = uaKrb5;
          else if (strcmp(token, "reject") == 0)
              *userauth_p = uaReject;
!         else if (strcmp(token, "crypt") == 0)
!             /* Try MD5 first; on failure, switch to crypt() */
              *userauth_p = uaMD5;
          else
              *error_p = true;
          line = lnext(line);
--- 226,235 ----
              *userauth_p = uaKrb5;
          else if (strcmp(token, "reject") == 0)
              *userauth_p = uaReject;
!         else if (strcmp(token, "md5") == 0)
              *userauth_p = uaMD5;
+         else if (strcmp(token, "crypt") == 0)
+             *userauth_p = uaCrypt;
          else
              *error_p = true;
          line = lnext(line);
Index: src/backend/libpq/pg_hba.conf.sample
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/pg_hba.conf.sample,v
retrieving revision 1.24
diff -c -r1.24 pg_hba.conf.sample
*** src/backend/libpq/pg_hba.conf.sample    2001/08/15 18:42:15    1.24
--- src/backend/libpq/pg_hba.conf.sample    2001/08/16 16:14:35
***************
*** 115,127 ****
  #         utility. Remember, these passwords override pg_shadow
  #         passwords.
  #
! #   crypt:      Same as "password", but authentication is done by
  #        encrypting the password sent over the network. This is
  #        always preferable to "password" except for old clients
! #        that don't support "crypt". Also, crypt can use
! #        usernames stored in secondary password files but not
! #        secondary passwords.
  #
  #   ident:    For TCP/IP connections, authentication is done by contacting
  #        the ident server on the client host.  (CAUTION: this is only
  #        as secure as the client machine!)  On machines that support
--- 115,129 ----
  #         utility. Remember, these passwords override pg_shadow
  #         passwords.
  #
! #   md5:      Same as "password", but authentication is done by
  #        encrypting the password sent over the network. This is
  #        always preferable to "password" except for old clients
! #        that don't support it. Also, md5 can use usernames stored
! #        in secondary password files but not secondary passwords.
  #
+ #   crypt:      Same as "md5", but uses crypt for pre-7.2 clients.  You can
+ #        not store encrypted passwords if you use this option.
+ #
  #   ident:    For TCP/IP connections, authentication is done by contacting
  #        the ident server on the client host.  (CAUTION: this is only
  #        as secure as the client machine!)  On machines that support
***************
*** 173,179 ****
  # if the user's password in pg_shadow is correctly supplied:
  #
  # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # host       template1   192.168.12.10 255.255.255.255    crypt
  #
  # In the absence of preceding "host" lines, these two lines will reject
  # all connection from 192.168.54.1 (since that entry will be matched
--- 175,181 ----
  # if the user's password in pg_shadow is correctly supplied:
  #
  # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # host       template1   192.168.12.10 255.255.255.255    md5
  #
  # In the absence of preceding "host" lines, these two lines will reject
  # all connection from 192.168.54.1 (since that entry will be matched
Index: src/include/libpq/hba.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/libpq/hba.h,v
retrieving revision 1.23
diff -c -r1.23 hba.h
*** src/include/libpq/hba.h    2001/08/15 18:42:15    1.23
--- src/include/libpq/hba.h    2001/08/16 16:14:41
***************
*** 36,43 ****
      uaIdent,
      uaPassword,
      uaCrypt,
!     uaMD5        /*     This starts as uaCrypt from pg_hba.conf, but gets
!                     overridden if the client supports MD5 */
  } UserAuth;

  typedef struct Port hbaPort;
--- 36,42 ----
      uaIdent,
      uaPassword,
      uaCrypt,
!     uaMD5
  } UserAuth;

  typedef struct Port hbaPort;

Re: Re: Proposal for encrypting pg_shadow passwords

From
Peter Eisentraut
Date:
Bruce Momjian writes:

> OK, here is a new patch that creates a new md5 keyword on pg_hba.conf.
> That certainly makes my coding easier, and when I apply the patch to use
> larger salt for MD5, there is now a good reason to have a different
> keyword.  With the old system, they could have used an old client to
> reply a sniffed packet, while now, if the host is set to MD5, they have
> a much larger namespace with no fallback to crypt.

I don't follow this argument.  You added a config option that toggles
whether to use the old crypt(3) method or the new md5 method.  If the old
method is enabled then everything works as until now.  If the new method
is enabled, old clients will fail smoothly.  I don't see why you need to
introduce a new authentication type token; I thought the idea was to allow
this to work transparently.

--
Peter Eisentraut   peter_e@gmx.net   http://funkturm.homeip.net/~peter