diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a3062be --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/* diff --git a/inc/ssl_utils.h b/inc/ssl_utils.h new file mode 100644 index 0000000..5da3bcf --- /dev/null +++ b/inc/ssl_utils.h @@ -0,0 +1,35 @@ +#pragma once + +struct cipher_suite +{ + int value; + const char* name; +}; + +enum chello_parse_result +{ + CHELLO_PARSE_SUCCESS = 0, + CHELLO_PARSE_INVALID_FORMAT = -1, + CHELLO_PARSE_NOT_ENOUGH_BUFF = -2 +}; + +struct ssl_version +{ + uint8_t minor; + uint8_t major; + uint16_t ossl_format; +}; + +struct ssl_chello +{ + struct ssl_version min_version; + struct ssl_version max_version; + + char* sni; + char* alpn; + char* cipher_suites; + char* cipher_suites_tls13; +}; +struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result); + +void ssl_chello_free(struct ssl_chello* chello); \ No newline at end of file diff --git a/inc/tsg_rule.h b/inc/tsg_rule.h index d1fac1a..c8d085e 100644 --- a/inc/tsg_rule.h +++ b/inc/tsg_rule.h @@ -30,7 +30,6 @@ int tsg_shared_table_init(const char *conffile, Maat_feather_t maat_feather, voi //return -1 if failed, return 0 on success; int tsg_scan_shared_policy(Maat_feather_t maat_feather, void *pkt, int pkt_len, Maat_rule_t *result, int result_num, scan_status_t *mid, void *logger, int thread_seq); - #ifdef __cplusplus } #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3361c84..2d19c2b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8) add_definitions(-fPIC) -set(SRC tsg_entry.cpp tsg_rule.cpp tsg_send_log.cpp) +set(SRC tsg_entry.cpp tsg_rule.cpp ssl_utils.cpp tsg_send_log.cpp) include_directories(${CMAKE_SOURCE_DIR}/inc) include_directories(/opt/MESA/include/MESA/) diff --git a/src/ssl_utils.cpp b/src/ssl_utils.cpp new file mode 100644 index 0000000..fa297b5 --- /dev/null +++ b/src/ssl_utils.cpp @@ -0,0 +1,473 @@ +#include +#include +#include +#include +#include "ssl_utils.h" + +#define ALLOC(type, number) ((type *)calloc(sizeof(type), number)) +#define FREE(p) {free(*p);*p=NULL;} +#define KNI_STRING_MAX 2048 + +struct cipher_suite cipher_suite_list[] = +{ + {0xC030, "ECDHE-RSA-AES256-GCM-SHA384"}, + {0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"}, + {0xC028, "ECDHE-RSA-AES256-SHA384"}, + {0xC024, "ECDHE-ECDSA-AES256-SHA384"}, + {0xC014, "ECDHE-RSA-AES256-SHA"}, + {0xC00A, "ECDHE-ECDSA-AES256-SHA"}, + {0x00A5, "DH-DSS-AES256-GCM-SHA384"}, + {0x00A3, "DHE-DSS-AES256-GCM-SHA384"}, + {0x00A1, "DH-RSA-AES256-GCM-SHA384"}, + {0x009F, "DHE-RSA-AES256-GCM-SHA384"}, + {0x006B, "DHE-RSA-AES256-SHA256"}, + {0x006A, "DHE-DSS-AES256-SHA256"}, + {0x0069, "DH-RSA-AES256-SHA256"}, + {0x0068, "DH-DSS-AES256-SHA256"}, + {0x0039, "DHE-RSA-AES256-SHA"}, + {0x0038, "DHE-DSS-AES256-SHA"}, + {0x0037, "DH-RSA-AES256-SHA"}, + {0x0036, "DH-DSS-AES256-SHA"}, + {0x0088, "DHE-RSA-CAMELLIA256-SHA"}, + {0x0087, "DHE-DSS-CAMELLIA256-SHA"}, + {0x0086, "DH-RSA-CAMELLIA256-SHA"}, + {0x0085, "DH-DSS-CAMELLIA256-SHA"}, + {0xC019, "AECDH-AES256-SHA"}, + {0x00A7, "ADH-AES256-GCM-SHA384"}, + {0x006D, "ADH-AES256-SHA256"}, + {0x003A, "ADH-AES256-SHA"}, + {0x0089, "ADH-CAMELLIA256-SHA"}, + {0xC032, "ECDH-RSA-AES256-GCM-SHA384"}, + {0xC02E, "ECDH-ECDSA-AES256-GCM-SHA384"}, + {0xC02A, "ECDH-RSA-AES256-SHA384"}, + {0xC026, "ECDH-ECDSA-AES256-SHA384"}, + {0xC00F, "ECDH-RSA-AES256-SHA"}, + {0xC005, "ECDH-ECDSA-AES256-SHA"}, + {0x009D, "AES256-GCM-SHA384"}, + {0x003D, "AES256-SHA256"}, + {0x0035, "AES256-SHA"}, + {0x0084, "CAMELLIA256-SHA"}, + {0x008D, "PSK-AES256-CBC-SHA"}, + {0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"}, + {0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"}, + {0xC027, "ECDHE-RSA-AES128-SHA256"}, + {0xC023, "ECDHE-ECDSA-AES128-SHA256"}, + {0xC013, "ECDHE-RSA-AES128-SHA"}, + {0xC009, "ECDHE-ECDSA-AES128-SHA"}, + {0x00A4, "DH-DSS-AES128-GCM-SHA256"}, + {0x00A2, "DHE-DSS-AES128-GCM-SHA256"}, + {0x00A0, "DH-RSA-AES128-GCM-SHA256"}, + {0x009E, "DHE-RSA-AES128-GCM-SHA256"}, + {0x0067, "DHE-RSA-AES128-SHA256"}, + {0x0040, "DHE-DSS-AES128-SHA256"}, + {0x003F, "DH-RSA-AES128-SHA256"}, + {0x003E, "DH-DSS-AES128-SHA256"}, + {0x0033, "DHE-RSA-AES128-SHA"}, + {0x0032, "DHE-DSS-AES128-SHA"}, + {0x0031, "DH-RSA-AES128-SHA"}, + {0x0030, "DH-DSS-AES128-SHA"}, + {0x009A, "DHE-RSA-SEED-SHA"}, + {0x0099, "DHE-DSS-SEED-SHA"}, + {0x0098, "DH-RSA-SEED-SHA"}, + {0x0097, "DH-DSS-SEED-SHA"}, + {0x0045, "DHE-RSA-CAMELLIA128-SHA"}, + {0x0044, "DHE-DSS-CAMELLIA128-SHA"}, + {0x0043, "DH-RSA-CAMELLIA128-SHA"}, + {0x0042, "DH-DSS-CAMELLIA128-SHA"}, + {0xC018, "AECDH-AES128-SHA"}, + {0x00A6, "ADH-AES128-GCM-SHA256"}, + {0x006C, "ADH-AES128-SHA256"}, + {0x0034, "ADH-AES128-SHA"}, + {0x009B, "ADH-SEED-SHA"}, + {0x0046, "ADH-CAMELLIA128-SHA"}, + {0xC031, "ECDH-RSA-AES128-GCM-SHA256"}, + {0xC02D, "ECDH-ECDSA-AES128-GCM-SHA256"}, + {0xC029, "ECDH-RSA-AES128-SHA256"}, + {0xC025, "ECDH-ECDSA-AES128-SHA256"}, + {0xC00E, "ECDH-RSA-AES128-SHA"}, + {0xC004, "ECDH-ECDSA-AES128-SHA"}, + {0x009C, "AES128-GCM-SHA256"}, + {0x003C, "AES128-SHA256"}, + {0x002F, "AES128-SHA"}, + {0x0096, "SEED-SHA"}, + {0x0041, "CAMELLIA128-SHA"}, + {0x008C, "PSK-AES128-CBC-SHA"}, + {0xC012, "ECDHE-RSA-DES-CBC3-SHA"}, + {0xC008, "ECDHE-ECDSA-DES-CBC3-SHA"}, + {0x0016, "EDH-RSA-DES-CBC3-SHA"}, + {0x0013, "EDH-DSS-DES-CBC3-SHA"}, + {0x0010, "DH-RSA-DES-CBC3-SHA"}, + {0x000D, "DH-DSS-DES-CBC3-SHA"}, + {0xC017, "AECDH-DES-CBC3-SHA"}, + {0x001B, "ADH-DES-CBC3-SHA"}, + {0xC00D, "ECDH-RSA-DES-CBC3-SHA"}, + {0xC003, "ECDH-ECDSA-DES-CBC3-SHA"}, + {0x000A, "DES-CBC3-SHA"}, + {0x0007, "IDEA-CBC-SHA"}, + {0x008B, "PSK-3DES-EDE-CBC-SHA"}, + {0x0021, "KRB5-IDEA-CBC-SHA"}, + {0x001F, "KRB5-DES-CBC3-SHA"}, + {0x0025, "KRB5-IDEA-CBC-MD5"}, + {0x0023, "KRB5-DES-CBC3-MD5"}, + {0xC011, "ECDHE-RSA-RC4-SHA"}, + {0xC007, "ECDHE-ECDSA-RC4-SHA"}, + {0xC016, "AECDH-RC4-SHA"}, + {0x0018, "ADH-RC4-MD5"}, + {0xC00C, "ECDH-RSA-RC4-SHA"}, + {0xC002, "ECDH-ECDSA-RC4-SHA"}, + {0x0005, "RC4-SHA"}, + {0x0004, "RC4-MD5"}, + {0x008A, "PSK-RC4-SHA"}, + {0x0020, "KRB5-RC4-SHA"}, + {0x0024, "KRB5-RC4-MD5"}, + {0xC010, "ECDHE-RSA-NULL-SHA"}, + {0xC006, "ECDHE-ECDSA-NULL-SHA"}, + {0xC015, "AECDH-NULL-SHA"}, + {0xC00B, "ECDH-RSA-NULL-SHA"}, + {0xC001, "ECDH-ECDSA-NULL-SHA"}, + {0x003B, "NULL-SHA256"}, + {0x0002, "NULL-SHA"}, + {0x0001, "NULL-MD5"} +}; + +struct cipher_suite cipher_suite_list_tls13[] = +{ + {0x1301, "TLS_AES_128_GCM_SHA256"}, + {0x1302, "TLS_AES_256_GCM_SHA384"}, + {0x1303, "TLS_CHACHA20_POLY1305_SHA256"}, + {0x1304, "TLS_AES_128_CCM_SHA256"}, + {0x1305, "TLS_AES_128_CCM_8_SHA256"} +}; + +void ssl_chello_free(struct ssl_chello* chello) +{ + if(chello==NULL) + { + return; + } + free(chello->sni); + chello->sni = NULL; + free(chello->alpn); + chello->alpn = NULL; + free(chello->cipher_suites); + chello->cipher_suites = NULL; + free(chello->cipher_suites_tls13); + chello->cipher_suites_tls13 = NULL; + free(chello); +} + +static char* parse_alpn_extension(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) +{ + size_t pos = 0; + size_t len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; + if(2 + len != buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return NULL; + } + char* alpn = ALLOC(char, len + 1); + strncpy((char*)alpn, (const char*)buff + 2, len); + alpn[len] = '\0'; + *result = CHELLO_PARSE_SUCCESS; + return alpn; +} + +static char* parse_server_name_extension(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) +{ + size_t pos = 2; /* skip server name list length */ + size_t len; + char* sni = NULL; + while (pos + 3 < buff_len) + { + len = ((size_t)buff[pos + 1] << 8) + (size_t)buff[pos + 2]; + if (pos + 3 + len > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return NULL; + } + switch (buff[pos]) + { + case 0x00: /* host_name */ + sni = (char*)malloc(len + 1); + strncpy(sni, (const char*)buff + pos + 3, len); + sni[len] = '\0'; + *result = CHELLO_PARSE_SUCCESS; + } + pos += 3 + len; + } + if (pos != buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + } + return sni; +} + +static enum chello_parse_result parse_extensions(const unsigned char* buff, size_t buff_len, struct ssl_chello* chello) { + size_t pos = 0; + /* Parse each 4 bytes for the extension header */ + while (pos + 4 <= buff_len) + { + size_t len = ((size_t)buff[pos + 2] << 8) + (size_t)buff[pos + 3]; + /* Check if it's a server name extension */ + if (buff[pos] == 0x00 && buff[pos + 1] == 0x00) + { + if (pos + 4 + len > buff_len) + { + return CHELLO_PARSE_INVALID_FORMAT; + } + enum chello_parse_result result = CHELLO_PARSE_SUCCESS; + chello->sni = parse_server_name_extension(buff + pos + 4, len, &result); + if(result != CHELLO_PARSE_SUCCESS) + { + return result; + } + } + /* Check if it's a alpn extension */ + if (buff[pos] == 0x00 && buff[pos + 1] == 0x10) + { + if (pos + 4 + len > buff_len) + { + return CHELLO_PARSE_INVALID_FORMAT; + } + enum chello_parse_result result = CHELLO_PARSE_SUCCESS; + chello->alpn = parse_alpn_extension(buff + pos + 4, len, &result); + if(result != CHELLO_PARSE_SUCCESS) + { + return result; + } + } + pos += (4 + len); + } + /* Check we ended where we expected to */ + if (pos != buff_len) + { + return CHELLO_PARSE_INVALID_FORMAT; + } + return CHELLO_PARSE_SUCCESS; +} + +static char* parse_cipher_suites(struct cipher_suite* _cipher_suite_list, int n, const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) +{ + char* cipher_suites_str = (char* )malloc(KNI_STRING_MAX); + cipher_suites_str[0] = '\0'; + size_t pos = 0; + int flag = 0; + while(pos < buff_len) + { + int i = 0; + for(i = 0;i < n; i++) + { + int val = (buff[pos] << 8) + buff[pos + 1]; + if(_cipher_suite_list[i].value == val) + { + if(strnlen(_cipher_suite_list[i].name, KNI_STRING_MAX) + strnlen(cipher_suites_str, KNI_STRING_MAX) + 1 > KNI_STRING_MAX) + { + flag = 1; + break; + } + strncat(cipher_suites_str, _cipher_suite_list[i].name, KNI_STRING_MAX); + strncat(cipher_suites_str, ":", KNI_STRING_MAX); + } + } + pos += 2; + if(flag == 1) + { + break; + } + } + int len = strnlen(cipher_suites_str, KNI_STRING_MAX); + if(len > 0) + { + cipher_suites_str[len-1] = '\0'; + } + if(pos != buff_len && flag == 0) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + free(cipher_suites_str); + return NULL; + } + *result = CHELLO_PARSE_SUCCESS; + return cipher_suites_str; +} + +struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result) +{ + if(buff == NULL) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return NULL; + } + if(buff_len < 1) + { + *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; + return NULL; + } + if(buff[0] != 0x80 && buff[0] != 0x16) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return NULL; + } + /* SSL 2.0 compatible Client Hello + * High bit of first byte (length) and content type is Client Hello + * See RFC5246 Appendix E.2 + * if it is SSL 2.0, only parse version + */ + if(buff[0] == 0x80) + { + struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1); + _chello->min_version.major = 0x02; + if(buff_len < 2) + { + *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; + return _chello; + } + size_t len = (size_t)buff[1]; + if (buff_len < len + 2) + { + *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; + return _chello; + } + buff_len = len + 2; + size_t pos = 2; + /* Handshark Message Type: Client Hello */ + if (pos + 1 > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + if (buff[pos] != 0x01) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + pos += 1; + /* Version */ + if(pos + 2 > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + _chello->max_version.major = buff[pos]; + _chello->max_version.minor = buff[pos + 1]; + _chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor; + *result = CHELLO_PARSE_SUCCESS; + return _chello; + } + else + { + if (buff_len < 5) + { + *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; + return NULL; + } + if(buff[1] != 3 || buff[2] > 4 || buff[2] < 0) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return NULL; + } + struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1); + _chello->min_version.major = buff[1]; + _chello->min_version.minor = buff[2]; + _chello->min_version.ossl_format=(uint16_t)_chello->min_version.major<<8|_chello->min_version.minor; + _chello->max_version.major = -1; + _chello->max_version.minor = -1; + _chello->sni = NULL; + _chello->alpn = NULL; + _chello->cipher_suites = NULL; + _chello->cipher_suites_tls13 = NULL; + /* TLS record length */ + size_t len = ((size_t)buff[3] << 8) + (size_t)buff[4] + 5; + if (buff_len < len) + { + *result = CHELLO_PARSE_NOT_ENOUGH_BUFF; + return _chello; + } + buff_len = len; + size_t pos = 5; + if (pos + 1 > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + if (buff[pos] != 0x01) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + pos += 4; + if(pos + 2 > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + _chello->max_version.major = buff[pos]; + _chello->max_version.minor = buff[pos+1]; + _chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor; + + pos += 34; + /* Session ID */ + if (pos + 1 > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + len = (size_t)buff[pos]; + pos += 1 + len; + /* Cipher Suites */ + if (pos + 2 > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; + pos += 2; + if(pos + len > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + int n = sizeof(cipher_suite_list) / sizeof(struct cipher_suite); + _chello->cipher_suites = parse_cipher_suites(cipher_suite_list, n, buff + pos, len, result); + if(*result != CHELLO_PARSE_SUCCESS) + { + return _chello; + } + n = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite); + _chello->cipher_suites_tls13 = parse_cipher_suites(cipher_suite_list_tls13, n, buff + pos, len, result); + if(*result != CHELLO_PARSE_SUCCESS) + { + return _chello; + } + pos += len; + /* Compression Methods */ + if (pos >= buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + len = (size_t)buff[pos]; + pos += 1 + len; + /* no extensions */ + if(pos == buff_len) + { + *result = CHELLO_PARSE_SUCCESS; + return _chello; + } + /* Extensions */ + if (pos + 2 > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; + pos += 2; + if (pos + len > buff_len) + { + *result = CHELLO_PARSE_INVALID_FORMAT; + return _chello; + } + enum chello_parse_result ret = parse_extensions(buff + pos, len, _chello); + *result = ret; + return _chello; + } +} diff --git a/src/tsg_rule.cpp b/src/tsg_rule.cpp index 639285e..4c7e843 100644 --- a/src/tsg_rule.cpp +++ b/src/tsg_rule.cpp @@ -1,18 +1,93 @@ -#include -#include -#include -#include "tsg_rule.h" +#include "MESA/MESA_handle_logger.h" +#include "Maat_rule.h" +#include "Maat_command.h" +#include "ssl_utils.h" -extern Maat_feather_t g_tsg_maat_feather; +#define KNI_DOMAIN_MAX 256 -int tsg_pull_policy_result(PULL_RESULT_TYPE pull_result_type, Maat_rule_t*result, int result_num) +enum kni_protocol{ + KNI_PROTOCOL_UNKNOWN = 0, + KNI_PROTOCOL_SSL, + KNI_PROTOCOL_HTTP, +}; + +enum kni_scan_table { - return 0; + TSG_FIELD_SSL_SNI, + TSG_FIELD_HTTP_HOST, + SCAN_TABLE_MAX +}; + +struct kni_protocol_identify_result{ + int protocol; + char domain[KNI_DOMAIN_MAX]; + int domain_len; +}; + +Maat_feather_t g_kni_maat_feather; +const char *g_kni_scan_table_name[SCAN_TABLE_MAX]; +int g_kni_scan_tableid[SCAN_TABLE_MAX] = {0}; + +static void protocol_identify(char *buff, int buff_len, struct kni_protocol_identify_result *result){ + result->protocol = KNI_PROTOCOL_UNKNOWN; + //TODO: http: get from http protocol plugin + + //ssl + enum chello_parse_result chello_status = CHELLO_PARSE_INVALID_FORMAT; + struct ssl_chello *chello = NULL; + chello = ssl_chello_parse((const unsigned char*)buff, buff_len, &chello_status); + if(chello_status == CHELLO_PARSE_SUCCESS){ + result->protocol = KNI_PROTOCOL_SSL; + if(chello->sni == NULL){ + result->domain_len = 0; + } + else{ + result->domain_len = strnlen(chello->sni, KNI_DOMAIN_MAX); + strncpy(result->domain, chello->sni, strnlen(chello->sni, sizeof(result->domain) - 1)); + } + } + ssl_chello_free(chello); + return; } -int tsg_scan_nesting_addr(Maat_feather_t maat_feather, struct streaminfo *a_stream, tsg_protocol_t proto, scan_status_t *mid, Maat_rule_t*result, int result_num) -{ - return 0; +//return -1 if failed, return 0 on success; +int tsg_shared_table_init(const char *conffile, Maat_feather_t maat_feather, void *logger){ + g_kni_maat_feather = maat_feather; + g_kni_scan_table_name[TSG_FIELD_HTTP_HOST] = "TSG_FIELD_HTTP_HOST"; + g_kni_scan_table_name[TSG_FIELD_SSL_SNI] = "TSG_FIELD_SSL_SNI"; + int i; + for(i = 0; i < SCAN_TABLE_MAX; i++){ + g_kni_scan_tableid[i] = Maat_table_register(maat_feather, g_kni_scan_table_name[i]); + if(g_kni_scan_tableid[i] < 0){ + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, "Failed at Maat_table_register, tablename = %s, ret = %d", + g_kni_scan_table_name[i], g_kni_scan_tableid[i]); + return -1; + } + } + return 0; } +//return -1 if failed, return 0 on success +int tsg_scan_shared_policy(Maat_feather_t maat_feather, void *pkt, int pkt_len, Maat_rule_t *result, int result_num, scan_status_t *mid, void *logger, int thread_seq){ + struct kni_protocol_identify_result protocol_identify_res; + memset(&protocol_identify_res, 0, sizeof(protocol_identify_res)); + protocol_identify((char*)pkt, pkt_len, &protocol_identify_res); + switch(protocol_identify_res.protocol){ + case KNI_PROTOCOL_UNKNOWN: + //TODO: field_stat refactor + //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_STMERR_UNSUPPORTED_PROTOCOL], 0, FS_OP_ADD, 1); + //pmeinfo->error = STREAM_ERROR_UNSUPPORTED_PROTOCOL; + return -1; + case KNI_PROTOCOL_SSL: + return Maat_full_scan_string(g_kni_maat_feather, g_kni_scan_tableid[TSG_FIELD_SSL_SNI], CHARSET_UTF8, + protocol_identify_res.domain, protocol_identify_res.domain_len, + result, NULL, result_num, mid, thread_seq); + case KNI_PROTOCOL_HTTP: + return Maat_full_scan_string(g_kni_maat_feather, g_kni_scan_tableid[TSG_FIELD_HTTP_HOST], CHARSET_UTF8, + protocol_identify_res.domain, protocol_identify_res.domain_len, + result, NULL, result_num, mid, thread_seq); + default: + return -1; + } +} \ No newline at end of file