diff options
Diffstat (limited to 'src/ssl_decoder.cpp')
| -rw-r--r-- | src/ssl_decoder.cpp | 585 |
1 files changed, 376 insertions, 209 deletions
diff --git a/src/ssl_decoder.cpp b/src/ssl_decoder.cpp index ffbbe17..059ae77 100644 --- a/src/ssl_decoder.cpp +++ b/src/ssl_decoder.cpp @@ -38,8 +38,29 @@ extern "C" #include "ssl_internal.h" #include "ssl_decoder.h" +#define SSL_TRUNK_MESSAGE_TOPIC "SSL_TRUNK_MESSAGE" + UT_icd UT_ssl_hello_extension_icd={sizeof(struct ssl_decoder_ltv), NULL, NULL, NULL}; +#define SSL_TRUNK_MAGIC 0x5a5a5a5a +enum SSL_TRUNK_TYPE +{ + SSL_TRUNK_TYPE_NONE=0, + SSL_TRUNK_TYPE_MOVE, + SSL_TRUNK_TYPE_APPEND, + SSL_TRUNK_TYPE_FREE, + SSL_TRUNK_TYPE_MAX, +}; + +struct ssl_trunk_message +{ + uint32_t magic; + enum SSL_TRUNK_TYPE type; + struct ssl_record_trunk *record_trunk; + uint8_t *pdata; + size_t pdata_sz; +}; + struct ssl_certificate_chain { uint8_t *data; @@ -62,9 +83,10 @@ struct ssl_record_header struct ssl_record_trunk { - struct ssl_record_header header; - size_t cache_len; - uint8_t* cache_buff; + uint8_t is_contains_header; + struct ssl_record_header record_hdr; + size_t data_sz; + uint8_t *data; }; #define SSL_NAME_MAX 256 @@ -96,6 +118,8 @@ struct ssl_decoder_plugin_env int32_t n_net_port; int32_t max_cache_len; struct message_schema ssl; + struct message_schema ptrunk; + struct message_schema strunk; struct message_schema tcp_stream; struct ssl_decoder_stat stat; }; @@ -106,6 +130,75 @@ struct ssl_decoder_context struct ssl_record_trunk record_trunk; }; +int32_t ssl_read_u8(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value) +{ + if(pdata_sz<(*pdata_offset)+1) + { + return SSL_DECODER_FALSE; + } + + if(value!=NULL) + { + *value=(uint8_t)pdata[(*pdata_offset)]; + } + + (*pdata_offset)++; + return SSL_DECODER_TRUE; +} + +int32_t ssl_read_be_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value) +{ + if(pdata_sz<(*pdata_offset)+2) + { + return SSL_DECODER_FALSE; + } + + if(value!=NULL) + { + *value=((uint16_t)pdata[*pdata_offset] << 8) | (uint16_t)pdata[*pdata_offset+1]; + } + + (*pdata_offset)+=2; + return SSL_DECODER_TRUE; +} + +int32_t ssl_read_be_u24(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value) +{ + if(pdata_sz<(*pdata_offset)+3) + { + return SSL_DECODER_FALSE; + } + + if(value!=NULL) + { + ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[2]); + ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[1]); + ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[0]); + } + else + { + (*pdata_offset)+=3; + } + + return SSL_DECODER_TRUE; +} + +int32_t ssl_read_be_u32(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint32_t *value) +{ + if(pdata_sz<(*pdata_offset)+4) + { + return SSL_DECODER_FALSE; + } + + if(value!=NULL) + { + *value=ntohl(*(uint32_t *)(pdata+(*pdata_offset))); + } + + (*pdata_offset)+=4; + return SSL_DECODER_TRUE; +} + void ssl_hello_md5sum(struct ssl_decoder_ltv *ltv, const char *str, size_t str_sz) { MD5_CTX ctx; @@ -150,123 +243,160 @@ void ssl_trunk_free(struct ssl_record_trunk *record_trunk) { if(record_trunk!=NULL) { - if(record_trunk->cache_buff!=NULL) + if(record_trunk->data!=NULL) { - FREE(record_trunk->cache_buff); - record_trunk->cache_buff=NULL; + FREE(record_trunk->data); } - record_trunk={0}; + record_trunk->data=NULL; + record_trunk->data_sz=0; + record_trunk->is_contains_header=SSL_DECODER_TRUE; + record_trunk->record_hdr={0}; } } -void ssl_trunk_cache(struct ssl_record_trunk *record_trunk, uint8_t *fragment, size_t fragment_sz) +void ssl_trunk_cache(struct ssl_record_trunk *record_trunk, enum SSL_TRUNK_TYPE type, uint8_t *fragment, size_t fragment_sz) { - if(fragment==NULL || fragment_sz==0) + if(record_trunk==NULL || fragment==NULL || fragment_sz==0) { return ; } - if(record_trunk->cache_buff==NULL) - { - record_trunk->cache_buff=(uint8_t *)malloc(fragment_sz); - } - - memmove(record_trunk->cache_buff+record_trunk->cache_len, fragment, fragment_sz); - record_trunk->cache_len+=fragment_sz; + switch(type) + { + case SSL_TRUNK_TYPE_MOVE: + { + uint8_t *tmp=(uint8_t *)malloc(fragment_sz); + memcpy(tmp, fragment, fragment_sz); + if(record_trunk->data!=NULL) + { + FREE(record_trunk->data); + } + record_trunk->data=tmp; + record_trunk->data_sz=fragment_sz; + } + break; + case SSL_TRUNK_TYPE_APPEND: + record_trunk->data=(record_trunk->data==NULL) ? (uint8_t *)malloc(fragment_sz) : (uint8_t *)realloc(record_trunk->data, record_trunk->data_sz+fragment_sz); + memcpy(record_trunk->data+record_trunk->data_sz, fragment, fragment_sz); + record_trunk->data_sz+=fragment_sz; + break; + default: + break; + } } int32_t is_trunk_cache(struct ssl_record_trunk *record_trunk) { - return ((record_trunk->cache_len>0) ? SSL_DECODER_TRUE : SSL_DECODER_FALSE); + return ((record_trunk->data_sz>0) ? SSL_DECODER_TRUE : SSL_DECODER_FALSE); } -void ssl_recod_buff_get0(struct ssl_record_trunk *record_trunk, uint8_t **record_buff, size_t *record_buff_sz) +int32_t ssl_record_header_get(struct ssl_record_header *record_hdr, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) { - if(!is_trunk_cache(record_trunk) || (*record_buff_sz)<=SSL_RECORD_HEADER_SZ) - { - return ; - } + if(pdata_sz<(*pdata_offset)+SSL_RECORD_HEADER_SZ) + { + return SSL_DECODER_FALSE; + } - ssl_trunk_cache(record_trunk, (*record_buff), (*record_buff_sz)); + ssl_read_u8(pdata, pdata_sz, pdata_offset, &(record_hdr->content_type)); + ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->version)); + ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->total_len)); - (*record_buff)=record_trunk->cache_buff; - (*record_buff_sz)=record_trunk->cache_len; + return SSL_DECODER_TRUE; } -void ssl_handshake_server_key_exchange_decode() +void ssl_recod_buff_get0(struct ssl_record_trunk *record_trunk, uint8_t **record_buff, size_t *record_buff_sz) { + if(!is_trunk_cache(record_trunk) && (*record_buff_sz)>SSL_RECORD_HEADER_SZ) + { + return ; + } -} - - -int32_t ssl_read_u8(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value) -{ - if(pdata_sz<(*pdata_offset)+1) + if(record_trunk->is_contains_header==SSL_DECODER_TRUE) { - return SSL_DECODER_FALSE; + ssl_trunk_cache(record_trunk, SSL_TRUNK_TYPE_APPEND, (*record_buff), (*record_buff_sz)); } - - if(value!=NULL) + else { - *value=(uint8_t)pdata[(*pdata_offset)]; + size_t offset=0; + struct ssl_record_header record_hdr={0}; + ssl_record_header_get(&record_hdr, *record_buff, *record_buff_sz, &offset); + if(record_hdr.content_type!=record_trunk->record_hdr.content_type) + { + ssl_trunk_free(record_trunk); + return ; + } + + if((*record_buff_sz)<SSL_RECORD_HEADER_SZ) + { + return ; + } + + ssl_trunk_cache(record_trunk, SSL_TRUNK_TYPE_APPEND, (*record_buff)+SSL_RECORD_HEADER_SZ, (*record_buff_sz)-SSL_RECORD_HEADER_SZ); } - - (*pdata_offset)++; - return SSL_DECODER_TRUE; + + + (*record_buff)=record_trunk->data; + (*record_buff_sz)=record_trunk->data_sz; } -int32_t ssl_read_be_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value) +void ssl_trunk_message_segment_data_cb(struct session *ss, int32_t topic_id, const void *msg, void *per_session_ctx, void *penv) { - if(pdata_sz<(*pdata_offset)+2) + struct ssl_trunk_message *trunk_msg=(struct ssl_trunk_message *)msg; + if(trunk_msg==NULL || trunk_msg->magic!=SSL_TRUNK_MAGIC) { - return SSL_DECODER_FALSE; + return ; } - - if(value!=NULL) + + switch(trunk_msg->type) { - *value=((uint16_t)pdata[*pdata_offset] << 8) | (uint16_t)pdata[*pdata_offset+1]; + case SSL_TRUNK_TYPE_MOVE: + ssl_trunk_cache(trunk_msg->record_trunk, SSL_TRUNK_TYPE_MOVE, trunk_msg->pdata, trunk_msg->pdata_sz); + break; + case SSL_TRUNK_TYPE_APPEND: + ssl_trunk_cache(trunk_msg->record_trunk, SSL_TRUNK_TYPE_APPEND, trunk_msg->pdata, trunk_msg->pdata_sz); + break; + case SSL_TRUNK_TYPE_FREE: + ssl_trunk_free(trunk_msg->record_trunk); + break; + default: + break; } - - (*pdata_offset)+=2; - return SSL_DECODER_TRUE; } -int32_t ssl_read_be_u24(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value) +void ssl_trunk_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, struct ssl_record_trunk *record_trunk, uint8_t *pdata, size_t pdata_sz) { - if(pdata_sz<(*pdata_offset)+3) - { - return SSL_DECODER_FALSE; + struct ssl_trunk_message *message=(struct ssl_trunk_message *)malloc(sizeof(struct ssl_trunk_message)); + message->magic=SSL_TRUNK_MAGIC; + message->record_trunk=record_trunk; + message->pdata=pdata; + message->pdata_sz=pdata_sz; + if(pdata_sz==0) + { + message->type=SSL_TRUNK_TYPE_FREE; } - - if(value!=NULL) + else { - ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[2]); - ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[1]); - ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[0]); + message->type=((is_trunk_cache(record_trunk)) ? SSL_TRUNK_TYPE_MOVE : SSL_TRUNK_TYPE_APPEND); } - else + + if(((long long)pdata_sz) <0) { - (*pdata_offset)+=3; + abort(); } - - return SSL_DECODER_TRUE; + + session_mq_publish_message(ss, plugin_env->ptrunk.topic_id, (void *)message); } -int32_t ssl_read_be_u32(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint32_t *value) +void ssl_trunk_message_free(struct session *sess, void *msg, void *msg_free_arg) { - if(pdata_sz<(*pdata_offset)+4) - { - return SSL_DECODER_FALSE; - } - - if(value!=NULL) + struct ssl_trunk_message *trunk_msg=(struct ssl_trunk_message *)msg; + if(trunk_msg==NULL) { - *value=ntohl(*(uint32_t *)(pdata+(*pdata_offset))); + return ; } - - (*pdata_offset)+=4; - return SSL_DECODER_TRUE; + + FREE(trunk_msg); } int32_t ssl_decoder_ltv_get(struct ssl_decoder_ltv *ltv, uint16_t type, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) @@ -723,7 +853,7 @@ struct ssl_client_hello *ssl_handshake_client_hello_decode(uint8_t *pdata, size_ utarray_push_back(chello->extensions, <v); - switch(ltv.type) + switch(ltv.vtype) { case SERVER_NAME_EXT_TYPE: { @@ -900,7 +1030,7 @@ int32_t ssl_client_hello_ja3_generate(struct ssl_client_hello *chello) return SSL_DECODER_TRUE; } -void ssl_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, enum ssl_message_type type, void *data) +void ssl_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, enum ssl_message_type type, void *data, size_t data_sz) { struct ssl_message *message=(struct ssl_message *)malloc(sizeof(struct ssl_message)); message->magic=SSL_MESSAGE_MAGIC; @@ -908,11 +1038,11 @@ void ssl_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct sessi message->ss=ss; message->plugin_env=plugin_env; message->data=data; + message->data_sz=data_sz; session_mq_publish_message(ss, plugin_env->ssl.topic_id, (void *)message); } - void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg) { struct ssl_message *message=(struct ssl_message *)msg; @@ -932,6 +1062,8 @@ void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg) { utarray_free(chello->extensions); } + + FREE(message->data); } break; case SSL_MESSAGE_SERVER_HELLO: @@ -941,6 +1073,8 @@ void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg) { utarray_free(shello->extensions); } + + FREE(message->data); } break; case SSL_MESSAGE_CERTIFICATE: @@ -955,103 +1089,112 @@ void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg) { FREE(certificate->subject_key.value); } + + FREE(message->data); } break; default: break; } - - FREE(message->data); } FREE(message); } - -void ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) +int32_t ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, size_t total_sz) { if(pdata==NULL || ((*pdata_offset)+1>pdata_sz)) { - return ; + return SSL_DECODER_FALSE; } - struct ssl_handshake_type *handshake_type=(struct ssl_handshake_type *)(pdata+(*pdata_offset)); - (*pdata_offset)+=sizeof(struct ssl_handshake_type); - - int32_t total_len=0; - int32_t ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&total_len); - if(ret==SSL_DECODER_FALSE || total_len<0 || total_len+(*pdata_offset)>pdata_sz) + size_t hd_offset=0; + while(total_sz>hd_offset && pdata_sz>(*pdata_offset)) { - return ; - } + struct ssl_handshake_type *handshake_type=(struct ssl_handshake_type *)(pdata+(*pdata_offset)); + if(handshake_type->content_type==SSL_HANDSHAKE_ENCRYPTED_MESSAGE) + { + hd_offset=total_sz; + (*pdata_offset)+=total_sz; + return SSL_DECODER_TRUE; + } - switch(handshake_type->content_type) - { - case SSL_HANDSHAKE_CLIENT_HELLO: - { - struct ssl_client_hello *chello=ssl_handshake_client_hello_decode(pdata, pdata_sz, pdata_offset); - ssl_client_hello_ja3_generate(chello); - ssl_message_publish(plugin_env, ss, SSL_MESSAGE_CLIENT_HELLO, (void *)chello); - } - break; - case SSL_HANDSHAKE_SERVER_HELLO: - { - struct ssl_server_hello *shello=ssl_handshake_server_hello_decode(pdata, pdata_sz, pdata_offset); - ssl_server_hello_ja3s_generate(shello); - ssl_message_publish(plugin_env, ss, SSL_MESSAGE_SERVER_HELLO, (void *)shello); - } - break; - case SSL_HANDSHAKE_CERTIFICATE: - { - int32_t cert_total_len=0; - ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&cert_total_len); - if(ret==SSL_DECODER_FALSE || cert_total_len<0 || cert_total_len+(*pdata_offset)>pdata_sz || (cert_total_len+3)!=total_len) - { - return ; - } + (*pdata_offset)+=sizeof(struct ssl_handshake_type); - struct ssl_certificate_chain cert_unit[SSL_CERTIFICATE_NUM_MAX]; - uint32_t cert_count=ssl_handshake_certificate_count_get(pdata, pdata_sz, pdata_offset, cert_unit, SSL_CERTIFICATE_NUM_MAX); + int32_t total_len=0; + int32_t ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&total_len); + if(ret==SSL_DECODER_FALSE) + { + return SSL_DECODER_CONTINUE; + } - for(uint32_t i=0, cert_offset=0; i<cert_count; i++, cert_offset++) - { - struct ssl_certificate *certificate=(struct ssl_certificate *)CALLOC(struct ssl_certificate, 1); + if(total_len<0) + { + return SSL_DECODER_FALSE; + } - certificate->type=ssl_handshake_certificate_type_get(cert_count, cert_offset); - int32_t state=ssl_x509_certificate_detail_decode(certificate, cert_unit[i].data, cert_unit[i].data_sz); - if(state==SSL_DECODER_FALSE) + if(total_len+(*pdata_offset)>pdata_sz) + { + return SSL_DECODER_CONTINUE; + } + + size_t offset=(*pdata_offset); + (*pdata_offset)+=total_len; + hd_offset+=total_len+4; + + switch(handshake_type->content_type) + { + case SSL_HANDSHAKE_CLIENT_HELLO: + { + struct ssl_client_hello *chello=ssl_handshake_client_hello_decode(pdata, pdata_sz, &offset); + ssl_client_hello_ja3_generate(chello); + ssl_message_publish(plugin_env, ss, SSL_MESSAGE_CLIENT_HELLO, (void *)chello, sizeof(struct ssl_client_hello)); + } + break; + case SSL_HANDSHAKE_SERVER_HELLO: + { + struct ssl_server_hello *shello=ssl_handshake_server_hello_decode(pdata, pdata_sz, &offset); + ssl_server_hello_ja3s_generate(shello); + ssl_message_publish(plugin_env, ss, SSL_MESSAGE_SERVER_HELLO, (void *)shello, sizeof(struct ssl_server_hello)); + } + break; + case SSL_HANDSHAKE_CERTIFICATE: + { + int32_t cert_total_len=0; + ret=ssl_read_be_u24(pdata, pdata_sz, &offset, (uint8_t *)&cert_total_len); + if(ret==SSL_DECODER_FALSE || cert_total_len<0 || cert_total_len+offset>pdata_sz || (cert_total_len+3)!=total_len) { - FREE(certificate); - return ; + break; } - ssl_message_publish(plugin_env, ss, SSL_MESSAGE_CERTIFICATE, (void *)certificate); - } - } - break; - case SSL_HANDSHAKE_SERVER_KEY_EXCHANGE: - // ssl_handshake_server_key_exchange_decode(); - break; - default: - break; - } -} + struct ssl_certificate_chain cert_unit[SSL_CERTIFICATE_NUM_MAX]; + uint32_t cert_count=ssl_handshake_certificate_count_get(pdata, pdata_sz, &offset, cert_unit, SSL_CERTIFICATE_NUM_MAX); -int32_t ssl_record_header_get(struct ssl_record_header *record_hdr, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) -{ - if(pdata_sz<(*pdata_offset)+SSL_RECORD_HEADER_SZ) - { - return SSL_DECODER_FALSE; - } + for(uint32_t i=0, cert_offset=0; i<cert_count; i++, cert_offset++) + { + struct ssl_certificate *certificate=(struct ssl_certificate *)CALLOC(struct ssl_certificate, 1); - ssl_read_u8(pdata, pdata_sz, pdata_offset, &(record_hdr->content_type)); - ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->version)); - ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->total_len)); + certificate->type=ssl_handshake_certificate_type_get(cert_count, cert_offset); + int32_t state=ssl_x509_certificate_detail_decode(certificate, cert_unit[i].data, cert_unit[i].data_sz); + if(state==SSL_DECODER_FALSE) + { + FREE(certificate); + break; + } + + ssl_message_publish(plugin_env, ss, SSL_MESSAGE_CERTIFICATE, (void *)certificate, sizeof(struct ssl_certificate)); + } + } + break; + case SSL_HANDSHAKE_SERVER_KEY_EXCHANGE: + default: + break; + } + } return SSL_DECODER_TRUE; } - void ssl_tcp_stream_session_segment_data_cb(struct session *ss, int32_t topic_id, const void *msg, void *per_session_ctx, void *penv) { size_t pdata_offset=0; @@ -1063,48 +1206,84 @@ void ssl_tcp_stream_session_segment_data_cb(struct session *ss, int32_t topic_id return ; } - /* - * fragment: - 1: less than SSL_RECORD_HEADER_SZ - 2: less than the length of the message - */ - - struct ssl_decoder_context *per_ss_ctx=(struct ssl_decoder_context *)(per_session_ctx); - + // fragment: 1: less than SSL_RECORD_HEADER_SZ; 2: less than the length of the message; 3: multiple record messages + struct ssl_decoder_plugin_env *plugin_env=(struct ssl_decoder_plugin_env *)penv; + struct ssl_decoder_context *per_ss_ctx=(struct ssl_decoder_context *)(per_session_ctx); ssl_recod_buff_get0(&(per_ss_ctx->record_trunk), &pdata, &pdata_sz); if(pdata_sz<=SSL_RECORD_HEADER_SZ) { return ; } - struct ssl_record_header record_hdr={0}; - ssl_record_header_get(&record_hdr, pdata, pdata_sz, &pdata_offset); - if(!is_trunk_cache(&(per_ss_ctx->record_trunk)) && pdata_sz<record_hdr.total_len) + while(pdata_sz>pdata_offset) { - ssl_trunk_cache(&(per_ss_ctx->record_trunk), pdata, pdata_sz); - return ; - } + struct ssl_record_header record_hdr={0}; + if(per_ss_ctx->record_trunk.is_contains_header==SSL_DECODER_TRUE) + { + ssl_record_header_get(&record_hdr, pdata, pdata_sz, &pdata_offset); + } + else + { + record_hdr=per_ss_ctx->record_trunk.record_hdr; + record_hdr.total_len=pdata_sz; + } - struct ssl_decoder_plugin_env *plugin_env=(struct ssl_decoder_plugin_env *)penv; + int32_t ret=SSL_DECODER_TRUE; + size_t offset=pdata_offset; + switch(record_hdr.content_type) + { + case SSL_CONTENT_TYPE_HANDSHAKE: + if(pdata_sz-pdata_offset<record_hdr.total_len) + { + pdata_offset-=5; + ret=SSL_DECODER_FALSE; + per_ss_ctx->record_trunk.record_hdr=record_hdr; + per_ss_ctx->record_trunk.is_contains_header=SSL_DECODER_TRUE; + break; + } + else + { + ret=ssl_handshake_decode(plugin_env, ss, pdata, pdata_sz, &offset, record_hdr.total_len); + pdata_offset=((ret==SSL_DECODER_FALSE) ? pdata_sz : pdata_offset); + } + break; + case SSL_CONTENT_TYPE_APPLICATION_DATA: + ssl_message_publish(plugin_env, ss, SSL_MESSAGE_ENCRYPTED_APPLICATION, (void *)(pdata+offset), record_hdr.total_len); + offset+=record_hdr.total_len; + break; + case SSL_CONTENT_TYPE_ALERT: + case SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC: + offset+=record_hdr.total_len; + break; + default: + offset+=record_hdr.total_len; + if(per_ss_ctx->identify_pkt_count++>=plugin_env->max_identify_pkt) + { + stellar_session_plugin_dettach_current_session(ss); + return ; + } + break; + } - switch(record_hdr.content_type) - { - case SSL_CONTENT_TYPE_HANDSHAKE: - ssl_handshake_decode(plugin_env, ss, pdata, pdata_sz, &pdata_offset); - break; - case SSL_CONTENT_TYPE_ALERT: - break; - case SSL_CONTENT_TYPE_APPLICATION_DATA: - break; - case SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC: + if(ret==SSL_DECODER_FALSE) + { break; - default: - if(per_ss_ctx->identify_pkt_count++>=plugin_env->max_identify_pkt) - { - stellar_session_plugin_dettach_current_session(ss); - return ; - } + } + + if(ret==SSL_DECODER_CONTINUE) + { + //pdata_offset-=5; + per_ss_ctx->record_trunk.record_hdr=record_hdr; + per_ss_ctx->record_trunk.is_contains_header=SSL_DECODER_FALSE; break; + } + + pdata_offset+=record_hdr.total_len; + } + + if(is_trunk_cache(&(per_ss_ctx->record_trunk)) || pdata_sz>pdata_offset) + { + ssl_trunk_message_publish(plugin_env, ss, &(per_ss_ctx->record_trunk), pdata+pdata_offset, pdata_sz-pdata_offset); } } @@ -1118,7 +1297,9 @@ void *ssl_decoder_per_session_context_new(struct session *ss, void *penv) return NULL; } - return CALLOC(struct ssl_decoder_context, 1); + struct ssl_decoder_context *per_ss_ctx=(struct ssl_decoder_context *)CALLOC(struct ssl_decoder_context, 1); + per_ss_ctx->record_trunk.is_contains_header=SSL_DECODER_TRUE; + return (void *)per_ss_ctx; } void ssl_decoder_per_session_context_free(struct session *ss, void *per_session_ctx, void *penv) @@ -1194,37 +1375,6 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ plugin_env->net_port[i]=ntohs(int_val.u.i); } - // toml_table_t *limited_tbl=toml_table_in(ssl_tbl, "limited"); - // if(NULL==limited_tbl) - // { - // fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.limited]", __FUNCTION__, __LINE__, cfg_path); - // toml_free(root); - // return -1; - // } - - // toml_datum_t max_rr_num_val=toml_int_in(limited_tbl, "max_rr_num"); - // if(max_rr_num_val.ok==0) - // { - // fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.limited.max_rr_num]", __FUNCTION__, __LINE__, cfg_path); - // ret=-1; - // } - // else - // { - // plugin_env->max_rr_num=max_rr_num_val.u.i; - // } - - // // max_cache_trans_num - // toml_datum_t max_cache_trans_num_val=toml_int_in(limited_tbl, "max_cache_trans_num"); - // if(max_cache_trans_num_val.ok==0) - // { - // fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.limited.max_cache_trans_num]", __FUNCTION__, __LINE__, cfg_path); - // ret=-1; - // } - // else - // { - // plugin_env->max_cache_trans_num=max_cache_trans_num_val.u.i; - // } - toml_table_t *local_stat_tbl=toml_table_in(ssl_tbl, "local_stat"); if(NULL==local_stat_tbl) { @@ -1354,21 +1504,38 @@ extern "C" void *ssl_decoder_init(struct stellar *st) plugin_env->ssl.free_cb=ssl_message_free; plugin_env->ssl.on_cb=NULL; plugin_env->ssl.topic_name=SSL_DECODER_MESSAGE_TOPIC; - plugin_env->ssl.topic_id=stellar_session_mq_get_topic_id(st, plugin_env->ssl.topic_name); + plugin_env->ssl.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->ssl.topic_name); if(plugin_env->ssl.topic_id<0) { - plugin_env->ssl.topic_id=stellar_session_mq_create_topic(st, plugin_env->ssl.topic_name, ssl_message_free, NULL); + plugin_env->ssl.topic_id=stellar_session_mq_create_topic(plugin_env->st, plugin_env->ssl.topic_name, ssl_message_free, NULL); } + plugin_env->ptrunk.free_cb=ssl_trunk_message_free; + plugin_env->ptrunk.on_cb=NULL; + plugin_env->ptrunk.topic_name=SSL_TRUNK_MESSAGE_TOPIC; + plugin_env->ptrunk.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->ptrunk.topic_name); + if(plugin_env->ptrunk.topic_id<0) + { + plugin_env->ptrunk.topic_id=stellar_session_mq_create_topic(plugin_env->st, plugin_env->ptrunk.topic_name, ssl_trunk_message_free, NULL); + } + + plugin_env->strunk.free_cb=NULL; + plugin_env->strunk.on_cb=ssl_trunk_message_segment_data_cb; + plugin_env->strunk.topic_name=SSL_TRUNK_MESSAGE_TOPIC; + plugin_env->strunk.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->strunk.topic_name); + plugin_env->strunk.sub_id=stellar_session_mq_subscribe(plugin_env->st, plugin_env->strunk.topic_id, plugin_env->strunk.on_cb, plugin_env->plugin_id); + plugin_env->tcp_stream.free_cb=NULL; plugin_env->tcp_stream.on_cb=ssl_tcp_stream_session_segment_data_cb; plugin_env->tcp_stream.topic_name=TOPIC_TCP_STREAM; plugin_env->tcp_stream.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->tcp_stream.topic_name); plugin_env->tcp_stream.sub_id=stellar_session_mq_subscribe(plugin_env->st, plugin_env->tcp_stream.topic_id, plugin_env->tcp_stream.on_cb, plugin_env->plugin_id); - printf("ssl_decoder_init: plugin_id: %d, topic: [{name: %s -> id: %d}, {name: %s -> id: %d}] \n", + printf("ssl_decoder_init: plugin_id: %d, topic: [{name: %s -> id: %d}, {name: %s -> id: %d}, {name: %s -> id: %d}, {name: %s -> id: %d}] \n", plugin_env->plugin_id, plugin_env->ssl.topic_name, plugin_env->ssl.topic_id, + plugin_env->ptrunk.topic_name, plugin_env->ptrunk.topic_id, + plugin_env->strunk.topic_name, plugin_env->strunk.topic_id, plugin_env->tcp_stream.topic_name, plugin_env->tcp_stream.topic_id ); |
