]> granicus.if.org Git - postgresql/commitdiff
If SSL negotiation fails and SSLMODE is 'prefer', then retry without SSL.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 21 Nov 2006 16:28:00 +0000 (16:28 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 21 Nov 2006 16:28:00 +0000 (16:28 +0000)
Negotiation failure is only likely to happen if one side or the other is
misconfigured, eg. bad client certificate.  I'm not 100% convinced that
a retry is really the best thing, hence not back-patching this fix for now.
Per gripe from Sergio Cinos.

src/interfaces/libpq/fe-connect.c

index 55f3e04f6d974f2881fcf5a7e4bc924f064a99f3..eb6ab6127df61ec20fc6fe56b314d4069dec4439 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.338 2006/10/06 17:14:00 petere Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.339 2006/11/21 16:28:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1400,6 +1400,25 @@ keep_going:                                              /* We will come back to here until there is
                                        conn->status = CONNECTION_MADE;
                                        return PGRES_POLLING_WRITING;
                                }
+                               if (pollres == PGRES_POLLING_FAILED)
+                               {
+                                       /*
+                                        * Failed ... if sslmode is "prefer" then do a non-SSL
+                                        * retry
+                                        */
+                                       if (conn->sslmode[0] == 'p' /* "prefer" */
+                                               && conn->allow_ssl_try  /* redundant? */
+                                               && !conn->wait_ssl_try) /* redundant? */
+                                       {
+                                               /* only retry once */
+                                               conn->allow_ssl_try = false;
+                                               /* Must drop the old connection */
+                                               closesocket(conn->sock);
+                                               conn->sock = -1;
+                                               conn->status = CONNECTION_NEEDED;
+                                               goto keep_going;
+                                       }
+                               }
                                return pollres;
 #else                                                  /* !USE_SSL */
                                /* can't get here */