Changelog
Daniel (11 September 2006)
+- Fixed my breakage from earlier today so that doing curl_easy_cleanup() on a
+ handle that is part of a multi handle first removes the handle from the
+ stack.
+
+- Added CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid to disable SSL
+ session-ID re-use on demand since there obviously are broken servers out
+ there that misbehave with session-IDs used.
+
- Jeff Pohlmeyer presented a *multi_socket()-using program that exposed a
problem with it (SIGSEGV-style). It clearly showed that the existing
socket-state and state-difference function wasn't good enough so I rewrote
This release includes the following changes:
+ o CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid added
o CURLMOPT_PIPELINING added for enabling pipelined transfers
o Added support for other MS-DOS compilers (besides djgpp)
o CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA were added
Using this option will disable that buffering.
If this option is used twice, the second will again switch on buffering.
+.IP "--no-sessionid"
+(SSL) Disable curl's use of SSL session-ID caching. By default all transfers
+are done using the cache. Note that while nothing ever should get hurt by
+attempting to reuse SSL session-IDs, there seem to be broken SSL
+implementations in the wild that may require you to disable this in order for
+you to succeed. (Added in 7.16.0)
+
+If this option is used twice, the second will again switch on use of the
+session cache.
.IP "--ntlm"
(HTTP) Enables NTLM authentication. The NTLM authentication method was
designed by Microsoft and is used by IIS web servers. It is a proprietary
You'll find more details about cipher lists on this URL:
\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
+.IP CURLOPT_SSL_SESSIONID_CACHE
+Pass a long set to 0 to disable libcurl's use of SSL session-ID caching. Set
+this to 1 to enable it. By default all transfers are done using the
+cache. Note that while nothing ever should get hurt by attempting to reuse SSL
+session-IDs, there seem to be broken SSL implementations in the wild that may
+require you to disable this in order for you to succeed. (Added in 7.16.0)
.IP CURLOPT_KRB4LEVEL
Pass a char * as parameter. Set the krb4 security level, this also enables
krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or
CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+ /* set to 0 to disable session ID re-use for this transfer, default is
+ enabled (== 1) */
+ CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
do {
+ if(!GOOD_EASY_HANDLE(easy->easy_handle))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
if (easy->easy_handle->state.pipe_broke) {
infof(easy->easy_handle, "Pipe broke: handle 0x%x\n", easy);
if(easy->easy_handle->state.is_in_pipeline) {
if (easy->easy_handle->state.cancelled &&
easy->state == CURLM_STATE_CANCELLED) {
/* Remove cancelled handles once it's safe to do so */
- easy = easy->next;
Curl_multi_rmeasy(multi_handle, easy->easy_handle);
+ easy->easy_handle = NULL;
+ easy = easy->next;
continue;
}
struct SessionHandle *data = conn->data;
long i;
+ if(!conn->ssl_config.sessionid)
+ /* session ID re-use is disabled */
+ return TRUE;
+
for(i=0; i< data->set.ssl.numsessions; i++) {
check = &data->state.session[i];
if(!check->sessionid)
long oldest_age=data->state.session[0].age; /* zero if unused */
char *clone_host;
+ /* Even though session ID re-use might be disabled, that only disables USING
+ IT. We still store it here in case the re-using is again enabled for an
+ upcoming transfer */
+
clone_host = strdup(conn->host.name);
if(!clone_host)
return CURLE_OUT_OF_MEMORY; /* bail out */
{
struct Curl_multi *m = data->multi;
- data->magic = 0; /* force a clear */
-
if(m)
/* This handle is still part of a multi handle, take care of this first
and detach this handle from there. */
Curl_multi_rmeasy(data->multi, data);
+ data->magic = 0; /* force a clear AFTER the possibly enforced removal from
+ the multi handle, since that function uses the magic
+ field! */
+
if(data->state.connc && (data->state.connc->type == CONNCACHE_PRIVATE)) {
/* close all connections still alive that are in the private connection
cache, as we no longer have the pointer left to the shared one. */
*/
data->set.ssl.verifypeer = TRUE;
data->set.ssl.verifyhost = 2;
+ data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */
#ifdef CURL_CA_BUNDLE
/* This is our preferred CA cert bundle since install time */
data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
data->set.sockopt_client = va_arg(param, void *);
break;
+ case CURLOPT_SSL_SESSIONID_CACHE:
+ data->set.ssl.sessionid = va_arg(param, long)?TRUE:FALSE;
+ break;
+
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_FAILED_INIT; /* correct this */
char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */
long numsessions; /* SSL session id cache size */
- curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
- void *fsslctxp; /*parameter for call back */
+ curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
+ void *fsslctxp; /* parameter for call back */
+ bool sessionid; /* cache session IDs or not */
};
/* information stored about one single SSL session */
int ftp_filemethod;
bool ignorecl; /* --ignore-content-length */
+ bool disable_sessionid;
};
#define WARN_PREFIX "Warning: "
" --netrc-optional Use either .netrc or URL; overrides -n",
" --ntlm Use HTTP NTLM authentication (H)",
" -N/--no-buffer Disable buffering of the output stream",
+ " --no-sessionid Disable SSL session-ID reusing (SSL)",
" -o/--output <file> Write output to <file> instead of stdout",
" -O/--remote-name Write output to a file named as the remote file",
" -p/--proxytunnel Operate through a HTTP proxy tunnel (using CONNECT)",
{"$t", "socks4", TRUE},
{"$u", "ftp-alternative-to-user", TRUE},
{"$v", "ftp-ssl-reqd", FALSE},
+ {"$w", "no-sessionid", FALSE},
{"0", "http1.0", FALSE},
{"1", "tlsv1", FALSE},
case 'v': /* --ftp-ssl-reqd */
config->ftp_ssl_reqd ^= TRUE;
break;
+ case 'w': /* --no-sessionid */
+ config->disable_sessionid ^= TRUE;
+ break;
}
break;
case '#': /* --progress-bar */
/* curl 7.15.2 */
if(config->localport) {
curl_easy_setopt(curl, CURLOPT_LOCALPORT, config->localport);
- curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, config->localportrange);
+ curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE,
+ config->localportrange);
}
- /* curl x.xx.x */
- curl_easy_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER, config->ftp_alternative_to_user);
+ /* curl 7.15.5 */
+ curl_easy_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER,
+ config->ftp_alternative_to_user);
+
+ /* curl 7.16.0 */
+ curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE,
+ !config->disable_sessionid);
retry_numretries = config->req_retry;
res = (int)curl_multi_perform(m, &running);
if (running <= 0) {
#ifdef LIB527
+ /* NOTE: this code does not remove the handle from the multi handle
+ here, which would be the nice, sane and documented way of working.
+ This however tests that the API survives this abuse gracefully. */
curl_easy_cleanup(curl[current]);
#endif
if(++current < NUM_HANDLES) {