2019-10-22 15:13:14 +08:00
/*************************************************************************
> File Name : verify - policy . cpp
2020-01-09 14:32:00 +08:00
> Author :
> Mail :
2019-10-22 15:13:14 +08:00
> Created Time : 2019 年 08 月 23 日 星 期 五 14 时 41 分 17 秒
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020-09-25 14:56:36 +08:00
/* Breakpad */
# include <client/linux/handler/exception_handler.h>
# include <common/linux/http_upload.h>
2019-10-22 15:13:14 +08:00
# include<iostream>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <fcntl.h>
# include <event2/listener.h>
# include <event2/http.h>
# include <cjson/cJSON.h>
# include <event2/buffer.h>
2020-01-17 10:59:34 +08:00
# include <sys/socket.h> //inet_addr
# include <netinet/in.h> //inet_addr
# include <arpa/inet.h> //inet_addr
# include <MESA/stream.h>
2020-09-25 14:56:36 +08:00
# include <sys/stat.h>
# include <libgen.h>
2020-01-17 10:59:34 +08:00
2019-10-22 15:13:14 +08:00
# include "verify_policy.h"
2020-06-22 15:15:52 +08:00
# include <MESA/MESA_prof_load.h>
2020-01-17 10:59:34 +08:00
# include "verify_policy_utils.h"
2019-10-22 15:13:14 +08:00
2020-02-18 17:54:15 +08:00
struct verify_policy * g_verify_proxy = NULL ;
2019-10-22 15:13:14 +08:00
2020-01-09 14:32:00 +08:00
/* VERSION STRING */
# ifdef TARGET_GIT_VERSION
static __attribute__ ( ( __used__ ) ) const char * git_ver = TARGET_GIT_VERSION ;
2019-10-22 15:13:14 +08:00
# else
2020-01-09 14:32:00 +08:00
static __attribute__ ( ( __used__ ) ) const char * git_ver = " 1.1 " ;
2019-10-22 15:13:14 +08:00
# endif
const char * version ( )
{
2020-01-09 14:32:00 +08:00
return git_ver ;
2019-10-22 15:13:14 +08:00
}
2020-09-28 16:59:41 +08:00
static int signals [ ] = { SIGHUP , SIGPIPE , SIGUSR1 } ;
2023-03-30 19:50:00 +08:00
static int load_system_conf ( struct verify_policy * verify , const char * profile )
2019-10-22 15:13:14 +08:00
{
int xret = - 1 ;
2020-01-09 14:32:00 +08:00
2019-10-22 15:13:14 +08:00
xret = MESA_load_profile_uint_nodef ( profile , " CONFIG " , " thread-nu " , & ( verify - > nr_work_threads ) ) ;
2024-07-02 10:16:29 +08:00
if ( xret < 0 )
{
log_fatal ( verify - > logger , MODULE_VERIFY_POLICY , " Reading the number of running threads failed " ) ;
2019-10-22 15:13:14 +08:00
}
xret = MESA_load_profile_short_nodef ( profile , " LISTEN " , " port " , ( short * ) & ( verify - > listen_port ) ) ;
2024-07-02 10:16:29 +08:00
if ( xret < 0 )
{
log_fatal ( verify - > logger , MODULE_VERIFY_POLICY , " Reading the listening port failed " ) ;
2019-10-22 15:13:14 +08:00
}
2024-07-02 10:16:29 +08:00
log_info ( verify - > logger , MODULE_VERIFY_POLICY , " %s:%d " , " The Threads " , verify - > nr_work_threads ) ;
log_info ( verify - > logger , MODULE_VERIFY_POLICY , " %s:%d " , " Libevent Port " , verify - > listen_port ) ;
2019-10-22 15:13:14 +08:00
return xret ;
}
2023-05-09 14:26:43 +08:00
int tsg_policy_type_str2idx ( const char * action_str )
2019-10-22 15:13:14 +08:00
{
2020-01-17 10:59:34 +08:00
const char * policy_name [ __SCAN_POLICY_MAX ] ;
2024-01-31 15:25:30 +08:00
policy_name [ TSG_TABLE_SECURITY ] = " security " ;
2020-04-15 19:06:31 +08:00
policy_name [ PXY_TABLE_MANIPULATION ] = " pxy_manipulation " ;
2023-01-31 17:43:12 +08:00
policy_name [ TSG_TRAFFIC_SHAPING ] = " traffic_shaping " ;
2023-03-14 10:36:03 +08:00
policy_name [ TSG_SERVICE_CHAINGNG ] = " service_chaining " ;
2023-05-09 14:26:43 +08:00
policy_name [ PXY_TABLE_INTERCEPT ] = " pxy_intercept " ;
2023-07-24 18:41:01 +08:00
policy_name [ TSG_STATISTICS ] = " statistics " ;
2023-11-24 17:59:26 +08:00
policy_name [ TSG_MONITOR ] = " monitor " ;
2024-04-02 17:49:53 +08:00
policy_name [ DOS_PROTECTION ] = " dos_protection " ;
2023-03-30 19:50:00 +08:00
policy_name [ PXY_TABLE_DEFENCE ] = " active_defence " ;
2020-01-09 14:32:00 +08:00
2019-10-22 15:13:14 +08:00
size_t i = 0 ;
2020-01-17 10:59:34 +08:00
for ( i = 0 ; i < sizeof ( policy_name ) / sizeof ( const char * ) ; i + + )
2019-10-22 15:13:14 +08:00
{
2020-01-17 10:59:34 +08:00
if ( 0 = = strcasecmp ( action_str , policy_name [ i ] ) )
2019-10-22 15:13:14 +08:00
break ;
}
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] policyType= %s " , action_str ) ;
2023-05-09 14:26:43 +08:00
return i ;
2019-10-22 15:13:14 +08:00
}
2023-05-09 14:26:43 +08:00
int protoco_field_type_str2idx ( const char * action_str , char * buff , char * * p )
2019-10-22 15:13:14 +08:00
{
2023-05-09 14:26:43 +08:00
const char * table_name [ __TSG_OBJ_MAX ] = { 0 } ;
2024-01-31 15:25:30 +08:00
table_name [ TSG_OBJ_SOURCE_ADDR ] = " ATTR_SOURCE_IP " ;
table_name [ TSG_OBJ_DESTINATION_ADDR ] = " ATTR_DESTINATION_IP " ;
2023-11-24 14:28:04 +08:00
table_name [ TSG_OBJ_SUBSCRIBE_ID ] = " ATTR_SUBSCRIBER_ID " ;
table_name [ TSG_OBJ_APP_ID ] = " ATTR_APP_ID " ;
table_name [ TSG_OBJ_HTTP_URL ] = " ATTR_HTTP_URL " ;
table_name [ TSG_OBJ_HTTP_REQ_HDR ] = " ATTR_HTTP_REQ_HDR " ;
table_name [ TSG_OBJ_HTTP_REQ_BODY ] = " ATTR_HTTP_REQ_BODY " ;
table_name [ TSG_OBJ_HTTP_RES_HDR ] = " ATTR_HTTP_RES_HDR " ;
table_name [ TSG_OBJ_HTTP_RES_BODY ] = " ATTR_HTTP_RES_BODY " ;
table_name [ TSG_OBJ_SSL_CN ] = " ATTR_SSL_CN " ;
table_name [ TSG_OBJ_SSL_CN_CAT ] = " ATTR_SSL_CN_CAT " ;
table_name [ TSG_OBJ_SSL_SAN ] = " ATTR_SSL_SAN " ;
table_name [ TSG_OBJ_SSL_SAN_CAT ] = " ATTR_SSL_SAN_CAT " ;
table_name [ TSG_OBJ_DOH_QNAME ] = " ATTR_DOH_QNAME " ;
table_name [ TSG_OBJ_DNS_QNAME ] = " ATTR_DNS_QNAME " ;
table_name [ TSG_OBJ_MAIL_ACCOUNT ] = " ATTR_MAIL_ACCOUNT " ;
table_name [ TSG_OBJ_MAIL_FROM ] = " ATTR_MAIL_FROM " ;
table_name [ TSG_OBJ_MAIL_TO ] = " ATTR_MAIL_TO " ;
table_name [ TSG_OBJ_MAIL_SUBJECT ] = " ATTR_MAIL_SUBJECT " ;
table_name [ TSG_OBJ_MAIL_CONTENT ] = " ATTR_MAIL_CONTENT " ;
table_name [ TSG_OBJ_MAIL_ATT_NAME ] = " ATTR_MAIL_ATT_NAME " ;
table_name [ TSG_OBJ_MAIL_ATT_CONTENT ] = " ATTR_MAIL_ATT_CONTENT " ;
table_name [ TSG_OBJ_FTP_URI ] = " ATTR_FTP_URI " ;
table_name [ TSG_OBJ_FTP_CONTENT ] = " ATTR_FTP_CONTENT " ;
table_name [ TSG_OBJ_FTP_ACCOUNT ] = " ATTR_FTP_ACCOUNT " ;
table_name [ TSG_OBJ_SIP_FROM ] = " ATTR_SIP_ORIGINATOR_DESCRIPTION " ;
table_name [ TSG_OBJ_SIP_TO ] = " ATTR_SIP_RESPONDER_DESCRIPTION " ;
table_name [ TSG_OBJ_IMSI ] = " ATTR_GTP_IMSI " ;
table_name [ TSG_OBJ_PHONE_NUMBER ] = " ATTR_GTP_PHONE_NUMBER " ;
table_name [ TSG_OBJ_APN ] = " ATTR_GTP_APN " ;
table_name [ TSG_OBJ_TUNNEL ] = " ATTR_TUNNEL " ,
table_name [ TSG_OBJ_FLAG ] = " ATTR_FLAG " ;
table_name [ TSG_OBJ_GTP_IMEI ] = " ATTR_GTP_IMEI " ;
table_name [ TSG_OBJ_IP_SRC_ASN ] = " ATTR_SOURCE_ASN " ;
table_name [ TSG_OBJ_IP_DST_ASN ] = " ATTR_DESTINATION_ASN " ;
2024-04-02 17:49:53 +08:00
table_name [ TSG_OBJ_IP_SRC_GEO_COUNTRY ] = " ATTR_SOURCE_GEO_COUNTRY " ;
table_name [ TSG_OBJ_IP_SRC_GEO_SUPER_ADMINISTRATIVE_AREA ] = " ATTR_SOURCE_GEO_SUPER_ADMINISTRATIVE_AREA " ;
table_name [ TSG_OBJ_IP_SRC_GEO_ADMINISTRATIVE_AREA ] = " ATTR_SOURCE_GEO_ADMINISTRATIVE_AREA " ;
table_name [ TSG_OBJ_IP_SRC_GEO_SUB_ADMINISTRATIVE_AREA ] = " ATTR_SOURCE_GEO_SUB_ADMINISTRATIVE_AREA " ;
table_name [ TSG_OBJ_IP_DST_GEO_COUNTRY ] = " ATTR_DESTINATION_GEO_COUNTRY " ;
table_name [ TSG_OBJ_IP_DST_GEO_SUPER_ADMINISTRATIVE_AREA ] = " ATTR_DESTINATION_GEO_SUPER_ADMINISTRATIVE_AREA " ;
table_name [ TSG_OBJ_IP_DST_GEO_ADMINISTRATIVE_AREA ] = " ATTR_DESTINATION_GEO_ADMINISTRATIVE_AREA " ;
table_name [ TSG_OBJ_IP_DST_GEO_SUB_ADMINISTRATIVE_AREA ] = " ATTR_DESTINATION_GEO_SUB_ADMINISTRATIVE_AREA " ;
2023-12-25 10:28:29 +08:00
table_name [ TSG_OBJ_DST_SERVER_FQDN ] = " ATTR_SERVER_FQDN " ;
table_name [ TSG_OBJ_DST_SERVER_FQDN_CAT ] = " ATTR_SERVER_FQDN_CAT " ;
2024-01-31 15:25:30 +08:00
table_name [ TSG_OBJ_INTERNAL_ADDR ] = " ATTR_INTERNAL_IP " ;
table_name [ TSG_OBJ_EXTERNAL_ADDR ] = " ATTR_EXTERNAL_IP " ;
table_name [ TSG_OBJ_SOURCE_PORT ] = " ATTR_SOURCE_PORT " ;
table_name [ TSG_OBJ_DESTINATION_PORT ] = " ATTR_DESTINATION_PORT " ;
table_name [ TSG_OBJ_INTERNAL_PORT ] = " ATTR_INTERNAL_PORT " ;
table_name [ TSG_OBJ_EXTERNAL_PORT ] = " ATTR_EXTERNAL_PORT " ;
table_name [ TSG_OBJ_IP_PROTOCOL ] = " ATTR_IP_PROTOCOL " ;
table_name [ TSG_OBJ_SSL_ECH ] = " ATTR_SSL_ECH " ;
table_name [ TSG_OBJ_SSL_ESNI ] = " ATTR_SSL_ESNI " ;
table_name [ TSG_OBJ_SSL_NO_SNI ] = " ATTR_SSL_NO_SNI " ;
table_name [ TSG_OBJ_TUNNEL_LEVEL ] = " ATTR_TUNNEL_LEVEL " ;
2024-03-01 15:36:17 +08:00
table_name [ TSG_OBJ_INTERNAL_ASN ] = " ATTR_INTERNAL_ASN " ;
table_name [ TSG_OBJ_EXTERNAL_ASN ] = " ATTR_EXTERNAL_ASN " ;
2024-04-07 17:55:59 +08:00
table_name [ TSG_OBJ_TUNNEL_GTP_ENDPOINT ] = " ATTR_TUNNEL_GTP_ENDPOINT " ;
table_name [ TSG_OBJ_TUNNEL_GRE_ENDPOINT ] = " ATTR_TUNNEL_GRE_ENDPOINT " ;
table_name [ TSG_OBJ_TUNNEL_IP_IN_IP_ENDPOINT ] = " ATTR_TUNNEL_IP_IN_IP_ENDPOINT " ;
2024-01-31 15:25:30 +08:00
2020-01-17 10:59:34 +08:00
size_t i = 0 ;
2023-05-09 14:26:43 +08:00
for ( i = 0 ; i < __TSG_OBJ_MAX ; i + + )
2019-10-22 15:13:14 +08:00
{
2020-01-17 10:59:34 +08:00
if ( 0 = = strcasecmp ( action_str , table_name [ i ] ) )
break ;
2019-10-22 15:13:14 +08:00
}
2020-02-18 17:54:15 +08:00
* p + = snprintf ( * p , sizeof ( buff ) - ( * p - buff ) , " , protocolField=%s,%d " , action_str , ( int ) i ) ;
2020-01-17 10:59:34 +08:00
return i ;
}
2023-12-12 16:59:04 +08:00
int match_ip_attribute_name ( char * attri_name )
{
size_t i = 0 ;
const char * attribute_name_map [ ] = { " source " , " destination " , " tunnel_endpointa " , " tunnel_endpointb " , " internal " , " external " } ;
for ( i = 0 ; i < sizeof ( attribute_name_map ) / sizeof ( attribute_name_map [ 0 ] ) ; i + + )
{
if ( 0 = = strcasecmp ( attri_name , attribute_name_map [ i ] ) )
{
return i ;
}
}
return - 1 ;
}
2024-01-31 15:25:30 +08:00
struct ipaddr * ip_to_stream_addr ( const char * clientIp1 , unsigned int clientPort1 , const char * serverIp1 , unsigned int serverPort1 , int addr_type , char * buff , int * protocol )
2020-01-17 10:59:34 +08:00
{
struct ipaddr * ip_addr = ALLOC ( struct ipaddr , 1 ) ;
if ( addr_type = = 4 )
2019-10-22 15:13:14 +08:00
{
2020-01-17 10:59:34 +08:00
struct stream_tuple4_v4 * v4_addr = ALLOC ( struct stream_tuple4_v4 , 1 ) ;
ip_addr - > addrtype = ADDR_TYPE_IPV4 ;
inet_pton ( AF_INET , clientIp1 , & ( v4_addr - > saddr ) ) ;
2024-04-07 17:55:59 +08:00
v4_addr - > source = clientPort1 ;
2020-01-17 10:59:34 +08:00
inet_pton ( AF_INET , serverIp1 , & ( v4_addr - > daddr ) ) ;
2024-04-07 17:55:59 +08:00
v4_addr - > dest = serverPort1 ;
2020-01-17 10:59:34 +08:00
ip_addr - > v4 = v4_addr ;
2019-10-22 15:13:14 +08:00
}
2020-01-17 10:59:34 +08:00
if ( addr_type = = 6 )
2019-10-22 15:13:14 +08:00
{
2020-01-17 10:59:34 +08:00
struct stream_tuple4_v6 * v6_addr = ALLOC ( struct stream_tuple4_v6 , 1 ) ;
ip_addr - > addrtype = ADDR_TYPE_IPV6 ;
inet_pton ( AF_INET6 , clientIp1 , & ( v6_addr - > saddr ) ) ;
2024-04-07 17:55:59 +08:00
v6_addr - > source = clientPort1 ;
2020-01-17 10:59:34 +08:00
inet_pton ( AF_INET6 , serverIp1 , & ( v6_addr - > daddr ) ) ;
2024-04-07 17:55:59 +08:00
v6_addr - > dest = serverPort1 ;
2020-01-17 10:59:34 +08:00
ip_addr - > v6 = v6_addr ;
2019-10-22 15:13:14 +08:00
}
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] %s, clientIp1=%s, clientPort1=%d, serverIp=%s, serverPort=%d, addr_type=%d, protocol=%d " , buff ,
2024-01-31 15:25:30 +08:00
clientIp1 , clientPort1 , serverIp1 , serverPort1 , addr_type , * protocol ) ;
2020-01-17 18:57:51 +08:00
2020-01-17 10:59:34 +08:00
return ip_addr ;
}
2022-09-22 16:06:33 +08:00
struct ipaddr * tunnel_to_stream_addr ( const char * Ip , int addr_type )
{
struct ipaddr * ip_addr = ALLOC ( struct ipaddr , 1 ) ;
if ( addr_type = = 4 )
{
struct stream_tuple4_v4 * v4_addr = ALLOC ( struct stream_tuple4_v4 , 1 ) ;
ip_addr - > addrtype = ADDR_TYPE_IPV4 ;
inet_pton ( AF_INET , Ip , & ( v4_addr - > saddr ) ) ;
ip_addr - > v4 = v4_addr ;
}
if ( addr_type = = 6 )
{
struct stream_tuple4_v6 * v6_addr = ALLOC ( struct stream_tuple4_v6 , 1 ) ;
ip_addr - > addrtype = ADDR_TYPE_IPV6 ;
inet_pton ( AF_INET6 , Ip , & ( v6_addr - > saddr ) ) ;
ip_addr - > v6 = v6_addr ;
}
2024-07-02 10:16:29 +08:00
log_debug ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] attributeName = ip, clientIp1=%s, addr_type = %d " , Ip , addr_type ) ;
2022-09-22 16:06:33 +08:00
return ip_addr ;
}
2020-01-20 18:22:36 +08:00
void ipaddr_free ( struct ipaddr * ip_addr )
{
2024-01-31 15:25:30 +08:00
if ( ip_addr = = NULL )
{
return ;
}
2020-01-20 18:22:36 +08:00
if ( ip_addr - > addrtype = = ADDR_TYPE_IPV4 )
{
free ( ip_addr - > v4 ) ;
}
if ( ip_addr - > addrtype = = ADDR_TYPE_IPV6 )
{
free ( ip_addr - > v6 ) ;
}
free ( ip_addr ) ;
}
2024-01-31 15:25:30 +08:00
static struct ipaddr * get_ip_from_json ( cJSON * attributeValue , const char * attributeName , int * protocol , char * buff )
2020-04-15 19:06:31 +08:00
{
cJSON * item = NULL ;
2023-12-12 16:59:04 +08:00
int addr_type = 0 ;
2020-07-08 10:36:20 +08:00
const char * Ip = NULL ;
unsigned int Port = 0 ;
2020-04-15 19:06:31 +08:00
2024-03-01 15:36:17 +08:00
if ( attributeName = = NULL )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " The attributeType is of type iP, but the attributeName is empty, resulting in IP type parsing failure. " ) ;
2024-03-01 15:36:17 +08:00
return NULL ;
}
2020-07-08 10:36:20 +08:00
item = cJSON_GetObjectItem ( attributeValue , " ip " ) ;
if ( item & & item - > type = = cJSON_String ) Ip = item - > valuestring ;
item = cJSON_GetObjectItem ( attributeValue , " port " ) ;
if ( item & & item - > type = = cJSON_String ) Port = atoi ( item - > valuestring ) ;
2020-04-15 19:06:31 +08:00
item = cJSON_GetObjectItem ( attributeValue , " protocol " ) ;
2023-12-12 16:59:04 +08:00
if ( item & & item - > type = = cJSON_Number ) * protocol = item - > valueint ;
2020-04-15 19:06:31 +08:00
item = cJSON_GetObjectItem ( attributeValue , " addrType " ) ;
if ( item & & item - > type = = cJSON_Number ) addr_type = item - > valueint ;
2024-03-01 15:36:17 +08:00
if ( strcasecmp ( attributeName , " ip_protocol " ) = = 0 )
{
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] %s, protocol=%d " , buff , * protocol ) ;
2024-03-01 15:36:17 +08:00
return NULL ;
}
2020-04-15 19:06:31 +08:00
struct ipaddr * ip_addr = NULL ;
2023-12-12 16:59:04 +08:00
if ( strcasecmp ( attributeName , " source " ) = = 0 | | strcasecmp ( attributeName , " internal " ) = = 0 | |
strcasecmp ( attributeName , " tunnel_endpointa " ) = = 0 | | strcasecmp ( attributeName , " tunnel_endpointb " ) = = 0 )
2020-07-08 10:36:20 +08:00
{
2024-01-31 15:25:30 +08:00
ip_addr = ip_to_stream_addr ( Ip , Port , " 0.0.0.0 " , 0 , addr_type , buff , protocol ) ;
2020-07-08 10:36:20 +08:00
}
2020-04-15 19:06:31 +08:00
2023-12-12 16:59:04 +08:00
if ( strcasecmp ( attributeName , " destination " ) = = 0 | | strcasecmp ( attributeName , " external " ) = = 0 )
2020-07-08 10:36:20 +08:00
{
2024-01-31 15:25:30 +08:00
ip_addr = ip_to_stream_addr ( " 0.0.0.0 " , 0 , Ip , Port , addr_type , buff , protocol ) ;
2020-07-08 10:36:20 +08:00
}
2020-04-15 19:06:31 +08:00
return ip_addr ;
}
2024-01-31 15:25:30 +08:00
static char * get_port_from_json ( cJSON * attributeValue , int * protocol , char * buff )
{
cJSON * item = NULL ;
char * string = NULL ;
item = cJSON_GetObjectItem ( attributeValue , " port " ) ;
if ( item & & item - > type = = cJSON_String )
{
string = item - > valuestring ;
}
item = cJSON_GetObjectItem ( attributeValue , " protocol " ) ;
if ( item & & item - > type = = cJSON_Number )
{
* protocol = item - > valueint ;
2024-07-02 10:16:29 +08:00
}
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] %s, port=%s, protocol=%d " , buff , string , * protocol ) ;
2024-01-31 15:25:30 +08:00
return string ;
}
static inline int match_attributeType_in_numeric ( const char * attribute_type , int table_id )
{
if ( 0 = = strcasecmp ( attribute_type , " numeric " ) | | 0 = = strcasecmp ( attribute_type , " flag " ) | |
0 = = strcasecmp ( attribute_type , " boolean " ) | | table_id = = TSG_OBJ_IP_PROTOCOL )
{
return 1 ;
}
else
{
return 0 ;
}
}
2020-04-15 19:06:31 +08:00
static int get_attribute_from_json ( int curr_id , cJSON * subchild , struct verify_policy_query * policy_query )
{
int xret = - 1 ;
2024-01-31 15:25:30 +08:00
const char * attribute_type = NULL ;
2023-10-12 18:40:45 +08:00
char buff [ VERIFY_STRING_MAX * 2 ] , * p = NULL ;
2024-04-07 17:55:59 +08:00
cJSON * item = NULL , * attributeValue = NULL , * tunnelType_item = NULL ;
2020-04-15 19:06:31 +08:00
p = buff ;
2024-01-31 15:25:30 +08:00
item = cJSON_GetObjectItem ( subchild , " attributeType " ) ;
if ( item & & item - > type = = cJSON_String )
{
attribute_type = item - > valuestring ;
p + = snprintf ( p , sizeof ( buff ) - ( p - buff ) , " attributeType = %s " , attribute_type ) ;
}
2020-04-15 19:06:31 +08:00
item = cJSON_GetObjectItem ( subchild , " attributeName " ) ;
if ( item & & item - > type = = cJSON_String )
{
2023-12-21 16:06:45 +08:00
policy_query - > request_object [ curr_id ] . attri_name = item - > valuestring ;
2024-01-31 15:25:30 +08:00
p + = snprintf ( p , sizeof ( buff ) - ( p - buff ) , " , attributeName = %s " , policy_query - > request_object [ curr_id ] . attri_name ) ;
2020-04-15 19:06:31 +08:00
}
2023-12-21 16:06:45 +08:00
policy_query - > request_object [ curr_id ] . attributes = cJSON_Duplicate ( subchild , 1 ) ;
2020-04-15 19:06:31 +08:00
item = cJSON_GetObjectItem ( subchild , " tableName " ) ;
if ( item & & item - > type = = cJSON_String )
{
2023-12-21 16:06:45 +08:00
policy_query - > request_object [ curr_id ] . table_id = protoco_field_type_str2idx ( item - > valuestring , buff , & p ) ;
if ( policy_query - > request_object [ curr_id ] . table_id = = __TSG_OBJ_MAX )
2023-11-30 18:24:21 +08:00
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Get table id failed form table name:%s " , item - > valuestring ) ;
2023-11-30 18:24:21 +08:00
return xret ;
}
2020-04-15 19:06:31 +08:00
}
2023-05-09 14:26:43 +08:00
2020-04-15 19:06:31 +08:00
attributeValue = cJSON_GetObjectItem ( subchild , " attributeValue " ) ;
if ( attributeValue = = NULL | | attributeValue - > type ! = cJSON_Object )
{
goto finish ;
}
2021-04-19 16:35:36 +08:00
2024-04-09 15:33:34 +08:00
tunnelType_item = cJSON_GetObjectItem ( attributeValue , " tunnelType " ) ;
2024-04-07 17:55:59 +08:00
if ( tunnelType_item & & tunnelType_item - > type = = cJSON_String )
{
policy_query - > request_object [ curr_id ] . tunnel_type = tunnelType_item - > valuestring ;
2024-04-09 15:33:34 +08:00
p + = snprintf ( p , sizeof ( buff ) - ( p - buff ) , " , tunnelType=%s " , policy_query - > request_object [ curr_id ] . tunnel_type ) ;
2024-04-07 17:55:59 +08:00
}
2024-01-31 15:25:30 +08:00
if ( 0 = = strcasecmp ( attribute_type , " ip " ) )
{
policy_query - > request_object [ curr_id ] . ip_addr = get_ip_from_json ( attributeValue , policy_query - > request_object [ curr_id ] . attri_name , & ( policy_query - > request_object [ curr_id ] . numeric ) , buff ) ;
goto end ;
}
if ( 0 = = strcasecmp ( attribute_type , " port " ) )
2022-09-22 16:06:33 +08:00
{
2024-01-31 15:25:30 +08:00
policy_query - > request_object [ curr_id ] . string = get_port_from_json ( attributeValue , & ( policy_query - > request_object [ curr_id ] . numeric ) , buff ) ;
2022-09-22 16:06:33 +08:00
goto end ;
}
2021-04-19 16:35:36 +08:00
item = cJSON_GetObjectItem ( attributeValue , " district " ) ;
if ( item ! = NULL )
{
2023-12-21 16:06:45 +08:00
policy_query - > request_object [ curr_id ] . district = item - > valuestring ;
p + = snprintf ( p , sizeof ( buff ) - ( p - buff ) , " , district = %s " , policy_query - > request_object [ curr_id ] . district ) ;
2021-04-19 16:35:36 +08:00
}
2024-01-31 15:25:30 +08:00
if ( match_attributeType_in_numeric ( attribute_type , policy_query - > request_object [ curr_id ] . table_id ) )
2020-04-15 19:06:31 +08:00
{
2022-12-28 14:36:53 +08:00
item = cJSON_GetObjectItem ( attributeValue , " numeric " ) ;
if ( item & & item - > type = = cJSON_Number )
{
2023-12-21 16:06:45 +08:00
policy_query - > request_object [ curr_id ] . numeric = item - > valueint ;
p + = snprintf ( p , sizeof ( buff ) - ( p - buff ) , " , content = %d " , policy_query - > request_object [ curr_id ] . numeric ) ;
2022-12-28 14:36:53 +08:00
}
}
else
{
item = cJSON_GetObjectItem ( attributeValue , " string " ) ;
if ( item ! = NULL )
{
2024-01-31 15:25:30 +08:00
policy_query - > request_object [ curr_id ] . string = item - > valuestring ;
p + = snprintf ( p , sizeof ( buff ) - ( p - buff ) , " , content = %s " , policy_query - > request_object [ curr_id ] . string ) ;
2022-12-28 14:36:53 +08:00
}
2020-04-15 19:06:31 +08:00
}
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] %s " , buff ) ;
2023-10-12 18:40:45 +08:00
memset ( buff , 0 , VERIFY_STRING_MAX * 2 ) ;
2020-04-15 19:06:31 +08:00
end :
xret = 1 ;
finish :
return xret ;
}
2023-05-11 11:50:34 +08:00
enum verify_type get_verify_type ( cJSON * data_json )
{
cJSON * item = NULL ;
enum verify_type q_type = VERIFY_TYPE_POLICY ;
item = cJSON_GetObjectItem ( data_json , " verifyType " ) ;
if ( item & & item - > type = = cJSON_String )
{
if ( 0 = = strcasecmp ( item - > valuestring , " policy " ) )
{
q_type = VERIFY_TYPE_POLICY ;
}
if ( 0 = = strcasecmp ( item - > valuestring , " regex " ) )
{
q_type = VERIFY_TYPE_REGEX ;
}
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] verifyType= %s " , item - > valuestring ) ;
2023-05-11 11:50:34 +08:00
}
return q_type ;
}
static int get_query_result_regex ( cJSON * verifylist_array_item , cJSON * data_obj )
{
int cur_id = 0 , i = 0 , is_valid [ 32 ] = { 0 } ;
2023-05-11 16:48:59 +08:00
cJSON * regexstr_obj [ 32 ] , * attributes = NULL ;
2023-05-11 11:50:34 +08:00
cJSON * item = NULL , * subchild = NULL ;
attributes = cJSON_GetObjectItem ( verifylist_array_item , " verifyRegex " ) ;
if ( attributes = = NULL | | attributes - > type ! = cJSON_Array )
{
return - 1 ;
}
for ( subchild = attributes - > child ; subchild ! = NULL ; subchild = subchild - > next )
{
item = cJSON_GetObjectItem ( subchild , " regexStr " ) ;
if ( item & & item - > type = = cJSON_String )
{
is_valid [ cur_id ] = policy_verify_regex_expression ( item - > valuestring ) ;
}
regexstr_obj [ cur_id ] = cJSON_Duplicate ( item , 1 ) ;
cur_id + + ;
}
cJSON * verify_regex_obj = NULL ;
cJSON * verifyRegex = cJSON_CreateArray ( ) ;
2023-05-11 16:48:59 +08:00
cJSON_AddItemToObject ( data_obj , " verifyRegex " , verifyRegex ) ;
2023-05-11 11:50:34 +08:00
for ( i = 0 ; i < cur_id ; i + + )
{
verify_regex_obj = cJSON_CreateObject ( ) ;
cJSON_AddItemToObject ( verify_regex_obj , " regexStr " , regexstr_obj [ i ] ) ;
cJSON_AddNumberToObject ( verify_regex_obj , " isValid " , is_valid [ i ] ) ;
cJSON_AddItemToArray ( verifyRegex , verify_regex_obj ) ;
}
return 1 ;
}
2023-11-23 11:17:11 +08:00
static void get_count_form_attributeName ( void * ctx , cJSON * subchild )
{
cJSON * item = NULL ;
item = cJSON_GetObjectItem ( subchild , " attributeName " ) ;
if ( item & & item - > type = = cJSON_String )
{
if ( 0 = = strcasecmp ( item - > valuestring , " tunnel_endpointa " ) )
{
verify_policy_tunnle_add ( ctx ) ;
}
if ( 0 = = strcasecmp ( item - > valuestring , " tunnel_endpointb " ) )
{
verify_policy_tunnle_add ( ctx ) ;
}
}
return ;
}
2023-05-11 11:50:34 +08:00
int get_query_result_policy ( cJSON * subitem , cJSON * data_obj , int thread_id )
2020-01-17 10:59:34 +08:00
{
2020-01-17 18:57:51 +08:00
int i = 0 ;
2020-10-29 16:23:58 +08:00
int hit_cnt = 0 , xret = 0 ;
2023-05-11 11:50:34 +08:00
cJSON * item = NULL , * subchild = NULL , * attributes = NULL ;
2020-04-15 19:06:31 +08:00
struct verify_policy_query * verify_policy = NULL ;
2020-01-17 10:59:34 +08:00
2023-05-11 11:50:34 +08:00
verify_policy = ALLOC ( struct verify_policy_query , 1 ) ;
2023-11-24 14:28:04 +08:00
item = cJSON_GetObjectItem ( subitem , " type " ) ;
2023-05-11 11:50:34 +08:00
if ( item & & item - > type = = cJSON_String )
{
verify_policy - > compile_table_id = tsg_policy_type_str2idx ( item - > valuestring ) ;
if ( verify_policy - > compile_table_id > = __SCAN_POLICY_MAX )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " policy type error, policy id = %d " , verify_policy - > compile_table_id ) ;
2023-05-11 11:50:34 +08:00
goto free ;
}
}
item = cJSON_GetObjectItem ( subitem , " vsysId " ) ;
if ( item & & item - > type = = cJSON_Number )
{
verify_policy - > vsys_id = item - > valueint ;
}
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] vsysId= %d " , verify_policy - > vsys_id ) ;
2023-05-11 11:50:34 +08:00
item = cJSON_GetObjectItem ( subitem , " verifySession " ) ;
if ( item = = NULL | | item - > type ! = cJSON_Object )
{
goto free ;
}
attributes = cJSON_GetObjectItem ( item , " attributes " ) ;
if ( attributes & & attributes - > type = = cJSON_Array )
{
void * ctx = policy_scan_ctx_new ( thread_id , verify_policy - > vsys_id , verify_policy - > compile_table_id ) ;
for ( subchild = attributes - > child ; subchild ! = NULL ; subchild = subchild - > next )
{
2023-11-23 11:17:11 +08:00
get_count_form_attributeName ( ctx , subchild ) ;
2023-05-11 11:50:34 +08:00
}
for ( subchild = attributes - > child ; subchild ! = NULL ; subchild = subchild - > next )
{
xret = get_attribute_from_json ( i , subchild , verify_policy ) ;
if ( xret < 0 )
{
goto free ;
}
2023-12-21 16:06:45 +08:00
hit_cnt = policy_verify_scan ( verify_policy - > vsys_id , verify_policy - > compile_table_id , & verify_policy - > request_object [ i ] , ctx ) ;
if ( match_ip_attribute_name ( verify_policy - > request_object [ i ] . attri_name ) > = 0 )
2023-05-11 11:50:34 +08:00
{
2023-12-21 16:06:45 +08:00
ipaddr_free ( verify_policy - > request_object [ i ] . ip_addr ) ;
2023-05-11 11:50:34 +08:00
}
i + + ;
}
2023-06-28 16:07:27 +08:00
http_hit_policy_list ( verify_policy , i , hit_cnt , data_obj , ctx ) ;
2023-05-11 11:50:34 +08:00
int item = 0 ;
cJSON * verfifySession = cJSON_CreateObject ( ) ;
cJSON_AddItemToObject ( data_obj , " verifySession " , verfifySession ) ;
cJSON * attributes = cJSON_CreateArray ( ) ;
cJSON_AddItemToObject ( verfifySession , " attributes " , attributes ) ;
for ( item = 0 ; item < i ; item + + )
{
2023-12-21 16:06:45 +08:00
http_get_scan_status ( & verify_policy - > request_object [ item ] , verify_policy - > compile_table_id , attributes , data_obj , ctx ) ;
2023-05-11 11:50:34 +08:00
}
policy_scan_ctx_free ( ctx ) ;
}
i = 0 ;
free :
if ( verify_policy )
{
FREE ( & verify_policy ) ;
}
return hit_cnt ;
}
2023-08-03 17:22:02 +08:00
cJSON * get_query_from_request ( const char * data , ssize_t data_len , int thread_id )
2023-05-11 11:50:34 +08:00
{
int hit_cnt = 0 ;
2020-01-17 10:59:34 +08:00
cJSON * data_json = cJSON_Parse ( data ) ;
if ( data_json = = NULL )
2019-10-22 15:13:14 +08:00
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Failed to parse the request data. " ) ;
2020-01-17 10:59:34 +08:00
return NULL ;
2019-10-22 15:13:14 +08:00
}
2020-02-18 17:54:15 +08:00
cJSON * policy_obj = NULL , * data_obj = NULL ;
2020-01-17 10:59:34 +08:00
policy_obj = cJSON_CreateObject ( ) ;
cJSON_AddNumberToObject ( policy_obj , " code " , 200 ) ;
cJSON_AddStringToObject ( policy_obj , " msg " , " Success " ) ;
data_obj = cJSON_CreateObject ( ) ;
cJSON_AddItemToObject ( policy_obj , " data " , data_obj ) ;
2023-05-11 11:50:34 +08:00
int verify_type = get_verify_type ( data_json ) ;
cJSON * item = NULL , * subitem = NULL ;
2020-01-17 10:59:34 +08:00
item = cJSON_GetObjectItem ( data_json , " verifyList " ) ;
2019-10-22 15:13:14 +08:00
if ( item & & item - > type = = cJSON_Array )
{
for ( subitem = item - > child ; subitem ! = NULL ; subitem = subitem - > next )
{
2023-05-11 11:50:34 +08:00
if ( verify_type = = VERIFY_TYPE_REGEX )
2019-10-22 15:13:14 +08:00
{
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [I] data= %.*s " , ( int ) data_len , data ) ;
2023-05-11 11:50:34 +08:00
hit_cnt = get_query_result_regex ( subitem , data_obj ) ;
2020-02-18 17:54:15 +08:00
}
2022-10-10 15:31:41 +08:00
2023-05-11 11:50:34 +08:00
if ( verify_type = = VERIFY_TYPE_POLICY )
2022-10-10 15:31:41 +08:00
{
2023-05-11 11:50:34 +08:00
hit_cnt = get_query_result_policy ( subitem , data_obj , thread_id ) ;
2022-10-10 15:31:41 +08:00
}
2020-04-15 19:06:31 +08:00
}
2020-03-06 16:02:42 +08:00
if ( hit_cnt > = 0 )
2020-02-18 17:54:15 +08:00
{
cJSON_AddBoolToObject ( policy_obj , " success " , true ) ;
}
else
{
cJSON_AddBoolToObject ( policy_obj , " success " , false ) ;
2020-01-09 14:32:00 +08:00
}
2019-10-22 15:13:14 +08:00
}
2020-01-17 10:59:34 +08:00
cJSON_Delete ( data_json ) ;
return policy_obj ;
2019-10-22 15:13:14 +08:00
}
2020-01-17 10:59:34 +08:00
static int evhttp_socket_send ( struct evhttp_request * req , char * sendbuf )
2019-10-22 15:13:14 +08:00
{
struct evbuffer * evb = NULL ;
/* This holds the content we're sending. */
evb = evbuffer_new ( ) ;
if ( sendbuf [ 0 ] = = ' \0 ' & & req = = NULL ) {
goto err ;
}
evhttp_add_header ( evhttp_request_get_output_headers ( req ) ,
2020-02-27 14:40:54 +08:00
" Content-Type " , " application/json " ) ;
2019-10-22 15:13:14 +08:00
evhttp_add_header ( evhttp_request_get_output_headers ( req ) , " Connection " , " keep-alive " ) ;
evbuffer_add_printf ( evb , " %s " , sendbuf ) ;
evhttp_send_reply ( req , HTTP_OK , " OK " , evb ) ;
goto done ;
err :
evhttp_send_error ( req , HTTP_NOTFOUND , " Document was not found " ) ;
done :
evbuffer_free ( evb ) ;
return 0 ;
}
void evhttp_request_cb ( struct evhttp_request * evh_req , void * arg )
2020-01-09 14:32:00 +08:00
{
2020-01-17 10:59:34 +08:00
char * policy_payload = NULL ; cJSON * policy_obj ;
2019-10-22 15:13:14 +08:00
struct evbuffer * evbuf_body = NULL ;
2020-01-09 14:32:00 +08:00
char * input = NULL ; ssize_t inputlen = 0 ;
2020-02-18 17:54:15 +08:00
struct verify_policy_thread * thread_ctx = ( struct verify_policy_thread * ) arg ;
2019-10-22 15:13:14 +08:00
if ( evhttp_request_get_command ( evh_req ) ! = EVHTTP_REQ_POST )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " FAILED (post type) " ) ;
2019-10-22 15:13:14 +08:00
goto error ;
}
2020-01-09 14:32:00 +08:00
evbuf_body = evhttp_request_get_input_buffer ( evh_req ) ;
2019-10-22 15:13:14 +08:00
if ( ! evbuf_body | | 0 = = ( inputlen = evbuffer_get_length ( evbuf_body ) ) | | ! ( input = ( char * ) evbuffer_pullup ( evbuf_body , inputlen ) ) )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Failed to get post data information. " ) ;
2019-10-22 15:13:14 +08:00
goto error ;
}
2020-01-17 10:59:34 +08:00
2023-08-03 17:22:02 +08:00
policy_obj = get_query_from_request ( input , inputlen , thread_ctx - > id ) ;
2020-01-17 10:59:34 +08:00
if ( policy_obj = = NULL )
{
goto error ;
}
policy_payload = cJSON_PrintUnformatted ( policy_obj ) ;
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " [O] %s " , policy_payload ) ;
2020-01-17 10:59:34 +08:00
evhttp_socket_send ( evh_req , policy_payload ) ;
cJSON_Delete ( policy_obj ) ;
free ( policy_payload ) ;
2019-10-22 15:13:14 +08:00
goto finish ;
2020-01-09 14:32:00 +08:00
2019-10-22 15:13:14 +08:00
error :
evhttp_send_error ( evh_req , HTTP_BADREQUEST , 0 ) ;
finish :
return ;
}
2020-02-18 17:54:15 +08:00
void * verify_policy_thread_func ( void * arg )
2019-10-22 15:13:14 +08:00
{
struct evhttp_bound_socket * bound = NULL ;
2020-02-18 17:54:15 +08:00
struct verify_policy_thread * thread_ctx = ( struct verify_policy_thread * ) arg ;
2020-01-09 14:32:00 +08:00
2019-10-22 15:13:14 +08:00
thread_ctx - > base = event_base_new ( ) ;
2020-01-09 14:32:00 +08:00
if ( ! thread_ctx - > base )
2019-10-22 15:13:14 +08:00
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Can'thread_ctx allocate event base " ) ;
2019-10-22 15:13:14 +08:00
goto finish ;
}
thread_ctx - > http = evhttp_new ( thread_ctx - > base ) ;
2020-01-09 14:32:00 +08:00
if ( ! thread_ctx - > http )
2019-10-22 15:13:14 +08:00
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " couldn'thread_ctx create evhttp. Exiting. " ) ;
2019-10-22 15:13:14 +08:00
goto error ;
}
2020-01-09 14:32:00 +08:00
2020-02-18 17:54:15 +08:00
evhttp_set_cb ( thread_ctx - > http , " /v1/policy/verify " , evhttp_request_cb , thread_ctx ) ;
2020-01-09 14:32:00 +08:00
2019-10-22 15:13:14 +08:00
bound = evhttp_accept_socket_with_handle ( thread_ctx - > http , thread_ctx - > accept_fd ) ;
2020-01-09 14:32:00 +08:00
if ( bound ! = NULL )
2019-10-22 15:13:14 +08:00
{
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Bound(%p) to port %d - Awaiting connections ... " , bound ,
2019-10-22 15:13:14 +08:00
g_verify_proxy - > listen_port ) ;
}
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Work thread %u is run... " , thread_ctx - > id ) ;
2020-01-09 14:32:00 +08:00
2019-10-22 15:13:14 +08:00
event_base_dispatch ( thread_ctx - > base ) ;
error :
event_base_free ( thread_ctx - > base ) ;
finish :
return NULL ;
}
static int
evutil_fast_socket_nonblocking ( evutil_socket_t fd )
{
# ifdef _WIN32
return evutil_make_socket_nonblocking ( fd ) ;
# else
if ( fcntl ( fd , F_SETFL , O_NONBLOCK ) = = - 1 ) {
return - 1 ;
}
return 0 ;
# endif
}
static int
evutil_fast_socket_closeonexec ( evutil_socket_t fd )
{
# if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
if ( fcntl ( fd , F_SETFD , FD_CLOEXEC ) = = - 1 ) {
return - 1 ;
}
# endif
return 0 ;
}
evutil_socket_t
evutil_socket_ ( int domain , int type , int protocol )
{
evutil_socket_t r ;
# if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
r = socket ( domain , type , protocol ) ;
if ( r > = 0 )
return r ;
else if ( ( type & ( SOCK_NONBLOCK | SOCK_CLOEXEC ) ) = = 0 )
return - 1 ;
# endif
# define SOCKET_TYPE_MASK (~(EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC))
r = socket ( domain , type & SOCKET_TYPE_MASK , protocol ) ;
if ( r < 0 )
return - 1 ;
if ( type & EVUTIL_SOCK_NONBLOCK ) {
if ( evutil_fast_socket_nonblocking ( r ) < 0 ) {
evutil_closesocket ( r ) ;
return - 1 ;
}
}
if ( type & EVUTIL_SOCK_CLOEXEC ) {
if ( evutil_fast_socket_closeonexec ( r ) < 0 ) {
evutil_closesocket ( r ) ;
return - 1 ;
}
}
return r ;
}
static evutil_socket_t
evhttp_listen_socket_byuser ( const struct sockaddr * sa , int socklen ,
unsigned flags , int backlog )
{
evutil_socket_t fd ;
int on = 1 ;
int family = sa ? sa - > sa_family : AF_UNSPEC ;
int socktype = SOCK_STREAM | EVUTIL_SOCK_NONBLOCK ;
if ( flags & LEV_OPT_CLOSE_ON_EXEC )
socktype | = EVUTIL_SOCK_CLOEXEC ;
fd = evutil_socket_ ( family , socktype , 0 ) ;
if ( fd = = - 1 )
return fd ;
if ( setsockopt ( fd , SOL_SOCKET , SO_KEEPALIVE , ( void * ) & on , sizeof ( on ) ) < 0 )
goto err ;
if ( flags & LEV_OPT_REUSEABLE ) {
if ( evutil_make_listen_socket_reuseable ( fd ) < 0 )
goto err ;
}
if ( flags & LEV_OPT_REUSEABLE_PORT ) {
if ( evutil_make_listen_socket_reuseable_port ( fd ) < 0 ) {
goto err ;
}
}
if ( sa ) {
if ( bind ( fd , sa , socklen ) < 0 )
goto err ;
}
if ( listen ( fd , backlog ) = = - 1 ) {
goto err ;
}
return fd ;
err :
evutil_closesocket ( fd ) ;
return fd ;
}
2023-03-30 19:50:00 +08:00
int verify_policy_work_thread_run ( struct verify_policy * verify )
2019-10-22 15:13:14 +08:00
{
int xret = 0 ;
unsigned int tid = 0 ;
2020-02-18 17:54:15 +08:00
struct verify_policy_thread * thread_ctx = NULL ;
2019-10-22 15:13:14 +08:00
struct sockaddr_in sin ;
memset ( & sin , 0 , sizeof ( struct sockaddr_in ) ) ;
sin . sin_family = AF_INET ;
sin . sin_port = htons ( verify - > listen_port ) ;
evutil_socket_t accept_fd = evhttp_listen_socket_byuser ( ( struct sockaddr * ) & sin , sizeof ( struct sockaddr_in ) , LEV_OPT_REUSEABLE_PORT | LEV_OPT_CLOSE_ON_FREE , - 1 ) ;
if ( accept_fd < 0 )
{
2024-07-02 10:16:29 +08:00
log_fatal ( verify - > logger , MODULE_VERIFY_POLICY , " Could not create a listen! " ) ;
2019-10-22 15:13:14 +08:00
goto finish ;
}
for ( tid = 0 ; tid < verify - > nr_work_threads ; tid + + )
{
2020-02-18 17:54:15 +08:00
verify - > work_threads [ tid ] = ALLOC ( struct verify_policy_thread , 1 ) ;
2019-10-22 15:13:14 +08:00
thread_ctx = verify - > work_threads [ tid ] ;
thread_ctx - > id = tid ;
thread_ctx - > accept_fd = accept_fd ;
2020-02-18 17:54:15 +08:00
thread_ctx - > routine = verify_policy_thread_func ;
2019-10-22 15:13:14 +08:00
if ( pthread_create ( & thread_ctx - > pid , thread_ctx - > attr , thread_ctx - > routine , thread_ctx ) )
{
2024-07-02 10:16:29 +08:00
log_fatal ( verify - > logger , MODULE_VERIFY_POLICY , " %s " , strerror ( errno ) ) ;
2019-10-22 15:13:14 +08:00
goto finish ;
}
if ( pthread_detach ( thread_ctx - > pid ) )
{
2024-07-02 10:16:29 +08:00
log_fatal ( verify - > logger , MODULE_VERIFY_POLICY , " %s " , strerror ( errno ) ) ;
2019-10-22 15:13:14 +08:00
goto finish ;
}
}
finish :
return xret ;
}
2020-09-25 14:56:36 +08:00
struct breakpad_instance
{
unsigned int en_breakpad ;
char minidump_dir_prefix [ VERIFY_STRING_MAX ] ;
google_breakpad : : ExceptionHandler * exceptionHandler ;
/* Upload to crash server */
unsigned int en_breakpad_upload ;
char minidump_sentry_upload_url [ VERIFY_STRING_MAX ] ;
/* Upload tools name */
char upload_tools_filename [ VERIFY_STRING_MAX ] ;
/* Upload tools exec command */
char * upload_tools_exec_argv [ 64 ] ;
char * minidump_filename ;
} ;
static void _mkdir ( const char * dir )
{
char tmp [ PATH_MAX ] ;
char * p = NULL ;
size_t len ;
snprintf ( tmp , sizeof ( tmp ) , " %s " , dir ) ;
len = strlen ( tmp ) ;
if ( tmp [ len - 1 ] = = ' / ' )
tmp [ len - 1 ] = 0 ;
for ( p = tmp + 1 ; * p ; p + + )
{
if ( * p = = ' / ' )
{
* p = 0 ;
mkdir ( tmp , S_IRWXU ) ;
* p = ' / ' ;
}
}
mkdir ( tmp , S_IRWXU ) ;
}
int breakpad_init_minidump_upload ( struct breakpad_instance * instance , const char * profile )
{
int ret = 0 ;
char execpath [ PATH_MAX ] = { } ;
char * execdirname = NULL ;
ret = MESA_load_profile_string_nodef ( profile , " system " , " breakpad_upload_url " ,
instance - > minidump_sentry_upload_url , sizeof ( instance - > minidump_sentry_upload_url ) ) ;
if ( unlikely ( ret < 0 ) )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " breakpad_upload_url is necessary, failed. " ) ;
2020-09-25 14:56:36 +08:00
goto errout ;
}
ret = readlink ( " /proc/self/exe " , execpath , sizeof ( execpath ) ) ;
if ( unlikely ( ret < 0 ) )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Failed at readlink /proc/self/exec: %s " , strerror ( errno ) ) ;
2020-09-25 14:56:36 +08:00
/* after log, reset errno */
errno = 0 ;
goto errout ;
}
execdirname = dirname ( execpath ) ;
snprintf ( instance - > upload_tools_filename , sizeof ( instance - > upload_tools_filename ) - 1 ,
" %s/%s " , execdirname , " minidump_upload " ) ;
/* Execfile */
instance - > upload_tools_exec_argv [ 0 ] = strdup ( instance - > upload_tools_filename ) ;
/* Firstly, Product Name and Product Version */
instance - > upload_tools_exec_argv [ 1 ] = strdup ( " -p " ) ;
instance - > upload_tools_exec_argv [ 2 ] = strdup ( " tfe " ) ;
instance - > upload_tools_exec_argv [ 3 ] = strdup ( " -v " ) ;
instance - > upload_tools_exec_argv [ 4 ] = strdup ( version ( ) ) ;
/* Minidump file location, now we don't know it */
instance - > minidump_filename = ( char * ) ALLOC ( char , PATH_MAX ) ;
instance - > upload_tools_exec_argv [ 5 ] = instance - > minidump_filename ;
/* Minidup upload url */
instance - > upload_tools_exec_argv [ 6 ] = strdup ( instance - > minidump_sentry_upload_url ) ;
instance - > upload_tools_exec_argv [ 7 ] = NULL ;
return 0 ;
errout :
return - 1 ;
}
static bool tfe_breakpad_dump_to_file ( const google_breakpad : : MinidumpDescriptor & descriptor ,
void * context , bool succeeded )
{
fprintf ( stderr , " Crash happened, minidump path: %s \n " , descriptor . path ( ) ) ;
return succeeded ;
}
static bool tfe_breakpad_dump_and_report ( const google_breakpad : : MinidumpDescriptor & descriptor ,
void * context , bool succeeded )
{
struct breakpad_instance * instance = g_verify_proxy - > breakpad ;
int ret = 0 ;
strncpy ( instance - > minidump_filename , descriptor . path ( ) , PATH_MAX - 1 ) ;
fprintf ( stderr , " Crash happened, prepare upload the minidump file: %s \n " , descriptor . path ( ) ) ;
ret = access ( instance - > minidump_filename , F_OK | R_OK ) ;
if ( ret < 0 )
{
fprintf ( stderr , " minidump file is not existed, cannot upload minidump file " ) ;
return succeeded ;
}
/* Firstly, fork an child process */
pid_t exec_child_pid = fork ( ) ;
if ( exec_child_pid = = 0 )
{
/* As a child, exec minidump upload tools */
ret = execv ( instance - > upload_tools_filename , instance - > upload_tools_exec_argv ) ;
if ( ret < 0 )
{
fprintf ( stderr , " Failed at exec the upload program %s: %s \n " ,
instance - > upload_tools_filename , strerror ( errno ) ) ;
/* after log, reset errno */
errno = 0 ;
}
exit ( EXIT_FAILURE ) ;
}
else if ( exec_child_pid > 0 )
{
fprintf ( stderr , " Starting upload minidump, PID = %d. \n " , exec_child_pid ) ;
return succeeded ;
}
else
{
/* failed at fork, cannot upload the minidump */
fprintf ( stderr , " Failed at fork(), cannot upload minidump file. : %s \n " , strerror ( errno ) ) ;
/* after log, reset errno */
errno = 0 ;
return succeeded ;
}
}
struct breakpad_instance * breakpad_init ( const char * profile )
{
struct breakpad_instance * instance = ALLOC ( struct breakpad_instance , 1 ) ;
assert ( instance ! = nullptr ) ;
int ret = 0 ;
unsigned int disable_coredump ;
MESA_load_profile_uint_def ( profile , " system " , " disable_coredump " , & disable_coredump , 0 ) ;
if ( disable_coredump > 0 )
{
const struct rlimit __rlimit_vars = { . rlim_cur = 0 , . rlim_max = 0 } ;
ret = setrlimit ( RLIMIT_CORE , & __rlimit_vars ) ;
if ( ret < 0 )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " setrlimit(RLIMIT_CORE, 0) failed: %s " , strerror ( errno ) ) ;
2020-09-25 14:56:36 +08:00
/* after log, reset errno */
errno = 0 ;
}
}
MESA_load_profile_uint_def ( profile , " system " , " enable_breakpad " , & instance - > en_breakpad , 1 ) ;
if ( instance - > en_breakpad < = 0 )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Breakpad Crash Reporting System is disabled. " ) ;
2020-09-25 14:56:36 +08:00
return instance ;
}
MESA_load_profile_string_def ( profile , " system " , " breakpad_minidump_dir " ,
instance - > minidump_dir_prefix , sizeof ( instance - > minidump_dir_prefix ) , " /tmp/crashreport " ) ;
MESA_load_profile_uint_def ( profile , " system " , " enable_breakpad_upload " ,
& instance - > en_breakpad_upload , 0 ) ;
/* Create the minidump dir if it is not existed */
_mkdir ( instance - > minidump_dir_prefix ) ;
if ( instance - > en_breakpad_upload )
{
/* Try to init the breakpad upload */
ret = breakpad_init_minidump_upload ( instance , profile ) ;
if ( ret < 0 )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Breakpad upload init failed, using local breakpad dumpfile " ) ;
2020-09-25 14:56:36 +08:00
instance - > en_breakpad_upload = 0 ;
}
/* When we use breakpad, do not generate any coredump file */
const struct rlimit __rlimit_vars = { . rlim_cur = 0 , . rlim_max = 0 } ;
ret = setrlimit ( RLIMIT_CORE , & __rlimit_vars ) ;
if ( ret < 0 )
{
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " setrlimit(RLIMIT_CORE, 0) failed: %s " , strerror ( errno ) ) ;
2020-09-25 14:56:36 +08:00
/* after log, reset errno */
errno = 0 ;
}
}
if ( instance - > en_breakpad_upload )
{
instance - > exceptionHandler = new google_breakpad : : ExceptionHandler (
google_breakpad : : MinidumpDescriptor ( instance - > minidump_dir_prefix ) , NULL ,
tfe_breakpad_dump_and_report , NULL , true , - 1 ) ;
}
else
{
instance - > exceptionHandler = new google_breakpad : : ExceptionHandler (
google_breakpad : : MinidumpDescriptor ( instance - > minidump_dir_prefix ) , NULL ,
tfe_breakpad_dump_to_file , NULL , true , - 1 ) ;
}
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Breakpad Crash Report is enable. " ) ;
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Minidump Dir: %s " , instance - > minidump_dir_prefix ) ;
2020-09-25 14:56:36 +08:00
return instance ;
}
2020-09-28 16:59:41 +08:00
void __signal_handler_cb ( int sig )
{
switch ( sig )
{
case SIGHUP :
2024-07-02 10:16:29 +08:00
log_info ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Reload log config " ) ;
2024-01-31 15:25:30 +08:00
verify_reload_loglevel ( ) ;
2020-09-28 16:59:41 +08:00
break ;
case SIGPIPE :
break ;
case SIGUSR1 :
case SIGINT :
break ;
default :
break ;
}
}
2019-10-22 15:13:14 +08:00
int main ( int argc , char * argv [ ] )
{
const char * main_profile = " ./conf/verify_policy.conf " ;
2020-06-24 16:36:16 +08:00
struct timespec start_time , end_time ;
2019-10-22 15:13:14 +08:00
2024-07-02 10:16:29 +08:00
int ret = 0 , opt = 0 , log_level = 0 ;
2019-10-22 15:13:14 +08:00
while ( ( opt = getopt ( argc , argv , " v " ) ) ! = - 1 )
{
switch ( opt )
{
case ' v ' :
2020-01-09 14:32:00 +08:00
fprintf ( stderr , " Welcome to Verify Policy Engine, Version: %s \n " , version ( ) ) ;
2019-10-22 15:13:14 +08:00
return 0 ;
default :
break ;
}
}
2020-02-18 17:54:15 +08:00
g_verify_proxy = ALLOC ( struct verify_policy , 1 ) ;
2019-10-22 15:13:14 +08:00
assert ( g_verify_proxy ) ;
strcpy ( g_verify_proxy - > name , " verify_policy " ) ;
2024-07-02 10:16:29 +08:00
const char * log_path = " ./logs/verify_policy.log " ;
MESA_load_profile_int_def ( main_profile , " SYSTEM " , " log_level " , & log_level , LOG_FATAL ) ;
g_verify_proxy - > logger = log_handle_create ( log_path , log_level ) ;
2019-10-22 15:13:14 +08:00
CHECK_OR_EXIT ( g_verify_proxy - > logger ! = NULL , " Failed at init log module. Exit. " ) ;
2023-03-30 19:50:00 +08:00
ret = load_system_conf ( g_verify_proxy , main_profile ) ;
2019-10-22 15:13:14 +08:00
CHECK_OR_EXIT ( ret = = 0 , " Failed at loading profile %s, Exit. " , main_profile ) ;
2020-01-09 14:32:00 +08:00
2020-06-24 16:36:16 +08:00
clock_gettime ( CLOCK_REALTIME , & ( start_time ) ) ;
2023-05-09 14:26:43 +08:00
ret = maat_table_init ( g_verify_proxy , main_profile ) ;
CHECK_OR_EXIT ( ret = = 0 , " Failed at init maat module, Exit. " ) ;
2020-06-24 16:36:16 +08:00
clock_gettime ( CLOCK_REALTIME , & ( end_time ) ) ;
2024-07-02 10:16:29 +08:00
log_fatal ( g_verify_proxy - > logger , MODULE_VERIFY_POLICY , " Read table_info.conf, take time %lu(s) " , end_time . tv_sec - start_time . tv_sec ) ;
2023-05-09 14:26:43 +08:00
printf ( " Read table_info.conf, take time %lu(s) \n " , end_time . tv_sec - start_time . tv_sec ) ;
2020-01-17 10:59:34 +08:00
2020-09-25 14:56:36 +08:00
g_verify_proxy - > breakpad = breakpad_init ( main_profile ) ;
CHECK_OR_EXIT ( g_verify_proxy - > breakpad , " Failed at starting breakpad. Exit. " ) ;
2020-09-28 16:59:41 +08:00
for ( size_t i = 0 ; i < ( sizeof ( signals ) / sizeof ( int ) ) ; i + + )
{
signal ( signals [ i ] , __signal_handler_cb ) ;
}
2023-03-30 19:50:00 +08:00
ret = verify_policy_work_thread_run ( g_verify_proxy ) ;
FOREVER {
sleep ( 1 ) ;
}
2020-01-09 14:32:00 +08:00
2019-10-22 15:13:14 +08:00
return ret ;
}