/* * call-seq: * session.timeout -> integer * * How long until the session expires in seconds. * */ static VALUE ossl_ssl_session_get_timeout(VALUE self) { SSL_SESSION *ctx; time_t t; GetSSLSession(self, ctx); t = SSL_SESSION_get_timeout(ctx); return TIMET2NUM(t); }
NOEXPORT int sess_new_cb(SSL *ssl, SSL_SESSION *sess) { unsigned char *val, *val_tmp; int val_len; val_len=i2d_SSL_SESSION(sess, NULL); val_tmp=val=str_alloc(val_len); i2d_SSL_SESSION(sess, &val_tmp); cache_transfer(ssl->ctx, CACHE_CMD_NEW, SSL_SESSION_get_timeout(sess), sess->session_id, sess->session_id_length, val, val_len, NULL, NULL); str_free(val); return 1; /* leave the session in local cache for reuse */ }
static int openssl_ssl_session_timeout(lua_State*L) { SSL_SESSION* session = CHECK_OBJECT(1, SSL_SESSION, "openssl.ssl_session"); int time; if (!lua_isnoneornil(L, 2)) { time = lua_tointeger(L, 2); time = SSL_SESSION_set_timeout(session, time); lua_pushinteger(L, time); return 1; } time = SSL_SESSION_get_timeout(session); lua_pushinteger(L, time); return 1; }
NOEXPORT void cache_new(SSL *ssl, SSL_SESSION *sess) { unsigned char *val, *val_tmp; ssize_t val_len; const unsigned char *session_id; unsigned int session_id_length; val_len=i2d_SSL_SESSION(sess, NULL); val_tmp=val=str_alloc((size_t)val_len); i2d_SSL_SESSION(sess, &val_tmp); #if OPENSSL_VERSION_NUMBER>=0x0090800fL session_id=SSL_SESSION_get_id(sess, &session_id_length); #else session_id=(const unsigned char *)sess->session_id; session_id_length=sess->session_id_length; #endif cache_transfer(SSL_get_SSL_CTX(ssl), CACHE_CMD_NEW, SSL_SESSION_get_timeout(sess), session_id, session_id_length, val, (size_t)val_len, NULL, NULL); str_free(val); }
static pn_ssl_session_t *ssn_cache_find( pn_ssl_domain_t *domain, const char *id ) { pn_timestamp_t now_msec = pn_i_now(); long now_sec = (long)(now_msec / 1000); pn_ssl_session_t *ssn = LL_HEAD( domain, ssn_cache ); while (ssn) { long expire = SSL_SESSION_get_time( ssn->session ) + SSL_SESSION_get_timeout( ssn->session ); if (expire < now_sec) { pn_ssl_session_t *next = ssn->ssn_cache_next; LL_REMOVE( domain, ssn_cache, ssn ); ssl_session_free( ssn ); ssn = next; continue; } if (!strcmp(ssn->id, id)) { break; } ssn = ssn->ssn_cache_next; } return ssn; }
enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb) { SSL *ssl = NULL; int rslt; char const* origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); PUBNUB_ASSERT_OPT((pb->state == PBS_READY) || (pb->state == PBS_WAIT_CONNECT)); if (!pb->options.useSSL) { return resolv_and_connect_wout_SSL(pb); } if (NULL == pb->pal.ctx) { PUBNUB_LOG_TRACE("pb=%p: Don't have SSL_CTX\n", pb); pb->pal.ctx = SSL_CTX_new(SSLv23_client_method()); if (NULL == pb->pal.ctx) { ERR_print_errors_cb(print_to_pubnub_log, NULL); PUBNUB_LOG_ERROR("pb=%p SSL_CTX_new failed\n", pb); return pbpal_resolv_resource_failure; } PUBNUB_LOG_TRACE("pb=%p: Got SSL_CTX\n", pb); add_pubnub_cert(pb->pal.ctx); } if (NULL == pb->pal.socket) { PUBNUB_LOG_TRACE("pb=%p: Don't have BIO\n", pb); pb->pal.socket = BIO_new_ssl_connect(pb->pal.ctx); if (PUBNUB_TIMERS_API) { pb->pal.connect_timeout = time(NULL) + pb->transaction_timeout_ms/1000; } } else { BIO_get_ssl(pb->pal.socket, &ssl); if (NULL == ssl) { return resolv_and_connect_wout_SSL(pb); } ssl = NULL; } if (NULL == pb->pal.socket) { ERR_print_errors_cb(print_to_pubnub_log, NULL); return pbpal_resolv_resource_failure; } PUBNUB_LOG_TRACE("pb=%p: Using BIO == %p\n", pb, pb->pal.socket); BIO_get_ssl(pb->pal.socket, &ssl); PUBNUB_ASSERT(NULL != ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* maybe not auto_retry? */ if (pb->pal.session != NULL) { SSL_set_session(ssl, pb->pal.session); } BIO_set_conn_hostname(pb->pal.socket, origin); BIO_set_conn_port(pb->pal.socket, "https"); if (pb->pal.ip_timeout != 0) { if (pb->pal.ip_timeout < time(NULL)) { pb->pal.ip_timeout = 0; } else { PUBNUB_LOG_TRACE("SSL re-connect to: %d.%d.%d.%d\n", pb->pal.ip[0], pb->pal.ip[1], pb->pal.ip[2], pb->pal.ip[3]); BIO_set_conn_ip(pb->pal.socket, pb->pal.ip); } } BIO_set_nbio(pb->pal.socket, !pb->options.use_blocking_io); WATCH_ENUM(pb->options.use_blocking_io); if (BIO_do_connect(pb->pal.socket) <= 0) { if (BIO_should_retry(pb->pal.socket) && PUBNUB_TIMERS_API && (pb->pal.connect_timeout > time(NULL))) { PUBNUB_LOG_TRACE("pb=%p: BIO_should_retry\n", pb); return pbpal_connect_wouldblock; } /* Expire the IP for the next connect */ pb->pal.ip_timeout = 0; ERR_print_errors_cb(print_to_pubnub_log, NULL); if (pb->pal.session != NULL) { SSL_SESSION_free(pb->pal.session); pb->pal.session = NULL; } PUBNUB_LOG_ERROR("pb=%p: BIO_do_connect failed\n", pb); return pbpal_connect_failed; } PUBNUB_LOG_TRACE("pb=%p: BIO connected\n", pb); { int fd = BIO_get_fd(pb->pal.socket, NULL); socket_set_rcv_timeout(fd, pb->transaction_timeout_ms); } rslt = SSL_get_verify_result(ssl); if (rslt != X509_V_OK) { PUBNUB_LOG_WARNING("pb=%p: SSL_get_verify_result() failed == %d(%s)\n", pb, rslt, X509_verify_cert_error_string(rslt)); ERR_print_errors_cb(print_to_pubnub_log, NULL); if (pb->options.fallbackSSL) { BIO_free_all(pb->pal.socket); pb->pal.socket = NULL; return resolv_and_connect_wout_SSL(pb); } return pbpal_connect_failed; } PUBNUB_LOG_INFO("pb=%p: SSL session reused: %s\n", pb, SSL_session_reused(ssl) ? "yes" : "no"); if (pb->pal.session != NULL) { SSL_SESSION_free(pb->pal.session); } pb->pal.session = SSL_get1_session(ssl); if (0 == pb->pal.ip_timeout) { pb->pal.ip_timeout = SSL_SESSION_get_time(pb->pal.session) + SSL_SESSION_get_timeout(pb->pal.session); memcpy(pb->pal.ip, BIO_get_conn_ip(pb->pal.socket), 4); } PUBNUB_LOG_TRACE("pb=%p: SSL connected to IP: %d.%d.%d.%d\n", pb, pb->pal.ip[0], pb->pal.ip[1], pb->pal.ip[2], pb->pal.ip[3]); return pbpal_connect_success; }