/* * Delete the given session ID from the cache. */ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) { size_t i; struct Curl_easy *data=conn->data; for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) { struct curl_ssl_session *check = &data->state.session[i]; if(check->sessionid == ssl_sessionid) { Curl_ssl_kill_session(check); break; } } }
void Curl_ssl_close_all(struct SessionHandle *data) { size_t i; /* kill the session ID cache if not shared */ if(data->state.session && !SSLSESSION_SHARED(data)) { for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) /* the single-killer function handles empty table slots */ Curl_ssl_kill_session(&data->state.session[i]); /* free the cache data */ Curl_safefree(data->state.session); } curlssl_close_all(data); }
CURLSHcode curl_share_cleanup(CURLSH *sh) { struct Curl_share *share = (struct Curl_share *)sh; if(share == NULL) return CURLSHE_INVALID; if(share->lockfunc) share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE, share->clientdata); if(share->dirty) { if(share->unlockfunc) share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); return CURLSHE_IN_USE; } if(share->hostcache) { Curl_hash_destroy(share->hostcache); share->hostcache = NULL; } #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(share->cookies) Curl_cookie_cleanup(share->cookies); #endif #ifdef USE_SSL if(share->sslsession) { size_t i; for(i = 0; i < share->max_ssl_sessions; i++) Curl_ssl_kill_session(&(share->sslsession[i])); free(share->sslsession); } #endif if(share->unlockfunc) share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); free(share); return CURLSHE_OK; }
/* * Delete the given session ID from the cache. */ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) { size_t i; struct SessionHandle *data=conn->data; if(SSLSESSION_SHARED(data)) Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) { struct curl_ssl_session *check = &data->state.session[i]; if(check->sessionid == ssl_sessionid) { Curl_ssl_kill_session(check); break; } } if(SSLSESSION_SHARED(data)) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); }
void Curl_ssl_close_all(struct SessionHandle *data) { long i; /* kill the session ID cache */ if(data->state.session && !(data->share && data->share->sslsession == data->state.session)) { Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); for(i=0; i< data->set.ssl.numsessions; i++) /* the single-killer function handles empty table slots */ Curl_ssl_kill_session(&data->state.session[i]); /* free the cache data */ free(data->state.session); data->state.session = NULL; Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); } curlssl_close_all(data); }
/* * Store session id in the session cache. The ID passed on to this function * must already have been extracted and allocated the proper way for the SSL * layer. Curl_XXXX_session_free() will be called to free/kill the session ID * later on. */ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, void *ssl_sessionid, size_t idsize) { size_t i; struct SessionHandle *data=conn->data; /* the mother of all structs */ struct curl_ssl_session *store = &data->state.session[0]; long oldest_age=data->state.session[0].age; /* zero if unused */ char *clone_host; long *general_age; /* 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 */ /* Now we should add the session ID and the host name to the cache, (remove the oldest if necessary) */ /* If using shared SSL session, lock! */ if(SSLSESSION_SHARED(data)) { Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); general_age = &data->share->sessionage; } else { general_age = &data->state.sessionage; } /* find an empty slot for us, or find the oldest */ for(i = 1; (i < data->set.ssl.max_ssl_sessions) && data->state.session[i].sessionid; i++) { if(data->state.session[i].age < oldest_age) { oldest_age = data->state.session[i].age; store = &data->state.session[i]; } } if(i == data->set.ssl.max_ssl_sessions) /* cache is full, we must "kill" the oldest entry! */ Curl_ssl_kill_session(store); else store = &data->state.session[i]; /* use this slot */ /* now init the session struct wisely */ store->sessionid = ssl_sessionid; store->idsize = idsize; store->age = *general_age; /* set current age */ if(store->name) /* free it if there's one already present */ free(store->name); store->name = clone_host; /* clone host name */ store->remote_port = conn->remote_port; /* port number */ /* Unlock */ if(SSLSESSION_SHARED(data)) Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) { store->sessionid = NULL; /* let caller free sessionid */ free(clone_host); return CURLE_OUT_OF_MEMORY; } return CURLE_OK; }
/* * Store session id in the session cache. The ID passed on to this function * must already have been extracted and allocated the proper way for the SSL * layer. Curl_XXXX_session_free() will be called to free/kill the session ID * later on. */ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, void *ssl_sessionid, size_t idsize, int sockindex) { size_t i; struct Curl_easy *data=conn->data; /* the mother of all structs */ struct curl_ssl_session *store = &data->state.session[0]; long oldest_age=data->state.session[0].age; /* zero if unused */ char *clone_host; char *clone_conn_to_host; int conn_to_port; long *general_age; const bool isProxy = CONNECT_PROXY_SSL(); struct ssl_primary_config * const ssl_config = isProxy ? &conn->proxy_ssl_config : &conn->ssl_config; DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name); if(!clone_host) return CURLE_OUT_OF_MEMORY; /* bail out */ if(conn->bits.conn_to_host) { clone_conn_to_host = strdup(conn->conn_to_host.name); if(!clone_conn_to_host) { free(clone_host); return CURLE_OUT_OF_MEMORY; /* bail out */ } } else clone_conn_to_host = NULL; if(conn->bits.conn_to_port) conn_to_port = conn->conn_to_port; else conn_to_port = -1; /* Now we should add the session ID and the host name to the cache, (remove the oldest if necessary) */ /* If using shared SSL session, lock! */ if(SSLSESSION_SHARED(data)) { general_age = &data->share->sessionage; } else { general_age = &data->state.sessionage; } /* find an empty slot for us, or find the oldest */ for(i = 1; (i < data->set.general_ssl.max_ssl_sessions) && data->state.session[i].sessionid; i++) { if(data->state.session[i].age < oldest_age) { oldest_age = data->state.session[i].age; store = &data->state.session[i]; } } if(i == data->set.general_ssl.max_ssl_sessions) /* cache is full, we must "kill" the oldest entry! */ Curl_ssl_kill_session(store); else store = &data->state.session[i]; /* use this slot */ /* now init the session struct wisely */ store->sessionid = ssl_sessionid; store->idsize = idsize; store->age = *general_age; /* set current age */ /* free it if there's one already present */ free(store->name); free(store->conn_to_host); store->name = clone_host; /* clone host name */ store->conn_to_host = clone_conn_to_host; /* clone connect to host name */ store->conn_to_port = conn_to_port; /* connect to port number */ /* port number */ store->remote_port = isProxy ? (int)conn->port : conn->remote_port; store->scheme = conn->handler->scheme; if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) { store->sessionid = NULL; /* let caller free sessionid */ free(clone_host); free(clone_conn_to_host); return CURLE_OUT_OF_MEMORY; } return CURLE_OK; }