Remove support for (insecure) crypt authentication.
authorMagnus Hagander <magnus@hagander.net>
Tue, 28 Oct 2008 12:10:44 +0000 (12:10 +0000)
committerMagnus Hagander <magnus@hagander.net>
Tue, 28 Oct 2008 12:10:44 +0000 (12:10 +0000)
This breaks compatibility with pre-7.2 versions.

13 files changed:
doc/src/sgml/client-auth.sgml
doc/src/sgml/protocol.sgml
doc/src/sgml/user-manag.sgml
src/backend/libpq/auth.c
src/backend/libpq/crypt.c
src/backend/libpq/hba.c
src/backend/postmaster/postmaster.c
src/include/libpq/hba.h
src/include/libpq/libpq-be.h
src/include/libpq/pqcomm.h
src/interfaces/libpq/fe-auth.c
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/libpq-int.h

index 50bf1ce42b75f0aa6befa4684d848d7649527e1e..733b6bafd893129d1f483b6e9efa7527acf3519c 100644 (file)
@@ -315,24 +315,6 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
         </listitem>
        </varlistentry>
 
-       <varlistentry>
-        <term><literal>crypt</></term>
-        <listitem>
-         <note>
-         <para>
-          This option is recommended only for communicating with pre-7.2
-          clients.
-         </para>
-         </note>
-         <para>
-          Require the client to supply a <function>crypt()</>-encrypted
-          password for authentication.
-          <literal>md5</literal> is now recommended over <literal>crypt</>.
-          See <xref linkend="auth-password"> for details.
-         </para>
-        </listitem>
-       </varlistentry>
-
        <varlistentry>
         <term><literal>password</></term>
         <listitem>
@@ -704,9 +686,6 @@ omicron       bryanh            guest1
    <indexterm>
     <primary>MD5</>
    </indexterm>
-   <indexterm>
-    <primary>crypt</>
-   </indexterm>
    <indexterm>
     <primary>password</primary>
     <secondary>authentication</secondary>
@@ -714,21 +693,15 @@ omicron       bryanh            guest1
 
    <para>
     The password-based authentication methods are <literal>md5</>,
-    <literal>crypt</>, and <literal>password</>. These methods operate
+    and <literal>password</>. These methods operate
     similarly except for the way that the password is sent across the
-    connection: respectively, MD5-hashed, crypt-encrypted, and clear-text.
-    A limitation is that the <literal>crypt</> method does not work with
-    passwords that have been encrypted in <structname>pg_authid</structname>.
+    connection: respectively, MD5-hashed and clear-text.
    </para>
 
    <para>
     If you are at all concerned about password
-    <quote>sniffing</> attacks then <literal>md5</> is preferred, with
-    <literal>crypt</> to be used only if you must support pre-7.2
-    clients. Plain <literal>password</> should be avoided especially for
-    connections over the open Internet (unless you use <acronym>SSL</acronym>,
-    <acronym>SSH</>, or another
-    communications security wrapper around the connection).
+    <quote>sniffing</> attacks then <literal>md5</> is preferred.
+    Plain <literal>password</> should always be avoided if possible.
    </para>
 
    <para>
index 14b5e9ac199beb76e125637fa2faad010a4f3aef..342be652ceb867e0f19de42859942d1eba028ac4 100644 (file)
       </listitem>
      </varlistentry>
 
-     <varlistentry>
-      <term>AuthenticationCryptPassword</term>
-      <listitem>
-       <para>
-        The frontend must now send a PasswordMessage containing the
-        password encrypted via crypt(3), using the 2-character salt
-        specified in the AuthenticationCryptPassword message.  If
-        this is the correct password, the server responds with an
-        AuthenticationOk, otherwise it responds with an ErrorResponse.
-       </para>
-      </listitem>
-     </varlistentry>
-
      <varlistentry>
       <term>AuthenticationMD5Password</term>
       <listitem>
@@ -1531,61 +1518,6 @@ AuthenticationCleartextPassword (B)
 </varlistentry>
 
 
-<varlistentry>
-<term>
-AuthenticationCryptPassword (B)
-</term>
-<listitem>
-<para>
-
-<variablelist>
-<varlistentry>
-<term>
-        Byte1('R')
-</term>
-<listitem>
-<para>
-                Identifies the message as an authentication request.
-</para>
-</listitem>
-</varlistentry>
-<varlistentry>
-<term>
-        Int32(10)
-</term>
-<listitem>
-<para>
-                Length of message contents in bytes, including self.
-</para>
-</listitem>
-</varlistentry>
-<varlistentry>
-<term>
-        Int32(4)
-</term>
-<listitem>
-<para>
-                Specifies that a crypt()-encrypted password is required.
-</para>
-</listitem>
-</varlistentry>
-<varlistentry>
-<term>
-        Byte2
-</term>
-<listitem>
-<para>
-                The salt to use when encrypting the password.
-</para>
-</listitem>
-</varlistentry>
-</variablelist>
-
-</para>
-</listitem>
-</varlistentry>
-
-
 <varlistentry>
 <term>
 AuthenticationMD5Password (B)
index 357e00c352674666eaf5157f248b16067da6c04b..594e574a05e33eaec938e13c5a12a8275b6d17a3 100644 (file)
@@ -215,8 +215,8 @@ CREATE USER <replaceable>name</replaceable>;
        <para>
         A password is only significant if the client authentication
         method requires the user to supply a password when connecting
-        to the database. The <option>password</>,
-        <option>md5</>, and <option>crypt</> authentication methods
+        to the database. The <option>password</> and
+        <option>md5</> authentication methods
         make use of passwords. Database passwords are separate from
         operating system passwords. Specify a password upon role
         creation with <literal>CREATE ROLE
index 85c16781eb6cf3a688a6dd912990f2305cf53c5f..3e21a11c8fbc03f32a94e8e242f8982e9188a2bc 100644 (file)
@@ -230,7 +230,6 @@ auth_failed(Port *port, int status)
                        errstr = gettext_noop("Ident authentication failed for user \"%s\"");
                        break;
                case uaMD5:
-               case uaCrypt:
                case uaPassword:
                        errstr = gettext_noop("password authentication failed for user \"%s\"");
                        break;
@@ -373,11 +372,6 @@ ClientAuthentication(Port *port)
                        status = recv_and_check_password_packet(port);
                        break;
 
-               case uaCrypt:
-                       sendAuthRequest(port, AUTH_REQ_CRYPT);
-                       status = recv_and_check_password_packet(port);
-                       break;
-
                case uaPassword:
                        sendAuthRequest(port, AUTH_REQ_PASSWORD);
                        status = recv_and_check_password_packet(port);
@@ -426,8 +420,6 @@ sendAuthRequest(Port *port, AuthRequest areq)
        /* Add the salt for encrypted passwords. */
        if (areq == AUTH_REQ_MD5)
                pq_sendbytes(&buf, port->md5Salt, 4);
-       else if (areq == AUTH_REQ_CRYPT)
-               pq_sendbytes(&buf, port->cryptSalt, 2);
 
 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
 
index 48b39ddd037c046fa798a8dee5d5ddadf54cee0a..9f0e911e4408883c1801a48c70636cf575e65404 100644 (file)
@@ -53,14 +53,6 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass)
        if (shadow_pass == NULL || *shadow_pass == '\0')
                return STATUS_ERROR;
 
-       /* We can't do crypt with MD5 passwords */
-       if (isMD5(shadow_pass) && port->hba->auth_method == uaCrypt)
-       {
-               ereport(LOG,
-                               (errmsg("cannot use authentication method \"crypt\" because password is MD5-encrypted")));
-               return STATUS_ERROR;
-       }
-
        /*
         * Compare with the encrypted or plain password depending on the
         * authentication method being used for this connection.
@@ -106,14 +98,6 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass)
                                pfree(crypt_pwd2);
                        }
                        break;
-               case uaCrypt:
-                       {
-                               char            salt[3];
-
-                               strlcpy(salt, port->cryptSalt, sizeof(salt));
-                               crypt_pwd = crypt(shadow_pass, salt);
-                               break;
-                       }
                default:
                        if (isMD5(shadow_pass))
                        {
index 85b3f77de5e05a8f1e175b9e0c6f86cb94e05f44..bf12e21ab7ef970ff6445aa5d4b416c4ff1078c6 100644 (file)
@@ -847,8 +847,6 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
                parsedline->auth_method = uaReject;
        else if (strcmp(token, "md5") == 0)
                parsedline->auth_method = uaMD5;
-       else if (strcmp(token, "crypt") == 0)
-               parsedline->auth_method = uaCrypt;
        else if (strcmp(token, "pam") == 0)
 #ifdef USE_PAM
                parsedline->auth_method = uaPAM;
index aaaab64a867425a15cbba7efe3445a22f8be83bc..6dcc96471214e3c9f15cc695e4bb1486945f802b 100644 (file)
@@ -323,7 +323,7 @@ static int  initMasks(fd_set *rmask);
 static void report_fork_failure_to_client(Port *port, int errnum);
 static enum CAC_state canAcceptConnections(void);
 static long PostmasterRandom(void);
-static void RandomSalt(char *cryptSalt, char *md5Salt);
+static void RandomSalt(char *md5Salt);
 static void signal_child(pid_t pid, int signal);
 static void SignalSomeChildren(int signal, bool only_autovac);
 
@@ -1808,7 +1808,7 @@ ConnCreate(int serverFd)
                 * fork, not after.  Else the postmaster's random sequence won't get
                 * advanced, and all backends would end up using the same salt...
                 */
-               RandomSalt(port->cryptSalt, port->md5Salt);
+               RandomSalt(port->md5Salt);
        }
 
        /*
@@ -3910,49 +3910,20 @@ dummy_handler(SIGNAL_ARGS)
 {
 }
 
-
-/*
- * CharRemap: given an int in range 0..61, produce textual encoding of it
- * per crypt(3) conventions.
- */
-static char
-CharRemap(long ch)
-{
-       if (ch < 0)
-               ch = -ch;
-       ch = ch % 62;
-
-       if (ch < 26)
-               return 'A' + ch;
-
-       ch -= 26;
-       if (ch < 26)
-               return 'a' + ch;
-
-       ch -= 26;
-       return '0' + ch;
-}
-
 /*
  * RandomSalt
  */
 static void
-RandomSalt(char *cryptSalt, char *md5Salt)
+RandomSalt(char *md5Salt)
 {
-       long            rand = PostmasterRandom();
-
-       cryptSalt[0] = CharRemap(rand % 62);
-       cryptSalt[1] = CharRemap(rand / 62);
+       long            rand;
 
        /*
-        * It's okay to reuse the first random value for one of the MD5 salt
-        * bytes, since only one of the two salts will be sent to the client.
-        * After that we need to compute more random bits.
-        *
         * We use % 255, sacrificing one possible byte value, so as to ensure that
         * all bits of the random() value participate in the result. While at it,
         * add one to avoid generating any null bytes.
         */
+       rand = PostmasterRandom();
        md5Salt[0] = (rand % 255) + 1;
        rand = PostmasterRandom();
        md5Salt[1] = (rand % 255) + 1;
index 21467a1cc35153c3302438b31102f61283cb3bd7..d9d5cd1950355d5f118209e196df757789c0f94a 100644 (file)
@@ -22,7 +22,6 @@ typedef enum UserAuth
        uaTrust,
        uaIdent,
        uaPassword,
-       uaCrypt,
        uaMD5,
        uaGSS,
        uaSSPI,
index 306bc5d6c945ac036ab2c9f5499a2624a427bd00..886ce8feafc2474b7930b94b2a3684c0a86d53de 100644 (file)
@@ -123,7 +123,6 @@ typedef struct Port
         */
        HbaLine    *hba;
        char            md5Salt[4];             /* Password salt */
-       char            cryptSalt[2];   /* Password salt */
 
        /*
         * Information that really has no business at all being in struct Port,
index 2a0f9339b679de4551e5f2f2bad0fb0c8f162bf1..7ba66122351afe1292e090f84e0c448304e49a81 100644 (file)
@@ -153,7 +153,7 @@ extern bool Db_user_namespace;
 #define AUTH_REQ_KRB4          1       /* Kerberos V4. Not supported any more. */
 #define AUTH_REQ_KRB5          2       /* Kerberos V5 */
 #define AUTH_REQ_PASSWORD      3       /* Password */
-#define AUTH_REQ_CRYPT         4       /* crypt password */
+#define AUTH_REQ_CRYPT         4       /* crypt password. Not supported any more. */
 #define AUTH_REQ_MD5           5       /* md5 password */
 #define AUTH_REQ_SCM_CREDS     6       /* transfer SCM credentials */
 #define AUTH_REQ_GSS           7       /* GSSAPI without wrap() */
index 490ca1bb3b9270f94acc6e842f4a28c2bb81894a..a2e7f49c61a3dd1ea3c188d1030af06b43c4a6fb 100644 (file)
 #include <pwd.h>
 #endif
 
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif
-
 #include "libpq-fe.h"
 #include "fe-auth.h"
 #include "libpq/md5.h"
@@ -787,14 +783,6 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
                                }
                                break;
                        }
-               case AUTH_REQ_CRYPT:
-                       {
-                               char            salt[3];
-
-                               strlcpy(salt, conn->cryptSalt, sizeof(salt));
-                               crypt_pwd = crypt(password, salt);
-                               break;
-                       }
                case AUTH_REQ_PASSWORD:
                        /* discard const so we can assign it */
                        crypt_pwd = (char *) password;
@@ -938,8 +926,12 @@ pg_fe_sendauth(AuthRequest areq, PGconn *conn)
 #endif
 
 
-               case AUTH_REQ_MD5:
                case AUTH_REQ_CRYPT:
+                       printfPQExpBuffer(&conn->errorMessage,
+                                libpq_gettext("Crypt authentication not supported\n"));
+                       return STATUS_ERROR;
+
+               case AUTH_REQ_MD5:
                case AUTH_REQ_PASSWORD:
                        conn->password_needed = true;
                        if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
index 17642d8b59e8b323fcd093369247f5e4f3399d1f..4c4615703a48ceb40305691b4f848c4ec9b9c486 100644 (file)
@@ -1674,15 +1674,6 @@ keep_going:                                              /* We will come back to here until there is
                                                return PGRES_POLLING_READING;
                                        }
                                }
-                               if (areq == AUTH_REQ_CRYPT)
-                               {
-                                       if (pqGetnchar(conn->cryptSalt,
-                                                                  sizeof(conn->cryptSalt), conn))
-                                       {
-                                               /* We'll come back when there are more data */
-                                               return PGRES_POLLING_READING;
-                                       }
-                               }
 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
 
                                /*
index 272d3b1dc73a15287810c885780e889dd9834c4f..1007849daa3ff24abc337a00b8092cf25460135c 100644 (file)
@@ -340,7 +340,6 @@ struct pg_conn
        int                     be_pid;                 /* PID of backend --- needed for cancels */
        int                     be_key;                 /* key of backend --- needed for cancels */
        char            md5Salt[4];             /* password salt received from backend */
-       char            cryptSalt[2];   /* password salt received from backend */
        pgParameterStatus *pstatus; /* ParameterStatus data */
        int                     client_encoding;        /* encoding id */
        bool            std_strings;    /* standard_conforming_strings */