/****************************************************************************** ****************************************************************************** ** Higher Level SSL_CTX Wrappers ** ****************************************************************************** ******************************************************************************/ static void log_callback(const SSL *ssl, int where, int ret) { const char *retstr = ""; int should_log = 0; lcbio_SOCKET *sock = SSL_get_app_data(ssl); /* Ignore low-level SSL stuff */ if (where & SSL_CB_ALERT) { should_log = 1; } if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) { should_log = 1; } if ((where & SSL_CB_EXIT) && ret == 0) { should_log = 1; } if (!should_log) { return; } retstr = SSL_alert_type_string(ret); lcb_log(LOGARGS(ssl, LCB_LOG_TRACE), "sock=%p: ST(0x%x). %s. R(0x%x)%s", (void*)sock, where, SSL_state_string_long(ssl), ret, retstr); if (where == SSL_CB_HANDSHAKE_DONE) { lcb_log(LOGARGS(ssl, LCB_LOG_DEBUG), "sock=%p. Using SSL version %s. Cipher=%s", (void*)sock, SSL_get_version(ssl), SSL_get_cipher_name(ssl)); } }
/** * Callback used for debugging */ static void sslLogCallback(const SSL *ssl, int where, int ret) { const char *retstr = ""; int should_log = 1; /* Ignore low-level SSL stuff */ if (where & SSL_CB_ALERT) { should_log = 1; } if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) { should_log = 1; } if ((where & SSL_CB_EXIT) && ret == 0) { should_log = 1; } if (!should_log) { return; } retstr = SSL_alert_type_string(ret); printf("ST(0x%x). %s. R(0x%x)%s\n", where, SSL_state_string_long(ssl), ret, retstr); if (where == SSL_CB_HANDSHAKE_DONE) { printf("Using SSL version %s. Cipher=%s\n", SSL_get_version(ssl), SSL_get_cipher_name(ssl)); } }
inline void DtlsTransport::onSSLInfo(int where, int ret) { MS_TRACE(); int w = where & -SSL_ST_MASK; const char* role; if (w & SSL_ST_CONNECT) role = "client"; else if (w & SSL_ST_ACCEPT) role = "server"; else role = "undefined"; if (where & SSL_CB_LOOP) { MS_DEBUG("[role:%s, action:'%s']", role, SSL_state_string_long(this->ssl)); } else if (where & SSL_CB_ALERT) { const char* alert_type; switch (*SSL_alert_type_string(ret)) { case 'W': alert_type = "warning"; break; case 'F': alert_type = "fatal"; break; default: alert_type = "undefined"; } if (where & SSL_CB_READ) MS_DEBUG("received DTLS %s alert: %s", alert_type, SSL_alert_desc_string_long(ret)); else if (where & SSL_CB_WRITE) MS_DEBUG("sending DTLS %s alert: %s", alert_type, SSL_alert_desc_string_long(ret)); else MS_DEBUG("DTLS %s alert: %s", alert_type, SSL_alert_desc_string_long(ret)); } else if (where & SSL_CB_EXIT) { if (ret == 0) MS_DEBUG("[role:%s, failed:'%s']", role, SSL_state_string_long(this->ssl)); else if (ret < 0) MS_DEBUG("role: %s, waiting:'%s']", role, SSL_state_string_long(this->ssl)); } else if (where & SSL_CB_HANDSHAKE_START) { MS_DEBUG("DTLS handshake start"); } else if (where & SSL_CB_HANDSHAKE_DONE) { MS_DEBUG("DTLS handshake done"); this->handshakeDoneNow = true; } // NOTE: checking SSL_get_shutdown(this->ssl) & SSL_RECEIVED_SHUTDOWN here upon // receipt of a close alert does not work (the flag is set after this callback). }
/****************************************************************************** ****************************************************************************** ** Higher Level SSL_CTX Wrappers ** ****************************************************************************** ******************************************************************************/ static void log_callback(const SSL *ssl, int where, int ret) { const char *retstr = ""; lcbio_SOCKET *sock = SSL_get_app_data(ssl); if (where & SSL_CB_ALERT) { retstr = SSL_alert_type_string(ret); } lcb_log(LOGARGS(ssl, LCB_LOG_TRACE), "sock=%p: ST(0x%x). %s. R(0x%x)%s", (void*)sock, where, SSL_state_string_long(ssl), ret, retstr); }
static void info_cb(const SSL *s, int where, int ret) { if (where & SSL_CB_ALERT) { HANDSHAKE_EX_DATA *ex_data = (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx)); if (where & SSL_CB_WRITE) { ex_data->alert_sent = ret; if (strcmp(SSL_alert_type_string(ret), "F") == 0 || strcmp(SSL_alert_desc_string(ret), "CN") == 0) ex_data->num_fatal_alerts_sent++; } else { ex_data->alert_received = ret; } } }
static int openssl_ssl_alert_string(lua_State*L) { int v = luaL_checkint(L, 1); int _long = lua_isnoneornil(L, 2) ? 0 : auxiliar_checkboolean(L, 2); const char* val; if (_long) val = SSL_alert_type_string_long(v); else val = SSL_alert_type_string(v); lua_pushstring(L, val); if (_long) val = SSL_alert_desc_string_long(v); else val = SSL_alert_desc_string(v); lua_pushstring(L, val); return 2; }
/** * This function tracks the status changes from libssl to manage local * object state. */ void info_callback(const SSL *ssl, int where, int ret) { int idx, i; struct sockaddr_storage peer; struct sockaddr_storage peer2; char addr[INET6_ADDRSTRLEN]; char port[6]; if (where & SSL_CB_LOOP) /* do not care for intermediary states */ return; memset(&peer, 0, sizeof(peer)); (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); /* lookup SSL object */ /* FIXME: need to get the ifindex */ idx = get_index_of_peer((struct sockaddr *)&peer, 0); if (idx >= 0) fprintf(stderr, "info_callback: assert: %d < 0 || %p == %p (storage: %p)\n", idx, ssl, ssl_peer_storage[idx]->ssl, ssl_peer_storage[idx]); if (idx >= 0 && ssl != ssl_peer_storage[idx]->ssl) { getnameinfo((struct sockaddr *)&peer, sizeof(peer), addr, sizeof(addr), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); fprintf(stderr," ssl: [%s]:%s ", addr, port); (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer2); getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), addr, sizeof(addr), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); fprintf(stderr," ssl_peer_storage[idx]->ssl: [%s]:%s\n", addr, port); fprintf(stderr, " hash:%lu h: %lu\n", hash_peer((const struct sockaddr *)&peer, 0), ssl_peer_storage[idx]->h); for (i = 0; i < MAX_SSL_PEERS; i++) { if (ssl_peer_storage[i]) { fprintf(stderr, "%02d: %p ssl: %p ", i, ssl_peer_storage[i] ,ssl_peer_storage[i]->ssl); (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[i]->ssl), &peer2); getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), addr, sizeof(addr), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); fprintf(stderr," peer: [%s]:%s h: %lu\n", addr, port, ssl_peer_storage[i]->h); } } fprintf(stderr, "***** ASSERT FAILED ******\n"); memset(&peer, 0, sizeof(peer)); (void) BIO_dgram_get_peer(SSL_get_wbio(ssl), &peer); idx = get_index_of_peer((struct sockaddr *)&peer, 0); fprintf(stderr, " get_index_of_peer for wbio returns %d, type is %04x\n", idx, where); } #if 1 check_peers(); OPENSSL_assert((idx < 0) || (ssl == ssl_peer_storage[idx]->ssl)); #endif if (where & SSL_CB_ALERT) { #ifndef NDEBUG if (ret != 0) fprintf(stderr,"%s:%s:%s\n", SSL_alert_type_string(ret), SSL_alert_desc_string(ret), SSL_alert_desc_string_long(ret)); #endif /* examine alert type */ switch (*SSL_alert_type_string(ret)) { case 'F': /* move SSL object from pending to close */ if (idx >= 0) { ssl_peer_storage[idx]->state = PEER_ST_CLOSED; pending--; } break; case 'W': if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) { if (where == SSL_CB_WRITE_ALERT) fprintf(stderr,"sent CLOSE_NOTIFY\n"); else /* received CN */ fprintf(stderr,"received CLOSE_NOTIFY\n"); } break; default: /* handle unknown alert types */ #ifndef NDEBUG printf("not handled!\n"); #endif } } if (where & SSL_CB_HANDSHAKE_DONE) { /* move SSL object from pending to established */ printf("HANDSHAKE_DONE "); if (idx >= 0) { if (ssl_peer_storage[idx]->state == PEER_ST_PENDING) { ssl_peer_storage[idx]->state = PEER_ST_ESTABLISHED; pending--; printf("moved SSL object %d to ESTABLISHED\n", idx); printf("%d objects pending\n", pending); } else { #ifndef NDEBUG printf("huh, object %d was not pending? (%d)\n", idx, ssl_peer_storage[idx]->state); #endif } return; } return; } return; }