kni适配firewall
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
add_library(common STATIC src/kni_utils.cpp src/ssl_utils.cpp src/kni_cmsg.cpp)
|
add_library(common STATIC src/kni_utils.cpp src/kni_cmsg.cpp)
|
||||||
target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||||
target_link_libraries(common MESA_handle_logger)
|
target_link_libraries(common MESA_handle_logger)
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#define KNI_STRING_MAX 2048
|
#define KNI_STRING_MAX 2048
|
||||||
#define KNI_PATH_MAX 256
|
#define KNI_PATH_MAX 256
|
||||||
#define KNI_SYMBOL_MAX 64
|
#define KNI_SYMBOL_MAX 64
|
||||||
#define KNI_DOMAIN_MAX 256
|
|
||||||
#define KNI_ADDR_MAX 128
|
#define KNI_ADDR_MAX 128
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
@@ -71,26 +70,20 @@ struct kni_tcpopt_info{
|
|||||||
#define KNI_FS_COLUMN_MAX 256
|
#define KNI_FS_COLUMN_MAX 256
|
||||||
#define KNI_FS_LINE_MAX 256
|
#define KNI_FS_LINE_MAX 256
|
||||||
enum kni_field{
|
enum kni_field{
|
||||||
KNI_FIELD_BYP_STM,
|
KNI_FIELD_BYP_INTCPERR,
|
||||||
KNI_FIELD_BYP_STM_POLICY,
|
//intercept error
|
||||||
KNI_FIELD_BYP_STM_ERR,
|
KNI_FIELD_INTCPERR_ASYM_ROUTING,
|
||||||
//stream error
|
KNI_FIELD_INTCPERR_NO_SYN,
|
||||||
KNI_FIELD_STMERR_ASYM_ROUTING,
|
KNI_FIELD_INTCPERR_NO_SYN_ACK,
|
||||||
KNI_FIELD_STMERR_NO_SYN,
|
KNI_FIELD_INTCPERR_INVALID_IP_HDR,
|
||||||
KNI_FIELD_STMERR_NO_SYN_ACK,
|
KNI_FIELD_INTCPERR_EXCEED_MTU,
|
||||||
KNI_FIELD_STMERR_NO_DATA,
|
//intercept error: internal error
|
||||||
KNI_FIELD_STMERR_UNSUPPORTED_PROTOCOL,
|
KNI_FIELD_INTCPERR_SENDTO_TFE_FAIL,
|
||||||
KNI_FIELD_STMERR_INVALID_IP_HDR,
|
KNI_FIELD_INTCPERR_TUPLE2STM_ADD_FAIL,
|
||||||
KNI_FIELD_STMERR_EXCEED_MTU,
|
KNI_FIELD_INTCPERR_NO_TFE,
|
||||||
//stream error: internal error
|
KNI_FIELD_INTCPERR_DUP_TRAFFIC,
|
||||||
KNI_FIELD_STMERR_INVALID_ACTION,
|
KNI_FIELD_INTCPERR_CMSG_ADD_FAIL,
|
||||||
KNI_FIELD_STMERR_SENDTO_TFE_FAIL,
|
//success intercept stream
|
||||||
KNI_FIELD_STMERR_TUPLE2STM_ADD_FAIL,
|
|
||||||
KNI_FIELD_STMERR_NO_TFE,
|
|
||||||
KNI_FIELD_STMERR_PME_INIT_FAIL,
|
|
||||||
KNI_FIELD_STMERR_DUP_TRAFFIC,
|
|
||||||
KNI_FIELD_STMERR_CMSG_ADD_FAIL,
|
|
||||||
//intercept stream
|
|
||||||
KNI_FIELD_INTCP_STM,
|
KNI_FIELD_INTCP_STM,
|
||||||
KNI_FIELD_INTCP_BYTE,
|
KNI_FIELD_INTCP_BYTE,
|
||||||
KNI_FIELD_SSL_STM,
|
KNI_FIELD_SSL_STM,
|
||||||
@@ -154,6 +147,7 @@ struct pkt_info{
|
|||||||
uint16_t tcphdr_len;
|
uint16_t tcphdr_len;
|
||||||
char *data;
|
char *data;
|
||||||
uint16_t data_len;
|
uint16_t data_len;
|
||||||
|
int parse_failed;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum kni_ipv4hdr_parse_error{
|
enum kni_ipv4hdr_parse_error{
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
#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);
|
|
||||||
@@ -1,466 +0,0 @@
|
|||||||
#include "kni_utils.h"
|
|
||||||
#include "ssl_utils.h"
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -100,3 +100,4 @@ remote_ip = 192.168.10.152
|
|||||||
remote_port = 8125
|
remote_port = 8125
|
||||||
local_path = ./fs2_kni.status
|
local_path = ./fs2_kni.status
|
||||||
stat_cycle = 2
|
stat_cycle = 2
|
||||||
|
print_mode = 1
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
add_library(kni SHARED src/kni_entry.cpp src/kni_maat.cpp src/kni_send_logger.cpp src/tfe_mgr.cpp src/kni_tun.cpp)
|
add_library(kni SHARED src/kni_entry.cpp src/kni_send_logger.cpp src/tfe_mgr.cpp src/kni_tun.cpp)
|
||||||
target_include_directories(kni PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
target_include_directories(kni PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||||
target_link_libraries(kni common MESA_prof_load MESA_htable MESA_field_stat maatframe marsio uuid cjson rdkafka dabloom)
|
target_link_libraries(kni common MESA_prof_load MESA_htable MESA_field_stat maatframe marsio uuid cjson rdkafka dabloom)
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#define KNI_MAAT_READCONF_IRIS 0
|
|
||||||
#define KNI_MAAT_READCONF_JSON 1
|
|
||||||
#define KNI_MAAT_READCONF_REDIS 2
|
|
||||||
#define KNI_MAAT_RULE_NUM_MAX 8
|
|
||||||
struct kni_maat_handle;
|
|
||||||
|
|
||||||
|
|
||||||
/* action
|
|
||||||
0x00: none
|
|
||||||
0x01: monitor
|
|
||||||
0x02: intercept
|
|
||||||
0x10: reject
|
|
||||||
0x30: Manipulate
|
|
||||||
0x60: steer
|
|
||||||
0x80: bypass
|
|
||||||
*/
|
|
||||||
enum kni_action{
|
|
||||||
KNI_ACTION_NONE = 0x00,
|
|
||||||
KNI_ACTION_MONITOR = 0x01,
|
|
||||||
KNI_ACTION_INTERCEPT = 0x02,
|
|
||||||
KNI_ACTION_REJECT = 0x10,
|
|
||||||
KNI_ACTION_MANIPULATE = 0x30,
|
|
||||||
KNI_ACTION_STEER = 0x60,
|
|
||||||
KNI_ACTION_BYPASS = 0x80
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kni_maat_handle* kni_maat_init(const char* profile, void *logger, int thread_count);
|
|
||||||
void kni_maat_destroy(struct kni_maat_handle *handle);
|
|
||||||
enum kni_action intercept_policy_scan(struct kni_maat_handle* handle, struct ipaddr *addr, char *domain, int domain_len,
|
|
||||||
int thread_seq, int *policy_id, int *do_log, int *is_hit_policy);
|
|
||||||
char* kni_maat_action_trans(enum kni_action action);
|
|
||||||
46
entry/include/tsg_rule.h
Normal file
46
entry/include/tsg_rule.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef __TSG_RULE_H__
|
||||||
|
#define __TSG_RULE_H__
|
||||||
|
|
||||||
|
#include <MESA/Maat_rule.h>
|
||||||
|
#include "tsg_types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_DOAMIN_LEN 2048
|
||||||
|
|
||||||
|
struct _identify_info
|
||||||
|
{
|
||||||
|
tsg_protocol_t proto; //enum _tsg_protocol (tsg_types.h)
|
||||||
|
int domain_len;
|
||||||
|
char domain[MAX_DOAMIN_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum _PULL_RESULT_TYPE
|
||||||
|
{
|
||||||
|
PULL_KNI_RESULT,
|
||||||
|
PULL_FW_RESULT
|
||||||
|
}PULL_RESULT_TYPE;
|
||||||
|
|
||||||
|
extern Maat_feather_t g_tsg_maat_feather;
|
||||||
|
|
||||||
|
int tsg_rule_init(const char *conffile);
|
||||||
|
|
||||||
|
int tsg_scan_nesting_addr(Maat_feather_t maat_feather, const struct streaminfo *a_stream, tsg_protocol_t proto, scan_status_t *mid, Maat_rule_t*result, int result_num);
|
||||||
|
|
||||||
|
//return 0 if failed, return >0 on success;
|
||||||
|
int tsg_pull_policy_result(struct streaminfo *a_stream, PULL_RESULT_TYPE pull_result_type, Maat_rule_t *result, int result_num, struct _identify_info *identify_info);
|
||||||
|
|
||||||
|
//return -1 if failed, return 0 on success;
|
||||||
|
int tsg_shared_table_init(const char *conffile, Maat_feather_t maat_feather, void *logger);
|
||||||
|
|
||||||
|
//return value: -1: failed, 0: not hit, >0: hit count
|
||||||
|
int tsg_scan_shared_policy(Maat_feather_t maat_feather, void *pkt, int pkt_len, Maat_rule_t *result, int result_num, struct _identify_info *identify_info, scan_status_t *mid, void *logger, int thread_seq);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
109
entry/include/tsg_types.h
Normal file
109
entry/include/tsg_types.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#ifndef __TSG_TYPES_H__
|
||||||
|
#define __TSG_TYPES_H__
|
||||||
|
|
||||||
|
typedef enum _tsg_opt
|
||||||
|
{
|
||||||
|
LOG_OPT_HTTP_URL=1,
|
||||||
|
LOG_OPT_HTTP_HOST,
|
||||||
|
LOG_OPT_HTTP_REQUEST_LINE,
|
||||||
|
LOG_OPT_HTTP_RESPONSE_LINE,
|
||||||
|
LOG_OPT_HTTP_REQUEST_HEADER,
|
||||||
|
LOG_OPT_HTTP_RESPONSE_HEADER,
|
||||||
|
LOG_OPT_HTTP_REQUEST_BODY,
|
||||||
|
LOG_OPT_HTTP_RESPONSE_BODY,
|
||||||
|
LOG_OPT_HTTP_PROXY_FLAG,
|
||||||
|
LOG_OPT_HTTP_SEQUENCE,
|
||||||
|
LOG_OPT_HTTP_SNAPSHOT,
|
||||||
|
LOG_OPT_HTTP_COOKIE,
|
||||||
|
LOG_OPT_HTTP_REFERER,
|
||||||
|
LOG_OPT_HTTP_USER_AGENT,
|
||||||
|
LOG_OPT_HTTP_CONTENT_LENGTH,
|
||||||
|
LOG_OPT_HTTP_CONTENT_TYPE,
|
||||||
|
LOG_OPT_HTTP_SET_COOKIE,
|
||||||
|
LOG_OPT_HTTP_VERSION,
|
||||||
|
|
||||||
|
LOG_OPT_MAIL_PROTOCOL_TYPE,
|
||||||
|
LOG_OPT_MAIL_SENDER,
|
||||||
|
LOG_OPT_MAIL_RECEIVER,
|
||||||
|
LOG_OPT_MAIL_SUBJECT,
|
||||||
|
LOG_OPT_MAIL_CONTENT,
|
||||||
|
LOG_OPT_MAIL_ATTACHMENT_NAME,
|
||||||
|
LOG_OPT_MAIL_ATTACHMENT_CONTENT,
|
||||||
|
LOG_OPT_MAIL_EML_FILE,
|
||||||
|
LOG_OPT_MAIL_SNAPSHOT,
|
||||||
|
LOG_OPT_MAIL_SUBJECT_CHARSET,
|
||||||
|
|
||||||
|
LOG_OPT_DNS_MESSAGE_ID,
|
||||||
|
LOG_OPT_DNS_QR,
|
||||||
|
LOG_OPT_DNS_OPCODE,
|
||||||
|
LOG_OPT_DNS_AA,
|
||||||
|
LOG_OPT_DNS_TC,
|
||||||
|
LOG_OPT_DNS_RD,
|
||||||
|
LOG_OPT_DNS_RA,
|
||||||
|
LOG_OPT_DNS_RCODE,
|
||||||
|
LOG_OPT_DNS_QDCOUNT,
|
||||||
|
LOG_OPT_DNS_ANCOUNT,
|
||||||
|
LOG_OPT_DNS_NSCOUNT,
|
||||||
|
LOG_OPT_DNS_ARCOUNT,
|
||||||
|
LOG_OPT_DNS_QNAME,
|
||||||
|
LOG_OPT_DNS_QTYPE,
|
||||||
|
LOG_OPT_DNS_QCLASS,
|
||||||
|
LOG_OPT_DNS_CNAME,
|
||||||
|
LOG_OPT_DNS_SUB,
|
||||||
|
LOG_OPT_DNS_RR,
|
||||||
|
|
||||||
|
LOG_OPT_SSL_VERSION,
|
||||||
|
LOG_OPT_SSL_SNI,
|
||||||
|
LOG_OPT_SSL_SAN,
|
||||||
|
LOG_OPT_SSL_CN,
|
||||||
|
LOG_OPT_SSL_PINNINGST,
|
||||||
|
LOG_OPT_SSL_INTERCEPT_STATE,
|
||||||
|
LOG_OPT_SSL_SERVER_SIDE_LATENCY,
|
||||||
|
LOG_OPT_SSL_CLINET_SIDE_LATENCY,
|
||||||
|
LOG_OPT_SSL_SERVER_SIDE_VERSION,
|
||||||
|
LOG_OPT_SSL_CLIENT_SIDE_VERSION,
|
||||||
|
LOG_OPT_SSL_CERT_VERIFY,
|
||||||
|
LOG_OPT_SSL_ERROR,
|
||||||
|
LOG_OPT_SSL_CON_LATENCY_MS,
|
||||||
|
|
||||||
|
LOG_OPT_FTP_URL,
|
||||||
|
LOG_OPT_FTP_CONTENT,
|
||||||
|
|
||||||
|
LOG_OPT_BGP_TYPE,
|
||||||
|
LOG_OPT_BGP_AS_NUM,
|
||||||
|
LOG_OPT_BGP_ROUTE,
|
||||||
|
|
||||||
|
LOG_OPT_VOIP_CALLING_ACCOUNT,
|
||||||
|
LOG_OPT_VOIP_CALLED_ACCOUNT,
|
||||||
|
LOG_OPT_VOIP_CALLING_NUMBER,
|
||||||
|
LOG_OPT_VOIP_CALLED_NUMBER,
|
||||||
|
|
||||||
|
LOG_OPT_RADIUS_PACKET_TYPE,
|
||||||
|
LOG_OPT_RADIUS_NAS_IP,
|
||||||
|
LOG_OPT_RADIUS_FRAMED_IP,
|
||||||
|
LOG_OPT_RADIUS_ACCOUNT,
|
||||||
|
LOG_OPT_RADIUS_SEESION_TIMEOUT,
|
||||||
|
LOG_OPT_RADIUS_IDLE_TIMEOUT,
|
||||||
|
LOG_OPT_RADIUS_ACCT_STATUS_TYPE,
|
||||||
|
LOG_OPT_RADIUS_ACCT_TERMINATE_CAUSE,
|
||||||
|
LOG_OPT_MAX
|
||||||
|
}tsg_opt_t;
|
||||||
|
|
||||||
|
typedef enum _tsg_protocol
|
||||||
|
{
|
||||||
|
PROTO_IPv4,
|
||||||
|
PROTO_IPv6,
|
||||||
|
PROTO_TCP,
|
||||||
|
PROTO_UDP,
|
||||||
|
PROTO_HTTP,
|
||||||
|
PROTO_MAIL,
|
||||||
|
PROTO_DNS,
|
||||||
|
PROTO_FTP,
|
||||||
|
PROTO_SSL,
|
||||||
|
PROTO_SIP,
|
||||||
|
PROTO_BGP,
|
||||||
|
PROTO_STREAMING_MEDIA,
|
||||||
|
PROTO_MAX
|
||||||
|
}tsg_protocol_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,405 +0,0 @@
|
|||||||
#include "kni_utils.h"
|
|
||||||
#include "kni_maat.h"
|
|
||||||
|
|
||||||
|
|
||||||
enum scan_table
|
|
||||||
{
|
|
||||||
PXY_INTERCEPT_IP,
|
|
||||||
PXY_INTERCEPT_DOMAIN,
|
|
||||||
TSG_OBJ_SUBSCRIBER_ID,
|
|
||||||
SCAN_TABLE_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum kni_action g_maat_default_action = KNI_ACTION_BYPASS;
|
|
||||||
int g_maat_default_log_option=1;
|
|
||||||
struct kni_maat_handle{
|
|
||||||
Maat_feather_t static_maat;
|
|
||||||
Maat_feather_t dynamic_maat;
|
|
||||||
int scan_tableid[SCAN_TABLE_MAX];
|
|
||||||
int subscriber_id_tableid;
|
|
||||||
void *logger;
|
|
||||||
};
|
|
||||||
|
|
||||||
void kni_maat_destroy(struct kni_maat_handle *handle){
|
|
||||||
if(handle != NULL){
|
|
||||||
if(handle->static_maat != NULL){
|
|
||||||
Maat_burn_feather(handle->static_maat);
|
|
||||||
}
|
|
||||||
if(handle->dynamic_maat != NULL){
|
|
||||||
Maat_burn_feather(handle->dynamic_maat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FREE(&handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void compile_ex_param_new(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp){
|
|
||||||
void *logger = argp;
|
|
||||||
unsigned char tmp=0;
|
|
||||||
KNI_LOG_DEBUG(logger, "call compile_ex_param_new");
|
|
||||||
if(rule->config_id == 0){
|
|
||||||
tmp=(unsigned char)rule->action;
|
|
||||||
enum kni_action action = (enum kni_action)tmp;
|
|
||||||
if(action==KNI_ACTION_INTERCEPT)
|
|
||||||
{
|
|
||||||
g_maat_default_action = KNI_ACTION_INTERCEPT;
|
|
||||||
KNI_LOG_INFO(logger, "Set default intercept action to intercept.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_maat_default_action = KNI_ACTION_BYPASS;
|
|
||||||
KNI_LOG_INFO(logger, "Set default intercept action to bypass.");
|
|
||||||
}
|
|
||||||
g_maat_default_log_option=rule->do_log;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void compile_ex_param_free(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp){
|
|
||||||
void *logger = argp;
|
|
||||||
KNI_LOG_DEBUG(logger, "call compile_ex_param_free");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void compile_ex_param_dup(int idx, MAAT_RULE_EX_DATA *to, MAAT_RULE_EX_DATA *from, long argl, void *argp){
|
|
||||||
void *logger = argp;
|
|
||||||
KNI_LOG_DEBUG(logger, "call compile_ex_param_dup");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Maat_feather_t create_maat_feather(const char *instance_name, const char* profile, const char *section, void *logger, int thread_count){
|
|
||||||
int readconf_mode;
|
|
||||||
char tableinfo_path[KNI_PATH_MAX];
|
|
||||||
char maatjson_path[KNI_PATH_MAX];
|
|
||||||
char redis_ip[INET_ADDRSTRLEN];
|
|
||||||
int redis_port;
|
|
||||||
int redis_index;
|
|
||||||
Maat_feather_t feather = NULL;
|
|
||||||
int effective_interval_ms = 1000;//1s
|
|
||||||
int ret = MESA_load_profile_int_nodef(profile, section, "readconf_mode", &readconf_mode);
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load: readconf_mode not set, profile = %s, section = %s", profile, section);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
ret = MESA_load_profile_string_nodef(profile, section, "tableinfo_path", tableinfo_path, sizeof(tableinfo_path));
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load: tableinfo_path not set, profile = %s, section = %s", profile, section);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n readconf_mode: %d\n tableinfo_path: %s" , section, readconf_mode, tableinfo_path);
|
|
||||||
feather = Maat_feather(thread_count, tableinfo_path, logger);
|
|
||||||
if(feather == NULL){
|
|
||||||
KNI_LOG_ERROR(logger, "Failed at Maat_feather, max_thread_num = %d, tableinfo_path = %s", thread_count, tableinfo_path);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
Maat_set_feather_opt(feather, MAAT_OPT_INSTANCE_NAME, instance_name, strlen(instance_name) + 1);
|
|
||||||
Maat_set_feather_opt(feather, MAAT_OPT_EFFECT_INVERVAL_MS, &effective_interval_ms, sizeof(effective_interval_ms));
|
|
||||||
switch(readconf_mode){
|
|
||||||
case KNI_MAAT_READCONF_JSON:
|
|
||||||
ret = MESA_load_profile_string_nodef(profile, section, "maatjson_path", maatjson_path, sizeof(maatjson_path));
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load: maatjson_path not set, profile = %s, section = %s", profile, section);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n maatjson_path: %s", section, maatjson_path);
|
|
||||||
Maat_set_feather_opt(feather, MAAT_OPT_JSON_FILE_PATH, maatjson_path, strlen(maatjson_path));
|
|
||||||
break;
|
|
||||||
case KNI_MAAT_READCONF_IRIS:
|
|
||||||
break;
|
|
||||||
case KNI_MAAT_READCONF_REDIS:
|
|
||||||
ret = MESA_load_profile_string_nodef(profile, section, "redis_ip", redis_ip, sizeof(redis_ip));
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load: redis_ip not set, profile = %s, section = %s", profile, section);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
ret = MESA_load_profile_int_nodef(profile, section, "redis_port", &redis_port);
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load: redis_port not set, profile = %s, section = %s", profile, section);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
ret = MESA_load_profile_int_nodef(profile, section, "redis_index", &redis_index);
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load: redis_index not set, profile = %s, section = %s", profile, section);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
KNI_LOG_ERROR(logger, "MESA_prof_load, [%s]:\n redis_ip: %s\n redis_port: %d\n redis_index: %d",
|
|
||||||
section, redis_ip, redis_port, redis_index);
|
|
||||||
Maat_set_feather_opt(feather, MAAT_OPT_REDIS_IP, (void*)redis_ip, strlen(redis_ip) + 1);
|
|
||||||
Maat_set_feather_opt(feather, MAAT_OPT_REDIS_PORT, (void*)&redis_port, sizeof(redis_port));
|
|
||||||
Maat_set_feather_opt(feather, MAAT_OPT_REDIS_INDEX, (void*)&redis_index, sizeof(redis_index));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = Maat_initiate_feather(feather);
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "Failed at Maat_initiate_feather");
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
return feather;
|
|
||||||
|
|
||||||
error_out:
|
|
||||||
if(feather != NULL){
|
|
||||||
Maat_burn_feather(feather);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy from tfe
|
|
||||||
static int get_column_pos(const char* line, int column_seq, size_t *offset, size_t *len){
|
|
||||||
const char* seps=" \t";
|
|
||||||
char* saveptr=NULL, *subtoken=NULL, *str=NULL;
|
|
||||||
char* dup_line=kni_strdup(line);
|
|
||||||
int i=0, ret=-1;
|
|
||||||
for (str = dup_line; ; str = NULL){
|
|
||||||
subtoken = strtok_r(str, seps, &saveptr);
|
|
||||||
if (subtoken == NULL)
|
|
||||||
break;
|
|
||||||
if(i==column_seq-1){
|
|
||||||
*offset=subtoken-dup_line;
|
|
||||||
*len=strlen(subtoken);
|
|
||||||
ret=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
free(dup_line);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void subscribe_id_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA* to, MAAT_PLUGIN_EX_DATA* from, long argl, void* argp){
|
|
||||||
*to = kni_strdup((char*)*from);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void subscribe_id_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp){
|
|
||||||
int ret = 0;
|
|
||||||
size_t subscribe_id_offset, len;
|
|
||||||
void *logger = argp;
|
|
||||||
ret = get_column_pos(table_line, 4, &subscribe_id_offset, &len);
|
|
||||||
if(ret<0){
|
|
||||||
KNI_LOG_ERROR(logger, "Add subscribe ID faild: %s", table_line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*ad = ALLOC(char, len+1);
|
|
||||||
memcpy(*ad, table_line+subscribe_id_offset, len);
|
|
||||||
KNI_LOG_INFO(logger, "Add subscribe ID: %s", (char*)*ad);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void subscribe_id_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp){
|
|
||||||
void *logger = argp;
|
|
||||||
KNI_LOG_INFO(logger, "Delete subscribe ID: %s", (char*)*ad);
|
|
||||||
free(*ad);
|
|
||||||
*ad = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct kni_maat_handle* kni_maat_init(const char* profile, void *logger, int thread_count){
|
|
||||||
struct kni_maat_handle *handle = ALLOC(struct kni_maat_handle, 1);
|
|
||||||
handle->logger = logger;
|
|
||||||
//static maat
|
|
||||||
const char *table_name[SCAN_TABLE_MAX];
|
|
||||||
char tablename_intercept_compile[] = "PXY_INTERCEPT_COMPILE";
|
|
||||||
char tablename_subscriber_id[] = "TSG_DYN_SUBSCRIBER_IP";
|
|
||||||
int ret, i;
|
|
||||||
handle->static_maat = create_maat_feather("static", profile, "static_maat", logger, thread_count);
|
|
||||||
if(handle->static_maat == NULL){
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
table_name[PXY_INTERCEPT_IP] = "PXY_INTERCEPT_IP";
|
|
||||||
table_name[PXY_INTERCEPT_DOMAIN] = "PXY_INTERCEPT_DOMAIN";
|
|
||||||
table_name[TSG_OBJ_SUBSCRIBER_ID] = "TSG_OBJ_SUBSCRIBER_ID";
|
|
||||||
for(i = 0; i < SCAN_TABLE_MAX; i++){
|
|
||||||
handle->scan_tableid[i] = Maat_table_register(handle->static_maat, table_name[i]);
|
|
||||||
if(handle->scan_tableid[i] < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "Failed at Maat_table_register, tablename = %s, ret = %d",
|
|
||||||
table_name[i], handle->scan_tableid[i]);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//get_ex
|
|
||||||
ret = Maat_rule_get_ex_new_index(handle->static_maat, tablename_intercept_compile, compile_ex_param_new, compile_ex_param_free, compile_ex_param_dup, 0, logger);
|
|
||||||
if(ret < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "Failed at Maat_rule_get_ex_new_index, tablename = %s, ret = %d", tablename_intercept_compile, ret);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
//dynamic maat register
|
|
||||||
handle->dynamic_maat = create_maat_feather("dynamic", profile, "dynamic_maat", logger, thread_count);
|
|
||||||
if(handle->dynamic_maat == NULL){
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
handle->subscriber_id_tableid = Maat_table_register(handle->dynamic_maat, tablename_subscriber_id);
|
|
||||||
if(handle->subscriber_id_tableid < 0){
|
|
||||||
KNI_LOG_ERROR(logger, "Failed at Maat_table_register, tablename = %s, ret = %d",
|
|
||||||
tablename_subscriber_id, handle->subscriber_id_tableid);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
ret = Maat_plugin_EX_register(handle->dynamic_maat,
|
|
||||||
handle->subscriber_id_tableid,
|
|
||||||
subscribe_id_new_cb,
|
|
||||||
subscribe_id_free_cb,
|
|
||||||
subscribe_id_dup_cb,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
logger);
|
|
||||||
if(ret != 0){
|
|
||||||
KNI_LOG_ERROR(NULL, "Failed at Maat_plugin_EX_register, tablename = %s, ret = %d", tablename_subscriber_id, ret);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
return handle;
|
|
||||||
|
|
||||||
error_out:
|
|
||||||
kni_maat_destroy(handle);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int index_of_enforce_policy(struct Maat_rule_t* result, size_t size){
|
|
||||||
size_t i = 0;
|
|
||||||
int biggest_intercept_policy_id = -1, ret_intercept_idx = -1;
|
|
||||||
int biggest_bypass_policy_id = -1, ret_bypass_idx = -1;
|
|
||||||
for(i = 0; i < size; i++){
|
|
||||||
if((unsigned char)result[i].action == KNI_ACTION_BYPASS){
|
|
||||||
if(result[i].config_id > biggest_bypass_policy_id){
|
|
||||||
biggest_bypass_policy_id = result[i].config_id;
|
|
||||||
ret_bypass_idx = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(result[i].config_id > biggest_intercept_policy_id){
|
|
||||||
biggest_intercept_policy_id = result[i].config_id;
|
|
||||||
ret_intercept_idx = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(biggest_bypass_policy_id != -1){
|
|
||||||
return ret_bypass_idx;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return ret_intercept_idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//type: 0 : sip, 1 : dip
|
|
||||||
static void get_ip_from_ipaddr(struct ipaddr *addr, char *ip, int type){
|
|
||||||
if(addr->addrtype == ADDR_TYPE_IPV4){
|
|
||||||
struct stream_tuple4_v4 *v4 = addr->v4;
|
|
||||||
if(type == 0){
|
|
||||||
inet_ntop(AF_INET, &(v4->saddr), ip, INET_ADDRSTRLEN);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
inet_ntop(AF_INET, &(v4->daddr), ip, INET_ADDRSTRLEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
struct stream_tuple4_v6 *v6 = addr->v6;
|
|
||||||
if(type == 0){
|
|
||||||
inet_ntop(AF_INET6, v6->saddr, ip, INET6_ADDRSTRLEN);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
inet_ntop(AF_INET6, v6->daddr, ip, INET6_ADDRSTRLEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum kni_action intercept_policy_scan(struct kni_maat_handle* handle, struct ipaddr *addr, char *domain, int domain_len,
|
|
||||||
int thread_seq, int *policy_id, int *do_log, int *is_hit_policy){
|
|
||||||
//return KNI_ACTION_INTERCEPT;
|
|
||||||
struct Maat_rule_t result[KNI_MAAT_RULE_NUM_MAX];
|
|
||||||
scan_status_t scan_mid = NULL;
|
|
||||||
int scan_ret = 0, hit_policy_cnt = 0, enforced_policy_idx = 0;
|
|
||||||
//scan subscribe_id
|
|
||||||
char sip[INET6_ADDRSTRLEN] = "";
|
|
||||||
char dip[INET6_ADDRSTRLEN] = "";
|
|
||||||
get_ip_from_ipaddr(addr, sip, 0);
|
|
||||||
get_ip_from_ipaddr(addr, dip, 1);
|
|
||||||
char* source_subscribe_id = NULL, *dest_subscribe_id = NULL;
|
|
||||||
source_subscribe_id = (char*)Maat_plugin_get_EX_data(handle->dynamic_maat, handle->subscriber_id_tableid, sip);
|
|
||||||
dest_subscribe_id = (char*)Maat_plugin_get_EX_data(handle->dynamic_maat, handle->subscriber_id_tableid, dip);
|
|
||||||
KNI_LOG_DEBUG(handle->logger, "sip = %s, source_subscribe_id = %s", sip, source_subscribe_id == NULL ? "null" : source_subscribe_id);
|
|
||||||
KNI_LOG_DEBUG(handle->logger, "dip = %s, dest_subscribe_id = %s", dip, dest_subscribe_id == NULL ? "null" : dest_subscribe_id);
|
|
||||||
if(source_subscribe_id != NULL){
|
|
||||||
scan_ret = Maat_full_scan_string(handle->static_maat, handle->scan_tableid[TSG_OBJ_SUBSCRIBER_ID],
|
|
||||||
CHARSET_UTF8, source_subscribe_id, strlen(source_subscribe_id),
|
|
||||||
result+hit_policy_cnt, NULL, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt,
|
|
||||||
&scan_mid, thread_seq);
|
|
||||||
KNI_LOG_DEBUG(handle->logger, "source_subscribe_id = %s, scan_ret = %d", source_subscribe_id, scan_ret);
|
|
||||||
if(scan_ret > 0){
|
|
||||||
hit_policy_cnt += scan_ret;
|
|
||||||
}
|
|
||||||
free(source_subscribe_id);
|
|
||||||
}
|
|
||||||
if(dest_subscribe_id != NULL){
|
|
||||||
scan_ret = Maat_full_scan_string(handle->static_maat, handle->scan_tableid[TSG_OBJ_SUBSCRIBER_ID],
|
|
||||||
CHARSET_UTF8, dest_subscribe_id, strlen(dest_subscribe_id),
|
|
||||||
result+hit_policy_cnt, NULL, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt,
|
|
||||||
&scan_mid, thread_seq);
|
|
||||||
KNI_LOG_DEBUG(handle->logger, "dest_subscribe_id = %s, scan_ret = %d", dest_subscribe_id, scan_ret);
|
|
||||||
if(scan_ret > 0){
|
|
||||||
hit_policy_cnt += scan_ret;
|
|
||||||
}
|
|
||||||
free(dest_subscribe_id);
|
|
||||||
}
|
|
||||||
//tcp: 6, udp: 17, can't be 0
|
|
||||||
scan_ret = Maat_scan_proto_addr(handle->static_maat, handle->scan_tableid[PXY_INTERCEPT_IP], addr, 6,
|
|
||||||
result+hit_policy_cnt, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt,
|
|
||||||
&scan_mid, thread_seq);
|
|
||||||
if(scan_ret > 0){
|
|
||||||
hit_policy_cnt += scan_ret;
|
|
||||||
}
|
|
||||||
scan_ret = Maat_full_scan_string(handle->static_maat, handle->scan_tableid[PXY_INTERCEPT_DOMAIN], CHARSET_UTF8,
|
|
||||||
domain, domain_len,
|
|
||||||
result+hit_policy_cnt, NULL, KNI_MAAT_RULE_NUM_MAX-hit_policy_cnt,
|
|
||||||
&scan_mid, thread_seq);
|
|
||||||
if(scan_ret > 0){
|
|
||||||
hit_policy_cnt += scan_ret;
|
|
||||||
}
|
|
||||||
Maat_clean_status(&scan_mid);
|
|
||||||
if(hit_policy_cnt > 0){
|
|
||||||
enforced_policy_idx = index_of_enforce_policy(result, hit_policy_cnt);
|
|
||||||
*policy_id = result[enforced_policy_idx].config_id;
|
|
||||||
*do_log = result[enforced_policy_idx].do_log;
|
|
||||||
*is_hit_policy = 1;
|
|
||||||
unsigned char action = (unsigned char)result[enforced_policy_idx].action;
|
|
||||||
return (enum kni_action)action;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
*policy_id = 0;
|
|
||||||
*do_log = g_maat_default_log_option;
|
|
||||||
return g_maat_default_action;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* action
|
|
||||||
0x00: none
|
|
||||||
0x01: monitor
|
|
||||||
0x02: intercept
|
|
||||||
0x10: reject
|
|
||||||
0x30: Manipulate
|
|
||||||
0x60: steer
|
|
||||||
0x80: bypass
|
|
||||||
*/
|
|
||||||
char* kni_maat_action_trans(enum kni_action action){
|
|
||||||
switch(action){
|
|
||||||
case 0x00:
|
|
||||||
return (char*)"none";
|
|
||||||
case 0x01:
|
|
||||||
return (char*)"monitor";
|
|
||||||
case 0x02:
|
|
||||||
return (char*)"intercept";
|
|
||||||
case 0x10:
|
|
||||||
return (char*)"reject";
|
|
||||||
case 0x30:
|
|
||||||
return (char*)"manipulate";
|
|
||||||
case 0x60:
|
|
||||||
return (char*)"steer";
|
|
||||||
case 0x80:
|
|
||||||
return (char*)"bypass";
|
|
||||||
default:
|
|
||||||
return (char*)"unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user