diff options
Diffstat (limited to 'entry/src/sslstat_entry.cpp')
| -rw-r--r-- | entry/src/sslstat_entry.cpp | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/entry/src/sslstat_entry.cpp b/entry/src/sslstat_entry.cpp new file mode 100644 index 0000000..70b4323 --- /dev/null +++ b/entry/src/sslstat_entry.cpp @@ -0,0 +1,131 @@ + + + +#include "base_utils.h" +#include "stream_inc/stream_base.h" +#include "stream_inc/stream_entry.h" +#include "ssl.h" +#include "cjson/cJSON.h" + +#define CERT_COUNT_MAX 16 + +struct ssl_context{ + char sip[INET_ADDRSTRLEN]; + int sport; + char dip[INET_ADDRSTRLEN]; + int dport; + unsigned char *sni; + char *san; + int cert_count; + cert_chain_t certs[CERT_COUNT_MAX]; +}; + +FILE *g_fp = NULL; + +static char *ssl_assemble_san(st_cert_t *cert){ + int tmp_buflen = 0, total_buflen = 0; + char *san_buf = NULL; + for (int i = 0; i < cert->SSLSubAltName->count; i++){ + tmp_buflen = strlen(cert->SSLSubAltName->san_array[i].san); + san_buf = (char *)realloc(san_buf, total_buflen + tmp_buflen + 1); + san_buf[total_buflen + tmp_buflen] = ';'; + memcpy(san_buf + total_buflen, cert->SSLSubAltName->san_array[i].san, tmp_buflen); + total_buflen += tmp_buflen + 1; + } + san_buf[total_buflen - 1] = '\0'; + return san_buf; +} + +void ssl_ctx_close(struct ssl_context *ctx, struct streaminfo *stream, ssl_stream *a_ssl){ + if (ctx != NULL){ + cJSON *log_obj = cJSON_CreateObject(); + cJSON_AddStringToObject(log_obj, "sip", ctx->sip); + cJSON_AddNumberToObject(log_obj, "sport", ctx->sport); + cJSON_AddStringToObject(log_obj, "dip", ctx->dip); + cJSON_AddNumberToObject(log_obj, "dport", ctx->dport); + cJSON_AddStringToObject(log_obj, "proto", "tcp"); + cJSON_AddStringToObject(log_obj, "sni", (const char*)ctx->sni); + cJSON_AddStringToObject(log_obj, "san", ctx->san); + //cert + cJSON *Cert = cJSON_CreateObject(); + cJSON_AddNumberToObject(Cert, "cert_count", ctx->cert_count); + cJSON *cert_info_list = cJSON_CreateArray(); + for(int i = 0; i < ctx->cert_count; i++){ + cJSON *cert_info = cJSON_CreateObject(); + cJSON_AddNumberToObject(cert_info, "length", ctx->certs[i].cert_len); + if(i == 0){ + cJSON_AddStringToObject(cert_info, "type", "individual"); + } + else{ + cJSON_AddStringToObject(cert_info, "type", "no-individual"); + } + cJSON_AddItemToArray(cert_info_list, cert_info); + } + cJSON_AddItemToObject(Cert, "cert_list", cert_info_list); + cJSON_AddItemToObject(log_obj, "Cert", Cert); + char *log_msg = cJSON_PrintUnformatted(log_obj); + fputs(log_msg, g_fp); + fputs("\n", g_fp); + cJSON_Delete(log_obj); + cJSON_free(log_msg); + FREE(&(ctx->san)) + FREE(&ctx); + } + return; +} + +extern "C" unsigned char sslstat_entry(stSessionInfo *session_info, void **param, int thread_seq, struct streaminfo *stream, void *a_packet){ + ssl_stream *a_ssl = (ssl_stream *)(session_info->app_info); + struct ssl_context *ctx = (ssl_context *)*param; + if ((session_info->session_state & SESSION_STATE_PENDING) == SESSION_STATE_PENDING){ + ctx = ALLOC(struct ssl_context, 1); + *param = ctx; + struct stream_tuple4_v4 *tuple4 = stream->addr.tuple4_v4; + inet_ntop(AF_INET, &(tuple4->saddr), ctx->sip, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &(tuple4->daddr), ctx->dip, INET_ADDRSTRLEN); + ctx->sport = ntohs(tuple4->source); + ctx->dport = ntohs(tuple4->dest); + } + switch (session_info->prot_flag){ + case SSL_CLIENT_HELLO: + if (a_ssl != NULL && a_ssl->stClientHello != NULL){ + ctx->sni = a_ssl->stClientHello->server_name; + } + break; + case SSL_CERTIFICATE: + ctx->cert_count = ssl_read_all_cert((const char*)session_info->buf, session_info->buflen, ctx->certs, CERT_COUNT_MAX); + case SSL_CERTIFICATE_DETAIL: + if (a_ssl != NULL && a_ssl->stSSLCert != NULL && stream->curdir == DIR_S2C){ + st_cert_t *cert = a_ssl->stSSLCert; + if (cert->cert_type == CERT_TYPE_INDIVIDUAL){ + if (cert->SSLSubAltName != NULL && cert->SSLSubAltName->count > 0){ + char *san_buf = ssl_assemble_san(cert); + ctx->san = san_buf; + } + } + } + break; + case SSL_APPLICATION_DATA: + break; + default: + break; + } + + if ((session_info->session_state & SESSION_STATE_CLOSE) == SESSION_STATE_CLOSE){ + +//close_ssl: + ssl_ctx_close(ctx, stream, (ssl_stream *)session_info->app_info); + return PROT_STATE_DROPME; + } + return PROT_STATE_GIVEME; +} + + +extern "C" int sslstat_init(){ + g_fp = fopen("./ssl_stat.txt", "a+"); + return 0; +} + +extern "C" void sslstat_destroy(void){ + return; +}
\ No newline at end of file |
