diff --git a/src/sniffer.c b/src/sniffer.c index 70bccedde..ca33f19df 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -406,6 +406,10 @@ static int RecoveryEnabled = 0; /* global switch */ static int MaxRecoveryMemory = -1; /* per session max recovery memory */ static word32 MissedDataSessions = 0; /* # of sessions with missed data */ +/* Connection Info Callback */ +static SSLConnCb ConnectionCb; +static void* ConnectionCbCtx = NULL; + static void UpdateMissedDataSessions(void) { @@ -1490,6 +1494,58 @@ static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size) } +/* Copies the session's infomation to the provided sslInfo. Skip copy if + * SSLInfo is not provided. */ +static void CopySessionInfo(SnifferSession* session, SSLInfo* sslInfo) +{ + if (NULL != sslInfo) { + XMEMSET(sslInfo, 0, sizeof(SSLInfo)); + + /* Pass back Session Info after we have processed the Server Hello. */ + if (0 != session->sslServer->options.cipherSuite) { + const char* pCipher; + + sslInfo->isValid = 1; + sslInfo->protocolVersionMajor = session->sslServer->version.major; + sslInfo->protocolVersionMinor = session->sslServer->version.minor; + sslInfo->serverCipherSuite0 = + session->sslServer->options.cipherSuite0; + sslInfo->serverCipherSuite = + session->sslServer->options.cipherSuite; + + pCipher = wolfSSL_get_cipher(session->sslServer); + if (NULL != pCipher) { + XSTRNCPY((char*)sslInfo->serverCipherSuiteName, pCipher, + sizeof(sslInfo->serverCipherSuiteName)); + sslInfo->serverCipherSuiteName + [sizeof(sslInfo->serverCipherSuiteName) - 1] = '\0'; + } + sslInfo->keySize = session->keySz; + #ifdef HAVE_SNI + if (NULL != session->sni) { + XSTRNCPY((char*)sslInfo->serverNameIndication, + session->sni, sizeof(sslInfo->serverNameIndication)); + sslInfo->serverNameIndication + [sizeof(sslInfo->serverNameIndication) - 1] = '\0'; + } + #endif + TraceSessionInfo(sslInfo); + } + } +} + + +/* Call the session connection start callback. */ +static void CallConnectionCb(SnifferSession* session) +{ + if (ConnectionCb != NULL) { + SSLInfo info; + CopySessionInfo(session, &info); + ConnectionCb((const void*)session, &info, ConnectionCbCtx); + } +} + + /* Process Client Key Exchange, RSA or static ECDH */ static int ProcessClientKeyExchange(const byte* input, int* sslBytes, SnifferSession* session, char* error) @@ -1698,6 +1754,8 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes, } #endif + CallConnectionCb(session); + return ret; } @@ -2521,6 +2579,10 @@ static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo, session->cliSeqStart = tcpInfo->sequence; session->cliExpected = 1; /* relative */ session->lastUsed= time(NULL); + session->keySz = 0; +#ifdef HAVE_SNI + session->sni = NULL; +#endif session->context = GetSnifferServer(ipInfo, tcpInfo); if (session->context == NULL) { @@ -3600,47 +3662,6 @@ static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo, } -/* Copies the session's infomation to the provided sslInfo. Skip copy if - * SSLInfo is not provided. */ -static void CopySessionInfo(SnifferSession* session, SSLInfo* sslInfo) -{ - if (NULL != sslInfo) { - XMEMSET(sslInfo, 0, sizeof(SSLInfo)); - - /* Pass back Session Info after we have processed the Server Hello. */ - if (0 != session->sslServer->options.cipherSuite) { - const char* pCipher; - - sslInfo->isValid = 1; - sslInfo->protocolVersionMajor = session->sslServer->version.major; - sslInfo->protocolVersionMinor = session->sslServer->version.minor; - sslInfo->serverCipherSuite0 = - session->sslServer->options.cipherSuite0; - sslInfo->serverCipherSuite = - session->sslServer->options.cipherSuite; - - pCipher = wolfSSL_get_cipher(session->sslServer); - if (NULL != pCipher) { - XSTRNCPY((char*)sslInfo->serverCipherSuiteName, pCipher, - sizeof(sslInfo->serverCipherSuiteName)); - sslInfo->serverCipherSuiteName - [sizeof(sslInfo->serverCipherSuiteName) - 1] = '\0'; - } - sslInfo->keySize = session->keySz; - #ifdef HAVE_SNI - if (NULL != session->sni) { - XSTRNCPY((char*)sslInfo->serverNameIndication, - session->sni, sizeof(sslInfo->serverNameIndication)); - sslInfo->serverNameIndication - [sizeof(sslInfo->serverNameIndication) - 1] = '\0'; - } - #endif - TraceSessionInfo(sslInfo); - } - } -} - - /* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */ /* returns Number of bytes on success, 0 for no data yet, and -1 on error */ static int ssl_DecodePacketInternal(const byte* packet, int length, @@ -3808,5 +3829,21 @@ int ssl_GetSessionStats(unsigned int* active, unsigned int* total, +int ssl_SetConnectionCb(SSLConnCb cb) +{ + ConnectionCb = cb; + return 0; +} + + + +int ssl_SetConnectionCtx(void* ctx) +{ + ConnectionCbCtx = ctx; + return 0; +} + + + #endif /* WOLFSSL_SNIFFER */ #endif /* WOLFCRYPT_ONLY */ diff --git a/wolfssl/sniffer.h b/wolfssl/sniffer.h index aef4d4b0d..33b26da87 100644 --- a/wolfssl/sniffer.h +++ b/wolfssl/sniffer.h @@ -125,6 +125,14 @@ SSL_SNIFFER_API int ssl_DecodePacketWithSessionInfo( const unsigned char* packet, int length, unsigned char** data, SSLInfo* sslInfo, char* error); +typedef void (*SSLConnCb)(const void* session, SSLInfo* info, void* ctx); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetConnectionCb(SSLConnCb cb); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_SetConnectionCtx(void* ctx); + #ifdef __cplusplus } /* extern "C" */