Richard Bramante's provided a fix for a handle re-use problem seen when you
authorDaniel Stenberg <daniel@haxx.se>
Mon, 24 Mar 2003 23:10:38 +0000 (23:10 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 24 Mar 2003 23:10:38 +0000 (23:10 +0000)
change options on an SSL-enabled connection between requests.

lib/url.c
lib/urldata.h

index c10a18997eefc2fa4f3d39c113a2ef28163d2995..563f8a548c7c56b987b1becf0e9593d676724b3b 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -143,7 +143,12 @@ static bool ConnectionExists(struct SessionHandle *data,
                              struct connectdata **usethis);
 static unsigned int ConnectionStore(struct SessionHandle *data,
                                     struct connectdata *conn);
-
+static bool ssl_config_matches(struct ssl_config_data* data,
+                               struct ssl_config_data* needle);
+static bool init_ssl_config(struct SessionHandle* data,
+                            struct connectdata* conn);
+static bool safe_strequal(char* str1, char* str2);
+static void free_ssl_config(struct ssl_config_data* sslc);
 
 #if !defined(WIN32)||defined(__CYGWIN32__)
 #ifndef RETSIGTYPE
@@ -1211,6 +1216,8 @@ CURLcode Curl_disconnect(struct connectdata *conn)
   if(conn->proxyhost)
     free(conn->proxyhost);
 
+  free_ssl_config(&conn->ssl_config);
+
   free(conn); /* free all the connection oriented data */
 
   return CURLE_OK;
@@ -1277,7 +1284,14 @@ ConnectionExists(struct SessionHandle *data,
       if(strequal(needle->protostr, check->protostr) &&
          strequal(needle->name, check->name) &&
          (needle->remote_port == check->remote_port) ) {
-        if(strequal(needle->protostr, "FTP")) {
+        if(needle->protocol & PROT_SSL) {
+          /* This is SSL, verify that we're using the same
+             ssl options as well */
+          if(!ssl_config_matches(&needle->ssl_config, &check->ssl_config)) {
+            continue;
+          }
+        }
+        if(needle->protocol & PROT_FTP) {
           /* This is FTP, verify that we're using the same name and
              password as well */
           if(!strequal(needle->data->state.user, check->proto.ftp->user) ||
@@ -2686,6 +2700,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     ConnectionStore(data, conn);
   }
 
+  if(!init_ssl_config(data, conn))
+    return CURLE_OUT_OF_MEMORY;
+
   /* Continue connectdata initialization here.
    * 
    * Inherit the proper values from the urldata struct AFTER we have arranged
@@ -3025,3 +3042,87 @@ CURLcode Curl_do_more(struct connectdata *conn)
 
   return result;
 }
+
+static bool safe_strequal(char* str1, char* str2)
+{
+  if(str1 && str2)
+    /* both pointers point to something then compare them */
+    return strequal(str1, str2);
+  else
+    /* if both pointers are NULL then treat them as equal */
+    return (!str1 && !str2);
+}
+
+static bool
+ssl_config_matches(struct ssl_config_data* data,
+                   struct ssl_config_data* needle)
+{
+  bool result = FALSE;
+
+  if((data->version == needle->version) &&
+     (data->verifypeer == needle->verifypeer) &&
+     (data->verifyhost == needle->verifyhost) &&
+     safe_strequal(data->CApath, needle->CApath) &&
+     safe_strequal(data->CAfile, needle->CAfile) &&
+     safe_strequal(data->random_file, needle->random_file) &&
+     safe_strequal(data->egdsocket, needle->egdsocket) &&
+     safe_strequal(data->cipher_list, needle->cipher_list))
+  {
+    result = TRUE;
+  }
+
+  return result;
+}
+
+static bool
+init_ssl_config(struct SessionHandle* data, struct connectdata* conn) 
+{
+  conn->ssl_config.verifyhost = data->set.ssl.verifyhost;
+  conn->ssl_config.verifypeer = data->set.ssl.verifypeer;
+  conn->ssl_config.version = data->set.ssl.version;
+
+  if(data->set.ssl.CAfile) {
+    conn->ssl_config.CAfile = strdup(data->set.ssl.CAfile);
+    if(!conn->ssl_config.CAfile) return FALSE;
+  }
+
+  if(data->set.ssl.CApath) {
+    conn->ssl_config.CApath = strdup(data->set.ssl.CApath);
+       if(!conn->ssl_config.CApath) return FALSE;
+  }
+
+  if(data->set.ssl.cipher_list) {
+    conn->ssl_config.cipher_list = strdup(data->set.ssl.cipher_list);
+       if(!conn->ssl_config.cipher_list) return FALSE;
+  }
+
+  if(data->set.ssl.egdsocket) {
+    conn->ssl_config.egdsocket = strdup(data->set.ssl.egdsocket);
+       if(!conn->ssl_config.egdsocket) return FALSE;
+  }
+
+  if(data->set.ssl.random_file) {
+    conn->ssl_config.random_file = strdup(data->set.ssl.random_file);
+       if(!conn->ssl_config.random_file) return FALSE;
+  }
+
+  return TRUE;
+}
+
+static void free_ssl_config(struct ssl_config_data* sslc) 
+{
+  if(sslc->CAfile)
+    free(sslc->CAfile);
+
+  if(sslc->CApath)
+    free(sslc->CApath);
+
+  if(sslc->cipher_list)
+    free(sslc->cipher_list);
+
+  if(sslc->egdsocket)
+    free(sslc->egdsocket);
+
+  if(sslc->random_file)
+    free(sslc->random_file);
+}
index 89aa50991f00c9e6906c01a5ce6cdbbae8dca6c6..93ad35b6034f49896a77cba56a0962c4ac0c97c9 100644 (file)
@@ -380,6 +380,7 @@ struct connectdata {
                        means unlimited */
   
   struct ssl_connect_data ssl; /* this is for ssl-stuff */
+  struct ssl_config_data ssl_config;
 
   struct ConnectBits bits;    /* various state-flags for this connection */