Commit 9558f229 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Fixup after talks with Richard Bramante. We should now make better

comparisons before re-using SSL connections and re-using SSL connection IDs.
parent 7917bfb1
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include "urldata.h"
#include "sendf.h"
#include "formdata.h" /* for the boundary function */
#include "url.h" /* for the ssl config check function */

#ifdef USE_SSLEAY
#include <openssl/rand.h>
@@ -522,7 +523,8 @@ static int Get_SSL_Session(struct connectdata *conn,
      /* not session ID means blank entry */
      continue;
    if(curl_strequal(conn->name, check->name) &&
       (conn->remote_port == check->remote_port) ) {
       (conn->remote_port == check->remote_port) &&
       Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
      /* yes, we have a session ID! */
      data->state.sessionage++;            /* increase general age */
      check->age = data->state.sessionage; /* set this as used in this age */
@@ -546,6 +548,9 @@ static int Kill_Single_Session(struct curl_ssl_session *session)
    SSL_SESSION_free(session->sessionid);
    session->sessionid=NULL;
    session->age = 0; /* fresh */

    Curl_free_ssl_config(&session->ssl_config);

    free(session->name);
    session->name = NULL; /* no name */

@@ -637,6 +642,8 @@ static int Store_SSL_Session(struct connectdata *conn)
  store->name = strdup(conn->name);       /* clone host name */
  store->remote_port = conn->remote_port; /* port number */

  Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config);

  return 0;
}

+29 −32
Original line number Diff line number Diff line
@@ -143,12 +143,7 @@ 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
@@ -1224,7 +1219,7 @@ CURLcode Curl_disconnect(struct connectdata *conn)
  if(conn->proxyhost)
    free(conn->proxyhost);

  free_ssl_config(&conn->ssl_config);
  Curl_free_ssl_config(&conn->ssl_config);

  free(conn); /* free all the connection oriented data */

@@ -1300,7 +1295,8 @@ ConnectionExists(struct SessionHandle *data,
        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)) {
          if(!Curl_ssl_config_matches(&needle->ssl_config,
                                      &check->ssl_config)) {
            continue;
          }
        }
@@ -2713,7 +2709,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
    ConnectionStore(data, conn);
  }

  if(!init_ssl_config(data, conn))
  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
    return CURLE_OUT_OF_MEMORY;

  /* Continue connectdata initialization here.
@@ -3066,8 +3062,8 @@ static bool safe_strequal(char* str1, char* str2)
    return (!str1 && !str2);
}

static bool
ssl_config_matches(struct ssl_config_data* data,
bool
Curl_ssl_config_matches(struct ssl_config_data* data,
                        struct ssl_config_data* needle)
{
  if((data->version == needle->version) &&
@@ -3083,47 +3079,48 @@ ssl_config_matches(struct ssl_config_data* data,
  return FALSE;
}

static bool
init_ssl_config(struct SessionHandle* data, struct connectdata* conn)
bool
Curl_clone_ssl_config(struct ssl_config_data *source,
                      struct ssl_config_data *dest)
{
  conn->ssl_config.verifyhost = data->set.ssl.verifyhost;
  conn->ssl_config.verifypeer = data->set.ssl.verifypeer;
  conn->ssl_config.version = data->set.ssl.version;
  dest->verifyhost = source->verifyhost;
  dest->verifypeer = source->verifypeer;
  dest->version = source->version;

  if(data->set.ssl.CAfile) {
    conn->ssl_config.CAfile = strdup(data->set.ssl.CAfile);
    if(!conn->ssl_config.CAfile)
  if(source->CAfile) {
    dest->CAfile = strdup(source->CAfile);
    if(!dest->CAfile)
      return FALSE;
  }

  if(data->set.ssl.CApath) {
    conn->ssl_config.CApath = strdup(data->set.ssl.CApath);
    if(!conn->ssl_config.CApath)
  if(source->CApath) {
    dest->CApath = strdup(source->CApath);
    if(!dest->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)
  if(source->cipher_list) {
    dest->cipher_list = strdup(source->cipher_list);
    if(!dest->cipher_list)
      return FALSE;
  }

  if(data->set.ssl.egdsocket) {
    conn->ssl_config.egdsocket = strdup(data->set.ssl.egdsocket);
    if(!conn->ssl_config.egdsocket)
  if(source->egdsocket) {
    dest->egdsocket = strdup(source->egdsocket);
    if(!dest->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)
  if(source->random_file) {
    dest->random_file = strdup(source->random_file);
    if(!dest->random_file)
      return FALSE;
  }

  return TRUE;
}

static void free_ssl_config(struct ssl_config_data* sslc)
void Curl_free_ssl_config(struct ssl_config_data* sslc)
{
  if(sslc->CAfile)
    free(sslc->CAfile);
+5 −0
Original line number Diff line number Diff line
@@ -37,4 +37,9 @@ CURLcode Curl_done(struct connectdata *);
CURLcode Curl_disconnect(struct connectdata *);
CURLcode Curl_protocol_connect(struct connectdata *conn,
                               struct Curl_dns_entry *dns);
bool Curl_ssl_config_matches(struct ssl_config_data* data,
                             struct ssl_config_data* needle);
bool Curl_clone_ssl_config(struct ssl_config_data* source,
                           struct ssl_config_data* dest);
void Curl_free_ssl_config(struct ssl_config_data* sslc);
#endif
+10 −8
Original line number Diff line number Diff line
@@ -125,14 +125,6 @@ struct ssl_connect_data {
#endif /* USE_SSLEAY */
};

/* information about one single SSL session */
struct curl_ssl_session {
  char *name;       /* host name for which this ID was used */
  void *sessionid;  /* as returned from the SSL layer */
  long age;         /* just a number, the higher the more recent */
  unsigned short remote_port; /* remote port to connect to */
};

struct ssl_config_data {
  long version;          /* what version the client wants to use */
  long certverifyresult; /* result from the certificate verification */
@@ -148,6 +140,16 @@ struct ssl_config_data {
  long numsessions;      /* SSL session id cache size */
};

/* information stored about one single SSL session */
struct curl_ssl_session {
  char *name;       /* host name for which this ID was used */
  void *sessionid;  /* as returned from the SSL layer */
  long age;         /* just a number, the higher the more recent */
  unsigned short remote_port; /* remote port to connect to */
  struct ssl_config_data ssl_config; /* setup for this session */
};


/****************************************************************************
 * HTTP unique setup
 ***************************************************************************/