]> granicus.if.org Git - postgresql/commitdiff
Remove sslverify parameter again, replacing it with two new sslmode values:
authorMagnus Hagander <magnus@hagander.net>
Fri, 24 Apr 2009 09:43:10 +0000 (09:43 +0000)
committerMagnus Hagander <magnus@hagander.net>
Fri, 24 Apr 2009 09:43:10 +0000 (09:43 +0000)
"verify-ca" and "verify-full".

Since "prefer" remains the default, this will make certificate validation
off by default, which should lead to less upgrade issues.

doc/src/sgml/libpq.sgml
doc/src/sgml/runtime.sgml
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-secure.c
src/interfaces/libpq/libpq-int.h

index 4e7748c3c523a6487c751d7e6f55ffd6a193e7b1..61a3e5d5e0e7da052dd64069d0d3ec3cc763dc33 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.285 2009/04/15 13:03:11 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.286 2009/04/24 09:43:09 mha Exp $ -->
 
 <chapter id="libpq">
  <title><application>libpq</application> - C Library</title>
               <entry><literal>require</></entry>
               <entry>only try an <acronym>SSL</> connection</entry>
              </row>
-        
+
+             <row>
+              <entry><literal>verify-ca</></entry>
+              <entry>only try an <acronym>SSL</> connection, and verify that
+              the server certificate is issued by a trusted <acronym>CA</>.
+              </entry>
+             </row>
+
+             <row>
+              <entry><literal>verify-full</></entry>
+              <entry>only try an <acronym>SSL</> connection, verify that
+              the server certificate is issued by a trusted <acronym>CA</> and
+              that the server hostname matches that in the certificate.</entry>
+             </row>
+
             </tbody>
            </tgroup>
           </table>
          </listitem>
         </varlistentry>
 
-        <varlistentry id="libpq-connect-sslverify" xreflabel="sslverify">
-         <term><literal>sslverify</literal></term>
-         <listitem>
-          <para>
-           This option controls how libpq verifies the certificate on the
-           server when performing an <acronym>SSL</> connection. There are
-           three options: <literal>none</> disables verification completely
-           (not recommended); <literal>cert</> enables verification that
-           the server certificate chains to a known certificate
-           authority (CA); <literal>cn</> will both verify that the
-           certificate chains to a known CA and that the <literal>cn</>
-           attribute of the server certificate matches the server's
-           hostname (default).
-          </para>
-
-          <para>
-           It is always recommended to use the <literal>cn</> value for
-           this parameter, since this is the only option that prevents
-           man-in-the-middle attacks. Note that this requires the server
-           name on the certificate to match exactly with the host name
-           used for the connection, and therefore does not support connections
-           to aliased names. It can be used with pure IP address connections
-           only if the certificate also has just the IP address in the
-           <literal>cn</> field.
-          </para>
-
-          <para>
-           If the <literal>cn</> attribute in the certificate sent by the
-           server starts with an asterisk (<literal>*</>), it will be treated
-           as a wildcard. This wildcard can only be present at the start of
-           the value, and will match all characters <emphasis>except</> a
-           dot (<literal>.</>). This means the certificate will not match
-           subdomains.
-          </para>
-         </listitem>
-        </varlistentry>
-
         <varlistentry id="libpq-connect-requiressl" xreflabel="requiressl">
          <term><literal>requiressl</literal></term>
          <listitem>
@@ -5800,16 +5777,6 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
      </para>
     </listitem>
 
-    <listitem>
-     <para>
-      <indexterm>
-       <primary><envar>PGSSLVERIFY</envar></primary>
-      </indexterm>
-      <envar>PGSSLVERIFY</envar> behaves the same as <xref
-      linkend="libpq-connect-sslverify"> connection parameter.
-     </para>
-    </listitem>
-
     <listitem>
      <para>
       <indexterm>
@@ -6162,25 +6129,60 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
    file.
   </para>
 
+ <sect2 id="libq-ssl-certificates">
+  <title>Certificate verification</title>
+
+  <para>
+   By default, <productname>PostgreSQL</> will not perform any validation of
+   the server certificate. This means that it is possible to spoof the server
+   identity (for example by modifying a DNS record or by taking over the server
+   IP address) without the client knowing. In order to prevent this,
+   <acronym>SSL</> certificate validation must be used.
+  </para>
+
+  <para>
+   If the parameter <literal>sslmode</> is set to <literal>verify-ca</>
+   libpq will verify that the server is trustworthy by checking the certificate
+   chain up to a trusted <acronym>CA</>. If <literal>sslmode</> is set to
+   <literal>verify-full</>, libpq will <emphasis>also</> verify that the server
+   hostname matches that of the certificate. The SSL connection will fail if
+   the server certificate cannot be verified. <literal>verify-full</> is
+   recommended in most security sensitive environments.
+  </para>
+
   <para>
-   When the <literal>sslverify</> parameter is set to <literal>cn</> or
-   <literal>cert</>, libpq requires a trustworthy server certificate by
-   checking the certificate chain up to a <acronym>CA</>.
-   To allow verification, place the certificate of a trusted <acronym>CA</>
-   in the file <filename>~/.postgresql/root.crt</> in the user's home directory.
-   (On Microsoft Windows the file is named
+   In <literal>verify-full</> mode, the <literal>cn</> attribute of the
+   certificate is matched against the hostname. If the <literal>cn</>
+   attribute starts with an asterisk (<literal>*</>), it will be treated as
+   a wildcard, and will match all characters <emphasis>except</> a dot
+   (<literal>.</>). This means the certificate will not match subdomains.
+   If the connection is made using an IP address instead of a hostname, the
+   IP address will be matched (without doing any DNS lookups).
+  </para>
+
+  <para>
+   To allow verification, the certificate of a trusted <acronym>CA</> must be
+   placed in the file <filename>~/.postgresql/root.crt</> in the user's home
+   directory. (On Microsoft Windows the file is named
    <filename>%APPDATA%\postgresql\root.crt</filename>.)
-   <application>libpq</application> will then verify that the server's
-   certificate is signed by one of the trusted certificate authorities.
-   The SSL connection will fail if the server certificate cannot be verified.
+  </para>
+
+  <para>
    Certificate Revocation List (CRL) entries are also checked
    if the file <filename>~/.postgresql/root.crl</filename> exists
    (<filename>%APPDATA%\postgresql\root.crl</filename> on Microsoft
    Windows).
+  </para>
+
+  <para>
    The location of the root certificate store and the CRL can be overridden
    by the connection parameters <literal>sslrootcert</> and <literal>sslcrl</>
    or the environment variables <envar>PGSSLROOTCERT</> and <envar>PGSSLCRL</>.
   </para>
+ </sect2>
+
+ <sect2 id="libpq-ssl-clientcert">
+  <title>Client certificates</title>
 
   <para>
    If the server requests a trusted client certificate,
@@ -6201,6 +6203,9 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
    environment variables <envar>PGSSLCERT</> and <envar>PGSSLKEY</>.
   </para>
 
+ </sect2>
+ <sect2 id="libpq-ssl-fileusage">
+  <title>SSL File Usage</title>
   <table id="libpq-ssl-file-usage">
    <title>Libpq/Client SSL File Usage</title>
    <tgroup cols="3">
@@ -6243,6 +6248,10 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
     </tbody>
    </tgroup>
   </table>
+ </sect2>
+
+ <sect2 id="libpq-ssl-initialize">
+  <title>SSL library initialization</title>
 
   <para>
    If your application initializes <literal>libssl</> and/or
@@ -6330,6 +6339,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
     </varlistentry>
    </variablelist>
   </para>
+ </sect2>
 
  </sect1>
 
index abfcd5dffb1549496bde0d04425dac70ba4fd6f1..0d54a1cc959d11651fd2b931ca2ddf2a5efb927f 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.425 2009/01/09 13:37:18 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.426 2009/04/24 09:43:09 mha Exp $ -->
 
 <chapter Id="runtime">
  <title>Server Setup and Operation</title>
@@ -1422,8 +1422,8 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
    <filename>server.key</filename> (key) and
    <filename>server.crt</filename> (certificate) files (<xref
    linkend="ssl-tcp">). The TCP client must connect using
-   <literal>sslmode='require'</>, specify <literal>sslverify='cn'</>
-   or <literal>sslverify='cert'</> and have the required certificate
+   <literal>sslmode='verify-ca'</> or
+   <literal>'verify-full'</> and have the required certificate
    files present (<xref linkend="libpq-connect">).
   </para>
  </sect1>
index 96391e49e7825b5f156b99e5b0ae83d765d6a3f6..a9ca5e30addcb6dfeb67dac74028c2f307bad876 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.372 2009/01/01 17:24:03 momjian Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.373 2009/04/24 09:43:10 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -91,11 +91,9 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
 #define DefaultAuthtype                  ""
 #define DefaultPassword                  ""
 #ifdef USE_SSL
-#define DefaultSSLMode "prefer"
-#define DefaultSSLVerify "cn"
+#define DefaultSSLMode "prefer"
 #else
 #define DefaultSSLMode "disable"
-#define DefaultSSLVerify "none"
 #endif
 
 /* ----------
@@ -185,9 +183,6 @@ static const PQconninfoOption PQconninfoOptions[] = {
        {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
        "SSL-Mode", "", 8},                     /* sizeof("disable") == 8 */
 
-       {"sslverify", "PGSSLVERIFY", DefaultSSLVerify, NULL,
-       "SSL-Verify", "", 5},           /* sizeof("chain") == 5 */
-
        {"sslcert", "PGSSLCERT", NULL, NULL,
        "SSL-Client-Cert", "", 64},
 
@@ -431,8 +426,6 @@ connectOptions1(PGconn *conn, const char *conninfo)
        conn->connect_timeout = tmp ? strdup(tmp) : NULL;
        tmp = conninfo_getval(connOptions, "sslmode");
        conn->sslmode = tmp ? strdup(tmp) : NULL;
-       tmp = conninfo_getval(connOptions, "sslverify");
-       conn->sslverify = tmp ? strdup(tmp) : NULL;
        tmp = conninfo_getval(connOptions, "sslkey");
        conn->sslkey = tmp ? strdup(tmp) : NULL;
        tmp = conninfo_getval(connOptions, "sslcert");
@@ -522,7 +515,9 @@ connectOptions2(PGconn *conn)
                if (strcmp(conn->sslmode, "disable") != 0
                        && strcmp(conn->sslmode, "allow") != 0
                        && strcmp(conn->sslmode, "prefer") != 0
-                       && strcmp(conn->sslmode, "require") != 0)
+                       && strcmp(conn->sslmode, "require") != 0
+                       && strcmp(conn->sslmode, "verify-ca") != 0
+                       && strcmp(conn->sslmode, "verify-full") != 0)
                {
                        conn->status = CONNECTION_BAD;
                        printfPQExpBuffer(&conn->errorMessage,
@@ -544,6 +539,7 @@ connectOptions2(PGconn *conn)
                                break;
 
                        case 'r':                       /* "require" */
+                       case 'v':                       /* "verify-ca" or "verify-full" */
                                conn->status = CONNECTION_BAD;
                                printfPQExpBuffer(&conn->errorMessage,
                                                                  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
@@ -555,24 +551,6 @@ connectOptions2(PGconn *conn)
        else
                conn->sslmode = strdup(DefaultSSLMode);
 
-       /*
-        * Validate sslverify option
-        */
-       if (conn->sslverify)
-       {
-               if (strcmp(conn->sslverify, "none") != 0
-                       && strcmp(conn->sslverify, "cert") != 0
-                       && strcmp(conn->sslverify, "cn") != 0)
-               {
-                       conn->status = CONNECTION_BAD;
-                       printfPQExpBuffer(&conn->errorMessage,
-                                                       libpq_gettext("invalid sslverify value: \"%s\"\n"),
-                                                         conn->sslverify);
-                       return false;
-               }
-       }
-
-
        /*
         * Only if we get this far is it appropriate to try to connect. (We need a
         * state flag, rather than just the boolean result of this function, in
@@ -1428,7 +1406,8 @@ keep_going:                                               /* We will come back to here until there is
                                        }
                                        else if (SSLok == 'N')
                                        {
-                                               if (conn->sslmode[0] == 'r')    /* "require" */
+                                               if (conn->sslmode[0] == 'r' ||  /* "require" */
+                                                       conn->sslmode[0] == 'v')    /* "verify-ca" or "verify-full" */
                                                {
                                                        /* Require SSL, but server does not want it */
                                                        appendPQExpBuffer(&conn->errorMessage,
@@ -1445,7 +1424,8 @@ keep_going:                                               /* We will come back to here until there is
                                                /* Received error - probably protocol mismatch */
                                                if (conn->Pfdebug)
                                                        fprintf(conn->Pfdebug, "received error from server, attempting fallback to pre-7.0\n");
-                                               if (conn->sslmode[0] == 'r')    /* "require" */
+                                               if (conn->sslmode[0] == 'r' ||  /* "require" */
+                                                       conn->sslmode[0] == 'v')    /* "verify-ca" or "verify-full" */
                                                {
                                                        /* Require SSL, but server is too old */
                                                        appendPQExpBuffer(&conn->errorMessage,
@@ -2052,8 +2032,6 @@ freePGconn(PGconn *conn)
                free(conn->pgpass);
        if (conn->sslmode)
                free(conn->sslmode);
-       if (conn->sslverify)
-               free(conn->sslverify);
        if (conn->sslcert)
                free(conn->sslcert);
        if (conn->sslkey)
index 05d9fdb229889c76652ebc1487cc8397846beecd..523e2ccccdba42997499f407ff082a324f51f7f7 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.123 2009/04/14 17:30:16 momjian Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.124 2009/04/24 09:43:10 mha Exp $
  *
  * NOTES
  *
@@ -523,7 +523,7 @@ verify_peer_name_matches_certificate(PGconn *conn)
         * If told not to verify the peer name, don't do it. Return
         * 0 indicating that the verification was successful.
         */
-       if(strcmp(conn->sslverify, "cn") != 0)
+       if (strcmp(conn->sslmode, "verify-full") != 0)
                return true;
 
        if (conn->pghostaddr)
@@ -987,9 +987,9 @@ initialize_SSL(PGconn *conn)
                return -1;
 
        /*
-        * If sslverify is set to anything other than "none", perform certificate
-        * verification. If set to "cn" we will also do further verifications after
-        * the connection has been completed.
+        * If sslmode is set to one of the verify options, perform certificate
+        * verification. If set to "verify-full" we will also do further
+        * verification after the connection has been completed.
         *
         * If we are going to look for either root certificate or CRL in the home directory,
         * we need pqGetHomeDirectory() to succeed. In other cases, we don't need to
@@ -999,7 +999,7 @@ initialize_SSL(PGconn *conn)
        {
                if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
                {
-                       if (strcmp(conn->sslverify, "none") != 0)
+                       if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
                        {
                                printfPQExpBuffer(&conn->errorMessage,
                                                                  libpq_gettext("could not get home directory to locate root certificate file"));
@@ -1064,7 +1064,7 @@ initialize_SSL(PGconn *conn)
        else
        {
                /* stat() failed; assume cert file doesn't exist */
-               if (strcmp(conn->sslverify, "none") != 0)
+               if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
                {
                        printfPQExpBuffer(&conn->errorMessage,
                                                          libpq_gettext("root certificate file \"%s\" does not exist\n"
index 597c8e77da83331e498aa8b3a1bb036702c9b248..eeb50462e679c20c32f6b013ec379e60aba783eb 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.140 2009/04/19 22:37:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.141 2009/04/24 09:43:10 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -294,7 +294,6 @@ struct pg_conn
        char       *pguser;                     /* Postgres username and password, if any */
        char       *pgpass;
        char       *sslmode;            /* SSL mode (require,prefer,allow,disable) */
-       char       *sslverify;          /* Verify server SSL certificate (none,chain,cn) */
        char       *sslkey;                     /* client key filename */
        char       *sslcert;            /* client certificate filename */
        char       *sslrootcert;        /* root certificate filename */