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; }