From e64d332e7909ea9ba76f241a0fdf9cfe4b6b1236 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 19 Jan 2012 22:28:04 +0100 Subject: OpenSSL: follow-up for commit a20daf90e3 avoid checking preprocessor definition official value --- lib/ssluse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/ssluse.c b/lib/ssluse.c index ec1a149c8..3754904f4 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -1553,8 +1553,7 @@ ossl_connect_step1(struct connectdata *conn, ctx_options |= SSL_OP_NO_TICKET; #endif -#if defined(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && \ - (SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG == 0x00000008L) +#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG /* mitigate CVE-2010-4180 */ ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; #endif -- cgit v1.2.3 From d7af7de5b2d9aee7e41fc45d502c082918abd4bd Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 20 Jan 2012 00:11:15 +0100 Subject: telnet.c: fix OOM triggered segfault --- lib/telnet.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/telnet.c b/lib/telnet.c index e7cb295d8..0be795435 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1273,11 +1273,13 @@ static CURLcode telnet_done(struct connectdata *conn, (void)status; /* unused */ (void)premature; /* not used */ + if(!tn) + return CURLE_OK; + curl_slist_free_all(tn->telnet_vars); tn->telnet_vars = NULL; - free(conn->data->state.proto.telnet); - conn->data->state.proto.telnet = NULL; + Curl_safefree(conn->data->state.proto.telnet); return CURLE_OK; } -- cgit v1.2.3 From 7883cd5af38a824e41b42c94890ea94bf4356fd3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 20 Jan 2012 23:32:43 +0100 Subject: URL parse: user name with ipv6 numerical address Using a URL with embedded user name and password didn't work if the host was given as a numerical IPv6 string, like ftp://user:password@[::1]/ Reported by: Brandon Wang Bug: http://curl.haxx.se/mail/archive-2012-01/0047.html --- lib/url.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/url.c b/lib/url.c index fd46a7e03..466748bfc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -137,7 +137,9 @@ static long ConnectionKillOne(struct SessionHandle *data); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); static CURLcode do_init(struct connectdata *conn); - +static CURLcode parse_url_userpass(struct SessionHandle *data, + struct connectdata *conn, + char *user, char *passwd); /* * Protocol table. */ @@ -3666,7 +3668,9 @@ static CURLcode findprotocol(struct SessionHandle *data, */ static CURLcode parseurlandfillconn(struct SessionHandle *data, struct connectdata *conn, - bool *prot_missing) + bool *prot_missing, + char *user, + char *passwd) { char *at; char *fragment; @@ -3675,6 +3679,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, int rc; char protobuf[16]; const char *protop; + CURLcode result; *prot_missing = FALSE; @@ -3841,6 +3846,14 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, path[0] = '/'; } + /************************************************************* + * Parse a user name and password in the URL and strip it out + * of the host name + *************************************************************/ + result = parse_url_userpass(data, conn, user, passwd); + if(result != CURLE_OK) + return result; + if(conn->host.name[0] == '[') { /* This looks like an IPv6 address literal. See if there is an address scope. */ @@ -4783,7 +4796,7 @@ static CURLcode create_conn(struct SessionHandle *data, conn->host.name = conn->host.rawalloc; conn->host.name[0] = 0; - result = parseurlandfillconn(data, conn, &prot_missing); + result = parseurlandfillconn(data, conn, &prot_missing, user, passwd); if(result != CURLE_OK) return result; @@ -4812,15 +4825,6 @@ static CURLcode create_conn(struct SessionHandle *data, data->change.url_alloc = TRUE; /* free this later */ } - /************************************************************* - * Parse a user name and password in the URL and strip it out - * of the host name - *************************************************************/ - result = parse_url_userpass(data, conn, user, passwd); - if(result != CURLE_OK) - return result; - - /************************************************************* * If the protocol can't handle url query strings, then cut * of the unhandable part -- cgit v1.2.3 From db1a856b4f7cf6ae334fb0656b26a18eea317000 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 19 Jan 2012 10:38:14 +0100 Subject: OpenSSL: don't disable security work-around OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability (http://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to SSL_OP_ALL that _disables_ that work-around despite the fact that SSL_OP_ALL is documented to do "rather harmless" workarounds. The libcurl code uses the SSL_OP_ALL define and thus logically always disables the OpenSSL fix. In order to keep the secure work-around workding, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit must not be set and this change makes sure of this. Reported by: product-security at Apple --- lib/ssluse.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib') diff --git a/lib/ssluse.c b/lib/ssluse.c index 3754904f4..014d5b56a 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -1545,6 +1545,13 @@ ossl_connect_step1(struct connectdata *conn, become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate CVE-2010-4180 when using previous OpenSSL versions we no longer enable this option regardless of OpenSSL version and SSL_OP_ALL definition. + + OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability + (http://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to + SSL_OP_ALL that _disables_ that work-around despite the fact that + SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to + keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit + must not be set. */ ctx_options = SSL_OP_ALL; @@ -1558,6 +1565,10 @@ ossl_connect_step1(struct connectdata *conn, ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; #endif +#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; +#endif + /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */ if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT) ctx_options |= SSL_OP_NO_SSLv2; -- cgit v1.2.3 From 75ca568fa1c19de4c5358fed246686de8467c238 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Dec 2011 13:24:16 +0100 Subject: URL sanitize: reject URLs containing bad data Protocols (IMAP, POP3 and SMTP) that use the path part of a URL in a decoded manner now use the new Curl_urldecode() function to reject URLs with embedded control codes (anything that is or decodes to a byte value less than 32). URLs containing such codes could easily otherwise be used to do harm and allow users to do unintended actions with otherwise innocent tools and applications. Like for example using a URL like pop3://pop3.example.com/1%0d%0aDELE%201 when the app wants a URL to get a mail and instead this would delete one. This flaw is considered a security vulnerability: CVE-2012-0036 Security advisory at: http://curl.haxx.se/docs/adv_20120124.html Reported by: Dan Fandrich --- lib/escape.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++------------- lib/escape.h | 10 +++++++--- lib/imap.c | 7 +------ lib/pop3.c | 6 +----- lib/smtp.c | 7 +++---- 5 files changed, 62 insertions(+), 31 deletions(-) (limited to 'lib') diff --git a/lib/escape.c b/lib/escape.c index b0922bc93..0dd5a1d0a 100644 --- a/lib/escape.c +++ b/lib/escape.c @@ -31,6 +31,7 @@ #include "urldata.h" #include "warnless.h" #include "non-ascii.h" +#include "escape.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -84,7 +85,7 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength) char *testing_ptr = NULL; unsigned char in; /* we need to treat the characters unsigned */ size_t newlen = alloc; - int strindex=0; + size_t strindex=0; size_t length; CURLcode res; @@ -132,23 +133,29 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength) } /* - * Unescapes the given URL escaped string of given length. Returns a - * pointer to a malloced string with length given in *olen. - * If length == 0, the length is assumed to be strlen(string). - * If olen == NULL, no output length is stored. + * Curl_urldecode() URL decodes the given string. + * + * Optionally detects control characters (byte codes lower than 32) in the + * data and rejects such data. + * + * Returns a pointer to a malloced string in *ostring with length given in + * *olen. If length == 0, the length is assumed to be strlen(string). + * */ -char *curl_easy_unescape(CURL *handle, const char *string, int length, - int *olen) +CURLcode Curl_urldecode(struct SessionHandle *data, + const char *string, size_t length, + char **ostring, size_t *olen, + bool reject_ctrl) { - int alloc = (length?length:(int)strlen(string))+1; + size_t alloc = (length?length:strlen(string))+1; char *ns = malloc(alloc); unsigned char in; - int strindex=0; + size_t strindex=0; unsigned long hex; CURLcode res; if(!ns) - return NULL; + return CURLE_OUT_OF_MEMORY; while(--alloc > 0) { in = *string; @@ -164,16 +171,20 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length, in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ - res = Curl_convert_from_network(handle, &in, 1); + res = Curl_convert_from_network(data, &in, 1); if(res) { /* Curl_convert_from_network calls failf if unsuccessful */ free(ns); - return NULL; + return res; } string+=2; alloc-=2; } + if(reject_ctrl && (in < 0x20)) { + free(ns); + return CURLE_URL_MALFORMAT; + } ns[strindex++] = in; string++; @@ -183,7 +194,33 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length, if(olen) /* store output size */ *olen = strindex; - return ns; + + if(ostring) + /* store output string */ + *ostring = ns; + + return CURLE_OK; +} + +/* + * Unescapes the given URL escaped string of given length. Returns a + * pointer to a malloced string with length given in *olen. + * If length == 0, the length is assumed to be strlen(string). + * If olen == NULL, no output length is stored. + */ +char *curl_easy_unescape(CURL *handle, const char *string, int length, + int *olen) +{ + char *str = NULL; + size_t inputlen = length; + size_t outputlen; + CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen, + FALSE); + if(res) + return NULL; + if(olen) + *olen = curlx_uztosi(outputlen); + return str; } /* For operating systems/environments that use different malloc/free diff --git a/lib/escape.h b/lib/escape.h index 04b06a973..4c7f84133 100644 --- a/lib/escape.h +++ b/lib/escape.h @@ -1,5 +1,5 @@ -#ifndef __ESCAPE_H -#define __ESCAPE_H +#ifndef HEADER_CURL_ESCAPE_H +#define HEADER_CURL_ESCAPE_H /*************************************************************************** * _ _ ____ _ @@ -8,7 +8,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -25,5 +25,9 @@ /* Escape and unescape URL encoding in strings. The functions return a new * allocated string or NULL if an error occurred. */ +CURLcode Curl_urldecode(struct SessionHandle *data, + const char *string, size_t length, + char **ostring, size_t *olen, + bool reject_crlf); #endif diff --git a/lib/imap.c b/lib/imap.c index c39664d86..c6701417d 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -953,17 +953,12 @@ static CURLcode imap_parse_url_path(struct connectdata *conn) struct imap_conn *imapc = &conn->proto.imapc; struct SessionHandle *data = conn->data; const char *path = data->state.path; - int len; if(!*path) path = "INBOX"; /* url decode the path and use this mailbox */ - imapc->mailbox = curl_easy_unescape(data, path, 0, &len); - if(!imapc->mailbox) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; + return Curl_urldecode(data, path, 0, &imapc->mailbox, NULL, TRUE); } /* call this when the DO phase has completed */ diff --git a/lib/pop3.c b/lib/pop3.c index b7781109b..cc360b8b9 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -914,11 +914,7 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn) const char *path = data->state.path; /* url decode the path and use this mailbox */ - pop3c->mailbox = curl_easy_unescape(data, path, 0, NULL); - if(!pop3c->mailbox) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; + return Curl_urldecode(data, path, 0, &pop3c->mailbox, NULL, TRUE); } /* call this when the DO phase has completed */ diff --git a/lib/smtp.c b/lib/smtp.c index 4cb25efca..553c697d0 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1244,7 +1244,6 @@ static CURLcode smtp_connect(struct connectdata *conn, struct SessionHandle *data = conn->data; struct pingpong *pp = &smtpc->pp; const char *path = conn->data->state.path; - int len; char localhost[HOSTNAME_MAX + 1]; *done = FALSE; /* default to not done yet */ @@ -1316,9 +1315,9 @@ static CURLcode smtp_connect(struct connectdata *conn, } /* url decode the path and use it as domain with EHLO */ - smtpc->domain = curl_easy_unescape(conn->data, path, 0, &len); - if(!smtpc->domain) - return CURLE_OUT_OF_MEMORY; + result = Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE); + if(result) + return result; /* When we connect, we start in the state where we await the server greeting */ -- cgit v1.2.3 From 70f71bb99f7ed9f4164430507c0b03b84c7e0258 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Jan 2012 23:53:06 +0100 Subject: gnutls: enforced use of SSLv3 With advice from Nikos Mavrogiannopoulos, changed the priority string to add "actual priorities" and favour ARCFOUR. This makes libcurl work better when enforcing SSLv3 with GnuTLS. Both in the sense that the libmicrohttpd test is now working again but also that it mitigates a weakness in the older SSL/TLS protocols. Bug: http://curl.haxx.se/mail/lib-2012-01/0225.html Reported by: Christian Grothoff --- lib/gtls.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gtls.c b/lib/gtls.c index f44fd7748..e24e7a81e 100644 --- a/lib/gtls.c +++ b/lib/gtls.c @@ -453,7 +453,13 @@ gtls_connect_step1(struct connectdata *conn, rc = gnutls_protocol_set_priority(session, protocol_priority); #else const char *err; - rc = gnutls_priority_set_direct(session, "-VERS-TLS-ALL:+VERS-SSL3.0", + /* the combination of the cipher ARCFOUR with SSL 3.0 and TLS 1.0 is not + vulnerable to attacks such as the BEAST, why this code now explicitly + asks for that + */ + rc = gnutls_priority_set_direct(session, + "NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0:" + "-CIPHER-ALL:+ARCFOUR-128", &err); #endif if(rc != GNUTLS_E_SUCCESS) -- cgit v1.2.3