diff options
| -rw-r--r-- | lib/imap.c | 10 | ||||
| -rw-r--r-- | lib/pop3.c | 10 | ||||
| -rw-r--r-- | lib/smtp.c | 10 | ||||
| -rw-r--r-- | lib/url.c | 127 | ||||
| -rw-r--r-- | lib/urldata.h | 1 | 
5 files changed, 149 insertions, 9 deletions
| diff --git a/lib/imap.c b/lib/imap.c index c75ccf9ad..0339add48 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -5,7 +5,7 @@   *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.   *   * This software is licensed as described in the file COPYING, which   * you should have received as part of this distribution. The terms @@ -227,7 +227,11 @@ static const struct SASLproto saslimap = {  #ifdef USE_SSL  static void imap_to_imaps(struct connectdata *conn)  { +  /* Change the connection handler */    conn->handler = &Curl_handler_imaps; + +  /* Set the connection's upgraded to TLS flag */ +  conn->tls_upgraded = TRUE;  }  #else  #define imap_to_imaps(x) Curl_nop_stmt @@ -1738,6 +1742,10 @@ static CURLcode imap_setup_connection(struct connectdata *conn)    if(result)      return result; +  /* Clear the TLS upgraded flag */ +  conn->tls_upgraded = FALSE; + +  /* Set up the proxy if necessary */    if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {      /* Unless we have asked to tunnel IMAP operations through the proxy, we         switch and use HTTP operations only */ diff --git a/lib/pop3.c b/lib/pop3.c index 73e1cb2e4..cb53b7445 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -5,7 +5,7 @@   *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.   *   * This software is licensed as described in the file COPYING, which   * you should have received as part of this distribution. The terms @@ -225,7 +225,11 @@ static const struct SASLproto saslpop3 = {  #ifdef USE_SSL  static void pop3_to_pop3s(struct connectdata *conn)  { +  /* Change the connection handler */    conn->handler = &Curl_handler_pop3s; + +  /* Set the connection's upgraded to TLS flag */ +  conn->tls_upgraded = TRUE;  }  #else  #define pop3_to_pop3s(x) Curl_nop_stmt @@ -1354,6 +1358,10 @@ static CURLcode pop3_setup_connection(struct connectdata *conn)    if(result)      return result; +  /* Clear the TLS upgraded flag */ +  conn->tls_upgraded = FALSE; + +  /* Set up the proxy if necessary */    if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {      /* Unless we have asked to tunnel POP3 operations through the proxy, we         switch and use HTTP operations only */ diff --git a/lib/smtp.c b/lib/smtp.c index 7102ffbf3..2a87c6eae 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -5,7 +5,7 @@   *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.   *   * This software is licensed as described in the file COPYING, which   * you should have received as part of this distribution. The terms @@ -224,7 +224,11 @@ static const struct SASLproto saslsmtp = {  #ifdef USE_SSL  static void smtp_to_smtps(struct connectdata *conn)  { +  /* Change the connection handler */    conn->handler = &Curl_handler_smtps; + +  /* Set the connection's upgraded to TLS flag */ +  conn->tls_upgraded = TRUE;  }  #else  #define smtp_to_smtps(x) Curl_nop_stmt @@ -1450,6 +1454,10 @@ static CURLcode smtp_setup_connection(struct connectdata *conn)    struct SessionHandle *data = conn->data;    CURLcode result; +  /* Clear the TLS upgraded flag */ +  conn->tls_upgraded = FALSE; + +  /* Set up the proxy if necessary */    if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {      /* Unless we have asked to tunnel SMTP operations through the proxy, we         switch and use HTTP operations only */ @@ -151,6 +151,8 @@ static CURLcode parse_url_login(struct SessionHandle *data,  static CURLcode parse_login_details(const char *login, const size_t len,                                      char **userptr, char **passwdptr,                                      char **optionsptr); +static unsigned int get_protocol_family(unsigned int protocol); +  /*   * Protocol table.   */ @@ -3272,7 +3274,8 @@ ConnectionExists(struct SessionHandle *data,        if((needle->handler->flags&PROTOPT_SSL) !=           (check->handler->flags&PROTOPT_SSL))          /* don't do mixed SSL and non-SSL connections */ -        if(!(needle->handler->protocol & check->handler->protocol)) +        if(get_protocol_family(check->handler->protocol) != +           needle->handler->protocol || !check->tls_upgraded)            /* except protocols that have been upgraded via TLS */            continue; @@ -3327,14 +3330,16 @@ ConnectionExists(struct SessionHandle *data,            Curl_raw_equal(needle->proxy.name, check->proxy.name) &&            (needle->port == check->port))) {          /* The requested connection does not use a HTTP proxy or it uses SSL or -           it is a non-SSL protocol tunneled over the same http proxy name and -           port number or it is a non-SSL protocol which is allowed to be -           upgraded via TLS */ - +           it is a non-SSL protocol tunneled over the same HTTP proxy name and +           port number */          if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) || -            needle->handler->protocol & check->handler->protocol) && +            (get_protocol_family(check->handler->protocol) == +             needle->handler->protocol && check->tls_upgraded)) &&             Curl_raw_equal(needle->host.name, check->host.name) &&             needle->remote_port == check->remote_port) { +          /* The schemes match or the the protocol family is the same and the +             previous connection was TLS upgraded, and the hostname and host +             port match */            if(needle->handler->flags & PROTOPT_SSL) {              /* This is a SSL connection so verify that we're using the same                 SSL options as well */ @@ -6362,3 +6367,113 @@ CURLcode Curl_do_more(struct connectdata *conn, int *complete)    return result;  } + +/* +* get_protocol_family() +* +* This is used to return the protocol family for a given protocol. +* +* Parameters: +* +* protocol  [in]  - A single bit protocol identifier such as HTTP or HTTPS. +* +* Returns the family as a single bit protocol identifier. +*/ + +unsigned int get_protocol_family(unsigned int protocol) +{ +  unsigned int family; + +  switch(protocol) { +  case CURLPROTO_HTTP: +  case CURLPROTO_HTTPS: +    family = CURLPROTO_HTTP; +    break; + +  case CURLPROTO_FTP: +  case CURLPROTO_FTPS: +    family = CURLPROTO_IMAP; +    break; + +  case CURLPROTO_SCP: +    family = CURLPROTO_SCP; +    break; + +  case CURLPROTO_SFTP: +    family = CURLPROTO_SFTP; +    break; + +  case CURLPROTO_TELNET: +    family = CURLPROTO_TELNET; +    break; + +  case CURLPROTO_LDAP: +  case CURLPROTO_LDAPS: +    family = CURLPROTO_IMAP; +    break; + +  case CURLPROTO_DICT: +    family = CURLPROTO_DICT; +    break; + +  case CURLPROTO_FILE: +    family = CURLPROTO_FILE; +    break; + +  case CURLPROTO_TFTP: +    family = CURLPROTO_TFTP; +    break; + +  case CURLPROTO_IMAP: +  case CURLPROTO_IMAPS: +    family = CURLPROTO_IMAP; +    break; + +  case CURLPROTO_POP3: +  case CURLPROTO_POP3S: +    family = CURLPROTO_POP3; +    break; + +  case CURLPROTO_SMTP: +  case CURLPROTO_SMTPS: +      family = CURLPROTO_SMTP; +      break; + +  case CURLPROTO_RTSP: +    family = CURLPROTO_RTSP; +    break; + +  case CURLPROTO_RTMP: +  case CURLPROTO_RTMPS: +    family = CURLPROTO_RTMP; +    break; + +  case CURLPROTO_RTMPT: +  case CURLPROTO_RTMPTS: +    family = CURLPROTO_RTMPT; +    break; + +  case CURLPROTO_RTMPE: +    family = CURLPROTO_RTMPE; +    break; + +  case CURLPROTO_RTMPTE: +    family = CURLPROTO_RTMPTE; +    break; + +  case CURLPROTO_GOPHER: +    family = CURLPROTO_GOPHER; +    break; + +  case CURLPROTO_SMB: +  case CURLPROTO_SMBS: +    family = CURLPROTO_SMB; +    break; + +  default: +      family = 0; +      break; +  } + +  return family; +}
\ No newline at end of file diff --git a/lib/urldata.h b/lib/urldata.h index fcb17561d..f832ea886 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -921,6 +921,7 @@ struct connectdata {    struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */    struct ssl_config_data ssl_config; +  bool tls_upgraded;    struct ConnectBits bits;    /* various state-flags for this connection */ | 
