Rebase dev 2.0

This commit is contained in:
杨威
2024-10-11 06:08:50 +00:00
parent 2e35a79528
commit 70d21f28c3
671 changed files with 1490 additions and 1770 deletions

View File

@@ -81,7 +81,7 @@ add_subdirectory(conf)
add_subdirectory(vendors) add_subdirectory(vendors)
add_subdirectory(deps) add_subdirectory(deps)
add_subdirectory(infra) add_subdirectory(infra)
#add_subdirectory(decoders) add_subdirectory(decoders)
add_subdirectory(scripts) add_subdirectory(scripts)
add_subdirectory(include) add_subdirectory(include)
add_subdirectory(test) add_subdirectory(test)

View File

@@ -10,6 +10,23 @@
cpu_mask = [5, 6, 7, 8, 9, 10, 11, 12] cpu_mask = [5, 6, 7, 8, 9, 10, 11, 12]
idle_yield_interval_ms = 900 # range: [0, 60000] (ms) idle_yield_interval_ms = 900 # range: [0, 60000] (ms)
[[module]]
path=""
init="packet_manager_on_init"
exit="packet_manager_on_exit"
[[module]]
path = ""
init = "polling_manager_on_init"
exit = "polling_manager_on_exit"
[[module]]
path=""
init="session_manager_on_init"
exit="session_manager_on_exit"
[ip_reassembly] [ip_reassembly]
enable = 1 enable = 1
bucket_entries = 32 # range: [1, 4294967295] (must be power of 2) bucket_entries = 32 # range: [1, 4294967295] (must be power of 2)
@@ -68,17 +85,5 @@
file = "log/stellar.log" file = "log/stellar.log"
level = "INFO" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL level = "INFO" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL
[[module]]
path = ""
init = "polling_manager_on_init"
exit = "polling_manager_on_exit"
[[module]]
path = ""
init = "packet_manager_on_init"
exit = "packet_manager_on_exit"
[[module]]
path = ""
init = "session_manager_on_init"
exit = "session_manager_on_exit"

View File

@@ -1,5 +1,6 @@
add_subdirectory(http) add_subdirectory(appid)
add_subdirectory(lpi) add_subdirectory(lpi_plus)
add_subdirectory(socks) #add_subdirectory(http)
add_subdirectory(stratum) #add_subdirectory(socks)
add_subdirectory(session_flags) #add_subdirectory(stratum)
#add_subdirectory(session_flags)

View File

@@ -0,0 +1 @@
add_library(appid appid.c)

49
decoders/appid/appid.c Normal file
View File

@@ -0,0 +1,49 @@
#include "appid_internal.h"
#include "stellar/utils.h"
#include "stellar/mq.h"
static void appid_message_free(void *msg, void *msg_free_arg __unused)
{
if(msg==NULL)return;
FREE(msg);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type"
static void stellar_appid_on_msg_dispatch(int topic_id __unused,
void *msg,
on_msg_cb_func* on_msg_cb,
void *on_msg_cb_arg,
void *dispatch_arg __unused)
{
on_appid_callback *appid_cb = (on_appid_callback *)on_msg_cb;
struct appid_message *appid_msg=(struct appid_message *)msg;
appid_cb(appid_msg->sess, appid_msg->origin, appid_msg->appid, appid_msg->appid_num, on_msg_cb_arg);
}
int stellar_appid_subscribe(struct stellar_module_manager *mod_mgr, on_appid_callback *cb, void *args)
{
if(mod_mgr==NULL)return -1;
int appid_topic_id=mq_schema_get_topic_id(stellar_module_manager_get_mq_schema(mod_mgr), APPID_MESSAGE_TOPIC);
if(appid_topic_id<0)
{
appid_topic_id=mq_schema_create_topic(stellar_module_manager_get_mq_schema(mod_mgr), APPID_MESSAGE_TOPIC, stellar_appid_on_msg_dispatch, mod_mgr, appid_message_free, NULL);
}
return mq_schema_subscribe(stellar_module_manager_get_mq_schema(mod_mgr), appid_topic_id, (on_msg_cb_func *)cb, args);
}
#pragma GCC diagnostic pop
int stellar_appid_create_topic(struct stellar_module_manager *mod_mgr)
{
int app_topic_id=mq_schema_get_topic_id(stellar_module_manager_get_mq_schema(mod_mgr), APPID_MESSAGE_TOPIC);
if(app_topic_id < 0)
{
app_topic_id=mq_schema_create_topic(stellar_module_manager_get_mq_schema(mod_mgr), APPID_MESSAGE_TOPIC, stellar_appid_on_msg_dispatch, NULL,appid_message_free, NULL);
}
return app_topic_id;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include "stellar/appid.h"
#define MAX_APPID_NUM 8
#define APPID_MESSAGE_TOPIC "TOPIC_APPID"
struct appid_message
{
struct session *sess;
enum APPID_ORIGIN origin;
uint32_t appid_num;
int32_t appid[MAX_APPID_NUM];
uint32_t surrogate_id[MAX_APPID_NUM];
uint32_t packet_sequence[MAX_APPID_NUM];
};
#ifdef __cplusplus
}
#endif

View File

@@ -1,12 +0,0 @@
add_definitions(-fPIC)
add_subdirectory(libprotoident)
add_library(lpi lpi_plugin.cpp quic_ident.cpp openvpn_ident.cpp)
target_include_directories(lpi PUBLIC ${CMAKE_SOURCE_DIR}/deps/)
target_link_libraries(lpi libprotoident)
set_target_properties(lpi PROPERTIES LINK_FLAGS
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map")
#install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/stellar_plugin COMPONENT LIBRARIES)

View File

@@ -1,783 +0,0 @@
/*
* dpkt_basic_proto_main.cpp
*
* Created on: Aug 7, 2020
* Author: iie
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include "uthash/uthash.h"
#include "stellar/utils.h"
#include "stellar/session.h"
#include "stellar/stellar_exdata.h"
#include "stellar/stellar_mq.h"
#include "stellar/packet.h"
#include "stellar/appid.h"
#include "lpi_plugin.h"
const char *dns_name="DNS";
const char *imap_name="IMAP";
const char *quic_name="QUIC";
const char *g_app_proto_conffile="./tsgconf/main.conf";
const char *log_path = (char *)"./tsglog/lpi/";
struct lpi_plugin_env
{
int level;
int max_pkts;
int l7_label_id;
int l7_bridge_id;
int plugin_exdata_idx;
int l7_app_id_exdata_idx;
int topic_id;
int plugin_id;
struct stellar *st;
char log_path[128];
char l7_protocol_file[128];
struct l7_protocol_hash *name_by_id;
void *logger;
int tcp_topic_id;
int udp_topic_id;
};
struct l7_protocol_hash g_app_name2lpi_id[]={
{0, LPI_PROTO_UNKNOWN, "UNCATEGORIZED",{}},
//{0, LPI_PROTO_UNKNOWN, "Unknown_UDP"},
//{0, LPI_PROTO_UNSUPPORTED, "Unknown_Other"},
{0, LPI_PROTO_DNS, "DNS", {}},
{0, LPI_PROTO_FTP_CONTROL, "FTP", {}},
//{0, LPI_PROTO_FTP_DATA, "FTP", NULL, NULL},
{0, LPI_PROTP_FTPS, "FTPS", {}},
{0, LPI_PROTO_HTTP, "HTTP", {}},
{0, LPI_PROTO_HTTPS, "HTTPS", {}},
{0, LPI_PROTO_ICMP, "ICMP", {}},
{0, LPI_PROTO_IKE, "IKE", {}},
{0, LPI_PROTO_MAIL, "MAIL", {}},
{0, LPI_PROTO_IMAP, "IMAP", {}},
{0, LPI_PROTO_IMAPS, "IMAPS", {}},
{0, LPI_PROTO_UDP_ESP, "IPSEC", {}},
{0, LPI_PROTO_XMPP, "XMPP", {}},
{0, LPI_PROTO_UDP_L2TP, "L2TP", {}},
{0, LPI_PROTO_UDP_NTP, "NTP", {}},
{0, LPI_PROTO_POP3, "POP3", {}},
{0, LPI_PROTO_POP3S, "POP3S", {}},
{0, LPI_PROTO_PPTP, "PPTP", {}},
{0, LPI_PROTO_UDP_QUIC, "QUIC", {}},
{0, LPI_PROTO_SIP, "SIP", {}},
{0, LPI_PROTO_SMB, "SMB", {}},
{0, LPI_PROTO_SMTP, "SMTP", {}},
{0, LPI_PROTO_SMTPS, "SMTPS", {}},
{0, LPI_PROTO_SPDY, "SPDY", {}},
{0, LPI_PROTO_SSH, "SSH", {}},
{0, LPI_PROTO_SSL, "SSL", {}},
{0, LPI_PROTO_SOCKS4, "SOCKS", {}},
//{0, LPI_PROTO_SOCKS4, "SOCKS4", NULL, NULL},
//{0, LPI_PROTO_SOCKS5, "SOCKS5", NULL, NULL},
{0, LPI_PROTO_TELNET, "TELNET", {}},
{0, LPI_PROTO_UDP_DHCP, "DHCP", {}},
{0, LPI_PROTO_UDP_RADIUS, "RADIUS", {}},
{0, LPI_PROTO_OPENVPN, "OPENVPN", {}},
{0, LPI_PROTO_STUN, "STUN", {}},
{0, LPI_PROTO_UDP_TEREDO, "TEREDO", {}},
{0, LPI_PROTO_UDP_DTLS, "DTLS", {}},
{0, LPI_PROTO_DOH, "DoH", {}},
{0, LPI_PROTO_UDP_ISAKMP, "ISAKMP", {}},
{0, LPI_PROTO_UDP_MDNS, "MDNS", {}},
{0, LPI_PROTO_NETBIOS, "NETBIOS", {}},
{0, LPI_PROTO_UDP_NETFLOW, "NETFLOW", {}},
{0, LPI_PROTO_RDP, "RDP", {}},
{0, LPI_PROTO_UDP_RTCP, "RTCP", {}},
{0, LPI_PROTO_UDP_RTP, "RTP", {}},
{0, LPI_PROTO_UDP_SLP, "SLP", {}},
{0, LPI_PROTO_UDP_SNMP, "SNMP", {}},
{0, LPI_PROTO_UDP_SSDP, "SSDP", {}},
{0, LPI_PROTO_UDP_TFTP, "TFTP", {}},
{0, LPI_PROTO_UDP_BJNP, "BJNP", {}},
{0, LPI_PROTO_LDAP, "LDAP", {}},
{0, LPI_PROTO_RTMP, "RTMP", {}},
{0, LPI_PROTO_RTSP, "RTSP", {}},
{0, LPI_PROTO_ESNI, "ESNI", {}},
{0, LPI_PROTO_STRATUM, "Stratum", {}},
{0, LPI_PROTO_QQ, "QQ", {}},
{0, LPI_PROTO_WECHAT, "WeChat", {}},
{0, LPI_PROTO_MMS, "MMS", {}},
{0, LPI_PROTO_RSYNC, "RSYNC", {}},
{0, LPI_PROTO_UDP_WIREGUARD, "WIREGUARD", {}},
};
struct dns_header
{
u_int16_t id;
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_char rd:1;
u_char tc:1;
u_char aa:1;
u_char opcode:4;
u_char qr:1;
u_char rcode:4;
u_char z:3;
u_char ra:1;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_char qr:1;
u_char opcode:4;
u_char aa:1;
u_char tc:1;
u_char rd:1;
u_char ra:1;
u_char z:3;
u_char rcode:4;
#endif
u_int16_t qdcount;
u_int16_t ancount;
u_int16_t aucount;//authority count
u_int16_t adcount;//additional count
};
static void get_host_order_port(struct session *sess __unused, unsigned short *sport, unsigned short *dport)
{
*sport=0;
*dport=0;
//get host order port from stellar session api
const struct packet *pkt = session_get0_current_packet(sess);
enum flow_type flow_type=session_get_flow_type(sess);
if(pkt && (flow_type==FLOW_TYPE_C2S || flow_type==FLOW_TYPE_S2C))
{
int layer_cnt=packet_get_layer_count(pkt);
const struct layer *layer = packet_get_layer_by_idx(pkt, layer_cnt - 1);
if (layer && layer->proto == LAYER_PROTO_TCP)
{
*sport = ntohs(layer->hdr.tcp->th_sport);
*dport = ntohs(layer->hdr.tcp->th_dport);
}
if (layer && layer->proto == LAYER_PROTO_UDP)
{
*sport = ntohs(layer->hdr.udp->uh_sport);
*dport = ntohs(layer->hdr.udp->uh_dport);
}
//S2C, swap sport and dport
if(flow_type == FLOW_TYPE_S2C)
{
unsigned short tmp = *sport;
*sport = *dport;
*dport = tmp;
}
}
return;
}
static int revise_lpi_result(struct session *sess, const char *scan_data, const int scan_data_len, lpi_module_t* proto, struct traffic_context *context, int l4_is_tcp, int curdir_is_c2s)
{
unsigned short sport=0, dport=0;
get_host_order_port(sess, &sport, &dport);
if(sport == 989 || sport == 990 || dport == 989 || dport == 990)
{
if(proto->protocol == LPI_PROTO_SSL)
{
proto->protocol=(lpi_protocol_t)LPI_PROTP_FTPS;
proto->category=LPI_CATEGORY_FILES;
proto->priority=3;
proto->name="FTPS";
proto->lpi_callback=NULL;
return 1;
}
}
if(sport==443 || dport==443 || sport==80 || dport==80 || sport==8443 || dport==8443)
{
if(app_identify_get_quic_protocol(curdir_is_c2s, (const unsigned char *)scan_data, scan_data_len) != QUIC_VERSION_UNKNOWN)
{
//lpi_quic
proto->protocol=LPI_PROTO_UDP_QUIC;
proto->category=LPI_CATEGORY_WEB;
proto->priority=9;
proto->name=quic_name;
proto->lpi_callback=NULL;
return 1;
}
}
if((sport==53 || dport==53) && (scan_data_len>12))
{
struct dns_header *dns_hdr=NULL;
if(l4_is_tcp)
{
dns_hdr=(struct dns_header *)(scan_data+2);
}
else
{
dns_hdr=(struct dns_header *)scan_data;
}
if((dns_hdr->qr==1 && ntohs(dns_hdr->qdcount)==1) ||
(dns_hdr->qr==0 && ntohs(dns_hdr->qdcount)==1 && ntohs(dns_hdr->aucount)==0 && ntohs(dns_hdr->ancount)==0))
{
proto->protocol=LPI_PROTO_DNS;
proto->category=LPI_CATEGORY_SERVICES;
proto->priority=10;
proto->name=dns_name;
proto->lpi_callback=NULL;
return 1;
}
}
if(((sport==143 || dport==143)) &&
(
(scan_data_len>=11 && memmem(scan_data, scan_data_len, " CAPABILITY", 11)!=NULL) ||
(scan_data_len>=7 && memmem(scan_data, scan_data_len, " LOGIN ", 7)!=NULL)
)
)
{
proto->protocol=LPI_PROTO_IMAP;
proto->category=LPI_CATEGORY_MAIL;
proto->priority=2;
proto->name=imap_name;
proto->lpi_callback=NULL;
return 1;
}
int c2s_pkt_cnt=context->c2s_pkt;
int s2c_pkt_cnt=context->s2c_pkt;
if(app_identify_guess_openvpn((const unsigned char *)scan_data, scan_data_len, c2s_pkt_cnt, s2c_pkt_cnt, &context->ovpn, l4_is_tcp, curdir_is_c2s)==1)
{
proto->protocol=LPI_PROTO_OPENVPN;
proto->category=LPI_CATEGORY_TUNNELLING;
proto->priority=4;
proto->name="OpenVPN";
proto->lpi_callback=NULL;
return 1;
}
return 0;
}
static int set_lpi_same_name(struct l7_protocol_hash *l7_protocol_hash, struct l7_protocol_hash *l7_protocol_elem, int lpi_protocol_id)
{
struct l7_protocol_hash *tmp=(struct l7_protocol_hash *)calloc(1, sizeof(struct l7_protocol_hash));
memcpy(tmp, l7_protocol_elem, sizeof(struct l7_protocol_hash));
tmp->lpi_protocol=lpi_protocol_id;
HASH_ADD(hh, l7_protocol_hash, lpi_protocol, sizeof(int), tmp);
return 0;
}
static int get_protocol_id(struct l7_protocol_hash *name_by_id, const lpi_module_t* proto)
{
struct l7_protocol_hash *out=NULL;
HASH_FIND(hh, name_by_id, &(proto->protocol), sizeof(int), out);
if(out!=NULL)
{
return out->protocol_id;
}
return -1;
}
static struct app_id_message *app_id_messgae_create(unsigned short *id_array, int id_num)
{
struct app_id_message *result=CALLOC(struct app_id_message, 1);
result->origin=ORIGIN_PROTO_IDENTIFY;
result->magic=MESSAGE_MAGIC;
result->app_id_num=id_num;
for(unsigned int i=0; i<result->app_id_num; i++)
{
result->app_id[i]=(int)(id_array[i]);
result->surrogate_id[i]=0;
}
return result;
}
static int update_protocol_id(unsigned short *old_id_array, int *old_id_num, unsigned short new_id)
{
int i=0;
if(*old_id_num>=MAX_APP_ID_NUM)
{
return 0;
}
for(i=0; i<(*old_id_num); i++)
{
if(new_id==old_id_array[i])
{
return 0;
}
}
old_id_array[(*old_id_num)]=new_id;
(*old_id_num)++;
return 1;
}
static int l7_protocol_mapper(struct lpi_plugin_env *g_app_proto_para, const char *filename)
{
size_t i=0,ret=0;
FILE *fp=NULL;
char line[1024]={0};
char type_name[32]={0};
struct l7_protocol_hash *name2lpi=NULL;
struct l7_protocol_hash *l7_protocol=NULL;
struct l7_protocol_hash *out=NULL;
fp=fopen(filename, "r");
if(fp==NULL)
{
printf("Open %s failed ...", filename);
return -1;
}
for(i=0; i<(sizeof(g_app_name2lpi_id)/sizeof(struct l7_protocol_hash)); i++)
{
HASH_ADD(hh, name2lpi, name, strlen(g_app_name2lpi_id[i].name), &(g_app_name2lpi_id[i]));
}
memset(line, 0, sizeof(line));
while((fgets(line, sizeof(line), fp))!=NULL)
{
if(line[0]=='#' || line[0]=='\n' || line[0]=='\r' ||line[0]=='\0')
{
continue;
}
l7_protocol=(struct l7_protocol_hash *)calloc(1, sizeof(struct l7_protocol_hash));
ret=sscanf(line, "%31s %63s %d", type_name, l7_protocol->name, &l7_protocol->protocol_id);
assert(ret==3);
HASH_FIND(hh, name2lpi, l7_protocol->name, strlen(l7_protocol->name), out);
if(out==NULL)
{
//MESA_handle_runtime_log(g_app_proto_para->logger, RLOG_LV_FATAL, "INIT_HASH", "Protocol %s identified without registered LPI ID", l7_protocol->name);
free(l7_protocol);
continue;
}
l7_protocol->lpi_protocol=out->lpi_protocol;
HASH_ADD(hh, g_app_proto_para->name_by_id, lpi_protocol, sizeof(int), l7_protocol);
switch(out->lpi_protocol)
{
case LPI_PROTO_DNS:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_DNS);
break;
case LPI_PROTO_SIP:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_SIP);
break;
case LPI_PROTO_SOCKS4:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_SOCKS5);
break;
case LPI_PROTO_FTP_CONTROL:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_FTP_DATA);
break;
case LPI_PROTO_OPENVPN:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_OPENVPN);
break;
case LPI_PROTO_LDAP:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_TCP_LDAP_AD);
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_LDAP_AD);
break;
case LPI_PROTO_HTTP:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_HTTP_BADPORT);
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_HTTP_TUNNEL);
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_NONSTANDARD_HTTP);
break;
case LPI_PROTO_STUN:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_STUN);
break;
case LPI_PROTO_NETBIOS:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_NETBIOS);
break;
case LPI_PROTO_QQ:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_QQ);
break;
case LPI_PROTO_WECHAT:
set_lpi_same_name(g_app_proto_para->name_by_id, l7_protocol, LPI_PROTO_UDP_WECHAT);
break;
default:
break;
}
memset(line, 0, sizeof(line));
}
fclose(fp);
fp=NULL;
HASH_CLEAR(hh, name2lpi);
#if 0
HASH_ITER(hh, g_app_proto_para->name_by_id, out ,tmp)
{
MESA_handle_runtime_log(g_app_proto_para->logger,
RLOG_LV_DEBUG,
"ID_MAPPER",
"%s lpi_protocol built-in ID is %d and TSG ID is %d",
out->name,
out->lpi_protocol,
out->protocol_id
);
}
#endif
return ret;
}
static void free_l7_protocol_mapper(struct l7_protocol_hash *hash)
{
if(hash==NULL)
{
return ;
}
struct l7_protocol_hash *out=NULL, *tmp=NULL;
HASH_ITER(hh, hash, out ,tmp)
{
if(out!=NULL)
{
HASH_DEL(hash, out);
free(out);
out=NULL;
}
}
}
int lpi_update_dpkt(lpi_data_t *data, struct session *sess,
const char *scan_data, int scan_data_len, char tsproto,
uint32_t is_c2s)
{
uint32_t dir = 0;
if(is_c2s == 1)
{
dir = 0;
}
else
{
dir = 1;
}
uint32_t four_bytes;
if (data->observed[dir] > 32 * 1024)
return 0;
data->observed[dir] += scan_data_len;
if (data->trans_proto == 0)data->trans_proto = tsproto;
if (scan_data == NULL)return 0;
if (scan_data_len <= 0)return 0;
if (scan_data_len < 4)
{
memcpy((char *)&four_bytes, scan_data, scan_data_len);
four_bytes = (ntohl(four_bytes)) >> (8 * (4 - scan_data_len));
four_bytes = htonl(four_bytes << (8 * (4 - scan_data_len)));
}
else
{
four_bytes = (*(uint32_t *)scan_data);
}
data->payload[dir] = four_bytes;
data->payload_len[dir] = scan_data_len;
uint16_t source=0;
uint16_t dest=0;
get_host_order_port(sess,&source ,&dest);
data->client_port = source;
data->server_port = dest;
// DONE: no need to set saddr and daddr
/*
if (pstream != NULL && data->ips[0] == 0
&& (pstream->addr.addrtype == __ADDR_TYPE_IP_PAIR_V4
|| pstream->addr.addrtype == ADDR_TYPE_IPV4))
{
if (dir == 1)
{
data->ips[0] = pstream->addr.ipv4->saddr;
data->ips[1] = pstream->addr.ipv4->daddr;
}
else
{
data->ips[1] = pstream->addr.ipv4->saddr;
data->ips[0] = pstream->addr.ipv4->daddr;
}
}
*/
return 1;
}
static int lpi_detector(struct session *sess, struct traffic_context *context, struct lpi_plugin_env *g_app_proto_para, const char *scan_data, const int scan_data_len, int l4_proto)
{
int ret=0,is_update=0;
//unsigned short sport=0, dport=0;
lpi_module_t modify_lpi_result={(lpi_protocol_t)0, (lpi_category_t)0, NULL, 0, NULL};
unsigned short new_protocol_id=0;
struct l7_protocol_label *l7_protocol=NULL;
//const struct packet *raw_packet=session_get0_current_packet(sess);
//int cur_pkt_dir= packet_get_direction(raw_packet);
int cur_pkt_dir=session_get_flow_type(sess);
context->pkt_cnt++;
(cur_pkt_dir==FLOW_TYPE_C2S) ? (context->c2s_pkt++) : (context->s2c_pkt++);
int is_c2s_pkt=((cur_pkt_dir==FLOW_TYPE_C2S) ? 1 : 0);
ret=lpi_update_dpkt(&(context->lpi_data), sess, scan_data, scan_data_len, l4_proto, is_c2s_pkt);
if(!ret)
{
return 1;
}
lpi_module_t *plpi_mod=lpi_guess_protocol(&(context->lpi_data));
if(plpi_mod==NULL)
{
return 1;
}
if((plpi_mod->protocol==LPI_PROTO_UNKNOWN || plpi_mod->protocol==LPI_PROTO_UDP) &&
(context->pkt_cnt<g_app_proto_para->max_pkts || context->is_identify==1))
{
ret=revise_lpi_result(sess, scan_data, scan_data_len, &modify_lpi_result, context,
(l4_proto==6?1:0),
(cur_pkt_dir==FLOW_TYPE_C2S?1:0));
if(ret==0)
{
return 1;
}
plpi_mod=&modify_lpi_result;
}
if (plpi_mod->protocol == LPI_PROTO_FTP_CONTROL && context->is_first_payload == 1 && cur_pkt_dir == FLOW_TYPE_S2C)
{
if ((((scan_data_len >= 4 && (memcmp(scan_data, "220-", 4) == 0)) || memcmp(scan_data, "220 ", 4) == 0)) &&
(((scan_data_len >= 7 && (memmem(scan_data, scan_data_len, " ESMTP ", 7) != NULL)) ||
memmem(scan_data, scan_data_len, " esmtp ", 7) != NULL)))
{
// lpi_smtp
modify_lpi_result.protocol = LPI_PROTO_SMTP;
modify_lpi_result.category = LPI_CATEGORY_MAIL;
modify_lpi_result.priority = 2;
modify_lpi_result.name = "SMTP";
plpi_mod = &modify_lpi_result;
}
}
if (plpi_mod->protocol == LPI_PROTO_SMTP && context->is_first_payload == 1 && cur_pkt_dir == FLOW_TYPE_S2C)
{
if (
(scan_data_len >= 4) &&
(memcmp(scan_data, "220 ", 4) == 0 || memcmp(scan_data, "220-", 4) == 0) &&
(memmem(scan_data, scan_data_len, "FTPd", 4) != NULL ||
memmem(scan_data, scan_data_len, "ftpd", 4) != NULL ||
memmem(scan_data, scan_data_len, "FTPD", 4) != NULL))
{
// lpi_ftpcontrol
modify_lpi_result.protocol = LPI_PROTO_FTP_CONTROL;
modify_lpi_result.category = LPI_CATEGORY_FILES;
modify_lpi_result.priority = 3;
modify_lpi_result.name = "FTP_Control";
plpi_mod = &modify_lpi_result;
}
}
new_protocol_id=get_protocol_id(g_app_proto_para->name_by_id, plpi_mod);
#if 0
if(new_protocol_id==(unsigned short)-1)
{
if(plpi_mod->protocol!=LPI_PROTO_UNKNOWN && plpi_mod->protocol!=LPI_PROTO_UDP && plpi_mod->protocol!=LPI_PROTO_UNSUPPORTED)
{
MESA_handle_runtime_log(g_app_proto_para->logger,
RLOG_LV_INFO,
"UNDEFINE",
"Protocol Name: %s identified without registered LPI ID=%d, category: %s priority: %d addr: %s",
plpi_mod->name,
plpi_mod->protocol,
lpi_print_category(plpi_mod->category),
plpi_mod->priority,
session_get0_readable_addr(sess)
);
}
return 1;
}
else
{
MESA_handle_runtime_log(g_app_proto_para->logger,
RLOG_LV_INFO,
"DEFINE",
"Protocol Name: %s identified registered LPI ID(%d), category: %s priority: %d addr: %s",
plpi_mod->name,
plpi_mod->protocol,
lpi_print_category(plpi_mod->category),
plpi_mod->priority,
session_get0_readable_addr(sess)
);
}
#endif
l7_protocol = (struct l7_protocol_label *)session_exdata_get(sess, g_app_proto_para->l7_app_id_exdata_idx);
if(l7_protocol==NULL)
{
l7_protocol=CALLOC(struct l7_protocol_label, 1);
l7_protocol->continue_scan_flag = 1;
session_exdata_set(sess, g_app_proto_para->l7_app_id_exdata_idx, l7_protocol);
}
is_update=update_protocol_id(l7_protocol->protocol_id, &(l7_protocol->protocol_id_num), new_protocol_id);
if(is_update==1)
{
context->is_identify=1;
struct app_id_message *msg=app_id_messgae_create(l7_protocol->protocol_id, l7_protocol->protocol_id_num);
if(session_mq_publish_message(sess, g_app_proto_para->topic_id, msg) < 0)
{
FREE(msg);
}
//MESA_handle_runtime_log(g_app_proto_para->logger, RLOG_LV_DEBUG, "ADD_PROJECT", "%s identified, ID %d addr: %s", plpi_mod->name, new_protocol_id, session_get0_readable_addr(sess));
}
if (context->pkt_cnt >= g_app_proto_para->max_pkts || (plpi_mod->category != LPI_CATEGORY_TUNNELLING && plpi_mod->category != LPI_CATEGORY_NAT && plpi_mod->protocol != LPI_PROTO_RDP && plpi_mod->protocol != LPI_PROTO_UDP_RDP && plpi_mod->protocol != LPI_PROTO_UDP_RTP && plpi_mod->protocol != LPI_PROTO_UDP_RTCP))
{
l7_protocol->continue_scan_flag=0;
return 0;
}
return 1;
}
static void lpi_plugin_on_session_msg(struct session *sess, int topic_id __unused, const void *msg, void *per_session_ctx __unused, void *plugin_env)
{
assert(plugin_env!=NULL);
if(msg==NULL)return;
struct lpi_plugin_env *env=(struct lpi_plugin_env *)plugin_env;
int identify_continue=0;
struct traffic_context *context = (struct traffic_context *)session_exdata_get(sess, env->plugin_exdata_idx);
if(context==NULL)
{
context= CALLOC(struct traffic_context, 1);
context->is_first_payload=1;
session_exdata_set(sess, env->plugin_exdata_idx, context);
}
//size_t payload_len=0;
//const char *payload=session_get0_current_payload(sess, &payload_len);
uint16_t payload_len=packet_get_payload_len((struct packet*)msg);
const char *payload=packet_get_payload((struct packet*)msg);
if (payload!=NULL && payload_len>0 && context->pkt_cnt<env->max_pkts)
{
int l4_proto=0;
enum session_type type= session_get_type(sess);
if(type == SESSION_TYPE_TCP)
{
l4_proto=6;
}
if(type == SESSION_TYPE_UDP)
{
l4_proto=17;
}
identify_continue=lpi_detector(sess, context, env, payload, payload_len, l4_proto);
context->is_first_payload=0;
}
else
{
identify_continue=1;
}
if (identify_continue==0)
{
FREE(context);
session_exdata_set(sess, env->plugin_exdata_idx, NULL);
stellar_session_plugin_dettach_current_session(sess);
}
return;
}
extern "C" void lpi_plugin_unload(void *plugin_env)
{
if(plugin_env)
{
struct lpi_plugin_env *env=(struct lpi_plugin_env *)plugin_env;
lpi_free_library();
free_l7_protocol_mapper(env->name_by_id);
FREE(plugin_env);
}
}
extern "C" void * lpi_plugin_load(struct stellar *st)
{
int ret=0;
struct lpi_plugin_env *env=CALLOC(struct lpi_plugin_env, 1);
env->st=st;
env->max_pkts=16;
strcpy( env->l7_protocol_file, "./tsgconf/tsg_l7_protocol.conf");
ret=lpi_init_library(1); // 1, 2 or 3
if(ret<0)
{
goto INIT_ERROR;
}
ret=l7_protocol_mapper(env,env->l7_protocol_file);
if(ret<0)
{
goto INIT_ERROR;
}
env->plugin_id=stellar_session_plugin_register(st, NULL, NULL, env);
if(env->plugin_id < 0)
{
goto INIT_ERROR;
}
env->tcp_topic_id=stellar_mq_get_topic_id(st, TOPIC_TCP_INPUT);
env->udp_topic_id=stellar_mq_get_topic_id(st, TOPIC_UDP_INPUT);
if(env->tcp_topic_id < 0 || env->udp_topic_id < 0)
{
perror("get tcp or udp topic id failed\n");
exit(-1);
}
stellar_session_mq_subscribe(st, env->tcp_topic_id, lpi_plugin_on_session_msg, env->plugin_id);
stellar_session_mq_subscribe(st, env->udp_topic_id, lpi_plugin_on_session_msg, env->plugin_id);
env->plugin_exdata_idx = stellar_exdata_new_index(st, "EXDATA_LPI", stellar_exdata_free_default, NULL);
env->l7_app_id_exdata_idx = stellar_exdata_new_index(st, "L7_PROTOCOL", stellar_exdata_free_default, NULL);
env->topic_id=stellar_mq_get_topic_id(st, APP_ID_MESSAGE_TOPIC);
if(env->topic_id < 0)
{
env->topic_id=stellar_mq_create_topic(st, APP_ID_MESSAGE_TOPIC, stellar_msg_free_default, NULL);
}
return env;
INIT_ERROR:
lpi_plugin_unload(env);
exit(-1);
return NULL;
}

View File

@@ -1,227 +0,0 @@
#pragma once
#include "libprotoident/libprotoident.h"
#include "uthash/uthash.h"
#define MAX_APP_ID_NUM 8
typedef enum {
LPI_PROTO_EXTEND_FRIST = LPI_PROTO_LAST,
LPI_PROTO_IKE, //unsupport
LPI_PROTO_DOH, //unsupport
LPI_PROTO_MAIL, //unsupport
LPI_PROTO_ESNI, //unsupport
LPI_PROTP_FTPS,
LPI_PROTO_EXTEND_LAST
} extend_lpi_protocol_t;
struct l7_protocol_label
{
int continue_scan_flag; //0: stop; 1: continue
int protocol_id_num;
unsigned short protocol_id[MAX_APP_ID_NUM];
};
struct l7_protocol_hash
{
int protocol_id;
int lpi_protocol;
char name[64];
UT_hash_handle hh;
};
struct ovpn_ctx
{
uint64_t local_session_id;
int contain_local_session_id_pkt_num;
int valid_opcode_cnt;
};
struct traffic_context
{
unsigned char is_identify;
unsigned char is_first_payload;
unsigned short pkt_cnt;
unsigned short s2c_pkt;
unsigned short c2s_pkt;
lpi_data_t lpi_data; // lpi API
union{
uint64_t ctx[2];
struct ovpn_ctx ovpn;
};
};
//https://github.com/quicwg/base-drafts/wiki/QUIC-Versions
enum _QUIC_VERSION
{
QUIC_VERSION_UNKNOWN=0,
//NetApp
QUANT_VERSION_00=0x45474700,
QUANT_VERSION_FF=0x454747FF,
//Private Octopus
PICOQUIC_VERSION_30=0x50435130,
//google
GQUIC_VERSION_Q001=0x51303031,
GQUIC_VERSION_Q002=0x51303032,
GQUIC_VERSION_Q003=0x51303033,
GQUIC_VERSION_Q004=0x51303034,
GQUIC_VERSION_Q005=0x51303035,
GQUIC_VERSION_Q006=0x51303036,
GQUIC_VERSION_Q007=0x51303037,
GQUIC_VERSION_Q008=0x51303038,
GQUIC_VERSION_Q009=0x51303039,
GQUIC_VERSION_Q010=0x51303130,
GQUIC_VERSION_Q011=0x51303131,
GQUIC_VERSION_Q012=0x51303132,
GQUIC_VERSION_Q013=0x51303133,
GQUIC_VERSION_Q014=0x51303134,
GQUIC_VERSION_Q015=0x51303135,
GQUIC_VERSION_Q016=0x51303136,
GQUIC_VERSION_Q017=0x51303137,
GQUIC_VERSION_Q018=0x51303138,
GQUIC_VERSION_Q019=0x51303139,
GQUIC_VERSION_Q020=0x51303230,
GQUIC_VERSION_Q021=0x51303231,
GQUIC_VERSION_Q022=0x51303232,
GQUIC_VERSION_Q023=0x51303233,
GQUIC_VERSION_Q024=0x51303234,
GQUIC_VERSION_Q025=0x51303235,
GQUIC_VERSION_Q026=0x51303236,
GQUIC_VERSION_Q027=0x51303237,
GQUIC_VERSION_Q028=0x51303238,
GQUIC_VERSION_Q029=0x51303239,
GQUIC_VERSION_Q030=0x51303330,
GQUIC_VERSION_Q031=0x51303331,
GQUIC_VERSION_Q032=0x51303332,
GQUIC_VERSION_Q033=0x51303333,
GQUIC_VERSION_Q034=0x51303334,
GQUIC_VERSION_Q035=0x51303335,
GQUIC_VERSION_Q036=0x51303336,
GQUIC_VERSION_Q037=0x51303337,
GQUIC_VERSION_Q038=0x51303338,
GQUIC_VERSION_Q039=0x51303339,
GQUIC_VERSION_Q040=0x51303430,
GQUIC_VERSION_Q041=0x51303431,
GQUIC_VERSION_Q042=0x51303432,
GQUIC_VERSION_Q043=0x51303433,
GQUIC_VERSION_Q044=0x51303434,
GQUIC_VERSION_Q045=0x51303435,
GQUIC_VERSION_Q046=0x51303436,
GQUIC_VERSION_Q047=0x51303437,
GQUIC_VERSION_Q048=0x51303438,
GQUIC_VERSION_Q049=0x51303439,
GQUIC_VERSION_Q050=0x51303530,
GQUIC_VERSION_Q051=0x51303531,
GQUIC_VERSION_Q052=0x51303532,
GQUIC_VERSION_Q053=0x51303533,
GQUIC_VERSION_Q054=0x51303534,
GQUIC_VERSION_Q055=0x51303535,
GQUIC_VERSION_Q056=0x51303536,
GQUIC_VERSION_Q057=0x51303537,
GQUIC_VERSION_Q058=0x51303538,
GQUIC_VERSION_Q059=0x51303539,
GQUIC_VERSION_Q099=0x51303939,
//Google QUIC with TLS 48 - 49 (T048 - T049)
GQUIC_VERSION_T048=0x54303438,
GQUIC_VERSION_T049=0x54303439,
//Google QUIC with TLS 50 - 59 (T050 - T059)
GQUIC_VERSION_T050=0x54303530,
GQUIC_VERSION_T051=0x54303531,
GQUIC_VERSION_T052=0x54303532,
GQUIC_VERSION_T053=0x54303533,
GQUIC_VERSION_T054=0x54303534,
GQUIC_VERSION_T055=0x54303535,
GQUIC_VERSION_T056=0x54303536,
GQUIC_VERSION_T057=0x54303537,
GQUIC_VERSION_T058=0x54303538,
GQUIC_VERSION_T059=0x54303539,
//Google QUIC with TLS 99 (T099)
GQUIC_VERSION_T099=0x54303939,
//Google Proxied QUIC
PQUIC_VERSION_PROX=0x50524f58,
//quic-go
QUIC_GO_VERSION_00=0x51474F00,
QUIC_GO_VERSION_FF=0x51474FFF,
//quicly
QUICLY_VERSION_00=0x91c17000,
QUICLY_VERSION_FF=0x91c170FF,
//Microsoft
MSQUIC_VERSION_00=0xabcd0000,
MSQUIC_VERSION_0F=0xabcd000F,
//Mozilla
MOZQUIC_VERSION_00=0xf123f0c0,
MOZQUIC_VERSION_0F=0xf123f0cF,
//Facebook
MVFST_VERSION_00=0xfaceb000,
MVFST_VERSION_01=0xfaceb001,
MVFST_VERSION_02=0xfaceb002,
MVFST_VERSION_03=0xfaceb003,
MVFST_VERSION_04=0xfaceb004,
MVFST_VERSION_05=0xfaceb005,
MVFST_VERSION_06=0xfaceb006,
MVFST_VERSION_07=0xfaceb007,
MVFST_VERSION_08=0xfaceb008,
MVFST_VERSION_09=0xfaceb009,
MVFST_VERSION_0A=0xfaceb00A,
MVFST_VERSION_0B=0xfaceb00B,
MVFST_VERSION_0C=0xfaceb00C,
MVFST_VERSION_0D=0xfaceb00D,
MVFST_VERSION_0E=0xfaceb00E,
MVFST_VERSION_0F=0xfaceb00F,
//IETF
IQUIC_VERSION_RFC9000=0x00000001,
IQUIC_VERSION_I001=0xFF000001,
IQUIC_VERSION_I002=0xFF000002,
IQUIC_VERSION_I003=0xFF000003,
IQUIC_VERSION_I004=0xFF000004,
IQUIC_VERSION_I005=0xFF000005,
IQUIC_VERSION_I006=0xFF000006,
IQUIC_VERSION_I007=0xFF000007,
IQUIC_VERSION_I008=0xFF000008,
IQUIC_VERSION_I009=0xFF000009,
IQUIC_VERSION_I010=0xFF00000A,
IQUIC_VERSION_I011=0xFF00000B,
IQUIC_VERSION_I012=0xFF00000C,
IQUIC_VERSION_I013=0xFF00000D,
IQUIC_VERSION_I014=0xFF00000E,
IQUIC_VERSION_I015=0xFF00000F,
IQUIC_VERSION_I016=0xFF000010,
IQUIC_VERSION_I017=0xFF000011,
IQUIC_VERSION_I018=0xFF000012,
IQUIC_VERSION_I019=0xFF000013,
IQUIC_VERSION_I020=0xFF000014,
IQUIC_VERSION_I021=0xFF000015,
IQUIC_VERSION_I022=0xFF000016,
IQUIC_VERSION_I023=0xFF000017,
IQUIC_VERSION_I024=0xFF000018,
IQUIC_VERSION_I025=0xFF000019,
IQUIC_VERSION_I026=0xFF00001A,
IQUIC_VERSION_I027=0xFF00001B,
IQUIC_VERSION_I028=0xFF00001C,
IQUIC_VERSION_I029=0xFF00001D,
IQUIC_VERSION_I030=0xFF00001E,
IQUIC_VERSION_I031=0xFF00001F,
IQUIC_VERSION_I032=0xFF000020
};
enum _QUIC_VERSION app_identify_get_quic_protocol(int curdir_is_c2s, const unsigned char *payload, const int payload_len);
int app_identify_guess_openvpn(const unsigned char *payload, int payload_len, int c2s_pkt_cnt, int s2c_pkt_cnt, struct ovpn_ctx *ovpn, int l4_is_tcp, int curdir_is_c2s);

View File

@@ -1,183 +0,0 @@
/*
* openvpn.c
*
* Copyright (C) 2011-22 - ntop.org
*
*
* nDPI is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* nDPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with nDPI. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include <arpa/inet.h>
#include "lpi_plugin.h"
/*
* OpenVPN TCP / UDP Detection - 128/160 hmac
*
* Detection based upon these openvpn protocol properties:
* - opcode
* - packet ID
* - session ID
*
* Two (good) packets are needed to perform detection.
* - First packet from client: save session ID
* - Second packet from server: report saved session ID
*
* TODO
* - Support PSK only mode (instead of TLS)
* - Support PSK + TLS mode (PSK used for early authentication)
* - TLS certificate extraction
*
*/
#define P_CONTROL_HARD_RESET_CLIENT_V1 (0x01 << 3)
#define P_CONTROL_HARD_RESET_CLIENT_V2 (0x07 << 3)
#define P_CONTROL_HARD_RESET_SERVER_V1 (0x02 << 3)
#define P_CONTROL_HARD_RESET_SERVER_V2 (0x08 << 3)
#define P_ACK_V1 (0x05 << 3)
#define P_CONTROL_V1 (0x04 << 3)
#define P_OPCODE_MASK 0xF8
#define P_SHA1_HMAC_SIZE 20
#define P_HMAC_128 16 // (RSA-)MD5, (RSA-)MD4, ..others
#define P_HMAC_160 20 // (RSA-|DSA-)SHA(1), ..others, SHA1 is openvpn default
#define P_HMAC_NONE 0
#define P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) (9 + hmac_size)
#define P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) (P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) + 8)
#define P_HARD_RESET_CLIENT_MAX_COUNT 5
static inline uint32_t get_packet_id(const uint8_t * payload, uint8_t hms) {
return(ntohl(*(uint32_t*)(payload + P_HARD_RESET_PACKET_ID_OFFSET(hms))));
}
static inline int8_t check_pkid_and_detect_hmac_size(const uint8_t * payload) {
// try to guess
if((int)get_packet_id(payload, P_HMAC_160) != 0)
return P_HMAC_160;
if((int)get_packet_id(payload, P_HMAC_128) != 0 )
return P_HMAC_128;
if((int)get_packet_id(payload, P_HMAC_NONE) != 0)
return P_HMAC_NONE;
return(-1);
}
int app_identify_guess_openvpn(const unsigned char *payload, int payload_len, int c2s_pkt_cnt, int s2c_pkt_cnt, struct ovpn_ctx *ovpn, int l4_is_tcp, int curdir_is_c2s)
{
const uint8_t * session_remote;
uint8_t opcode;
uint8_t alen;
int8_t hmac_size;
int8_t failed = 0;
if (c2s_pkt_cnt > 5)
{
if (ovpn->contain_local_session_id_pkt_num == P_HARD_RESET_CLIENT_MAX_COUNT - 1 && ovpn->valid_opcode_cnt == P_HARD_RESET_CLIENT_MAX_COUNT)
return 1;
return -1;
}
if (payload_len >= 40)
{
// skip openvpn TCP transport packet size
if (l4_is_tcp)
payload += 2, payload_len -= 2;
opcode = payload[0] & P_OPCODE_MASK;
if (curdir_is_c2s == 1 &&
(opcode == P_CONTROL_HARD_RESET_CLIENT_V1 ||
opcode == P_CONTROL_HARD_RESET_CLIENT_V2 ||
opcode == P_ACK_V1 ||
opcode == P_CONTROL_V1))
{
ovpn->valid_opcode_cnt++;
}
// for UDP, trying to identify by opcode and first packet length
if (l4_is_tcp == 0)
{
if ((c2s_pkt_cnt == 1 || s2c_pkt_cnt == 1) && (((payload_len == 112) && ((opcode == 168) || (opcode == 192))) || ((payload_len == 80) && ((opcode == 184) || (opcode == 88) || (opcode == 160) || (opcode == 168) || (opcode == 200)))))
{
return 1;
}
}
if(s2c_pkt_cnt >= 1 && curdir_is_c2s == 0)return 0;
if (curdir_is_c2s == 1 && c2s_pkt_cnt <= P_HARD_RESET_CLIENT_MAX_COUNT && (opcode == P_CONTROL_HARD_RESET_CLIENT_V1 || opcode == P_CONTROL_HARD_RESET_CLIENT_V2 || opcode == P_ACK_V1 || opcode == P_CONTROL_V1))
{
if (check_pkid_and_detect_hmac_size(payload) >= 0)
{
if (c2s_pkt_cnt > 1)
{
if (memcmp(&ovpn->local_session_id, payload + 1, 8) == 0)
{
ovpn->contain_local_session_id_pkt_num++;
}
}
memcpy(&ovpn->local_session_id, payload + 1, 8);
}
}
else if (c2s_pkt_cnt >= 1 && c2s_pkt_cnt <= P_HARD_RESET_CLIENT_MAX_COUNT &&
(opcode == P_CONTROL_HARD_RESET_SERVER_V1 || opcode == P_CONTROL_HARD_RESET_SERVER_V2))
{
hmac_size = check_pkid_and_detect_hmac_size(payload);
if (hmac_size >= 0)
{
u_int16_t offset = P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size);
alen = payload[offset];
if (alen > 0)
{
offset += 1 + alen * 4;
if ((offset + 8) <= payload_len)
{
session_remote = &payload[offset];
if (memcmp(&ovpn->local_session_id, session_remote, 8) == 0)
{
return 1;
}
else
{
failed = 1;
}
}
else
failed = 1;
}
else
failed = 1;
}
else
failed = 1;
}
else
failed = 1;
if (failed)
return -1;
}
return 0;
}

View File

@@ -1,237 +0,0 @@
#include <arpa/inet.h>
#include "lpi_plugin.h"
#define GQUIC_PUBLIC_FLAG_VERSION 0x01
#define GQUIC_PUBLIC_FLAG_RST 0x02
#define GQUIC_PUBLIC_FLAG_NONCE 0x04
#define GQUIC_PUBLIC_FLAG_CID 0x08
#define GQUIC_PUBLIC_FLAG_PKT_NUM 0x30
//GQIIC Frame type
#define GQUIC_SPECIAL_FRAME_FLAG 0xE0 // Special Frame Types
#define GQUIC_SPECIAL_FRAME_STREAM 0x80
#define GQUIC_SPECIAL_FRAME_ACK 0x40
#define GQUIC_SPECIAL_FRAME_CONGEST_FB 0x20
#define GQUIC_SPECIAL_FRAME_STREAM_FIN 0x40 // FIN
#define GQUIC_SPECIAL_FRAME_STREAM_DLEN 0x20 //stream length
#define GQUIC_SPECIAL_FRAME_STREAM_OFFSET 0x1C //offset header field
#define GQUIC_SPECIAL_FRAME_STREAM_ID 0x03 //offset header field
#define GQUIC_REGULAR_FRAME_PADDING 0x00
#define GQUIC_REGULAR_FRAME_RST_STREAM 0x01
#define GQUIC_REGULAR_FRAME_CONNECTION_CLOSE 0x02
#define GQUIC_REGULAR_FRAME_GOAWAY 0x03
#define GQUIC_REGULAR_FRAME_WINDOW_UPDATE 0x04
#define GQUIC_REGULAR_FRAME_BLOCKED 0x05
#define GQUIC_REGULAR_FRAME_STOP_WAITING 0x06
#define GQUIC_REGULAR_FRAME_PING 0x07
#define GQUIC_SPECIAL_FRAME_FLAG 0xE0 // Special Frame Types
#define GQUIC_SPECIAL_FRAME_STREAM 0x80
#define GQUIC_SPECIAL_FRAME_ACK 0x40
#define GQUIC_SPECIAL_FRAME_CONGEST_FB 0x20
#define GQUIC_SPECIAL_FRAME_STREAM_FIN 0x40 // FIN
#define GQUIC_SPECIAL_FRAME_STREAM_DLEN 0x20 //stream length
#define GQUIC_SPECIAL_FRAME_STREAM_OFFSET 0x1C //offset header field
#define GQUIC_SPECIAL_FRAME_STREAM_ID 0x03 //offset header field
#define GQUIC_REGULAR_FRAME_PADDING 0x00
#define GQUIC_REGULAR_FRAME_RST_STREAM 0x01
#define GQUIC_REGULAR_FRAME_CONNECTION_CLOSE 0x02
#define GQUIC_REGULAR_FRAME_GOAWAY 0x03
#define GQUIC_REGULAR_FRAME_WINDOW_UPDATE 0x04
#define GQUIC_REGULAR_FRAME_BLOCKED 0x05
#define GQUIC_REGULAR_FRAME_STOP_WAITING 0x06
#define GQUIC_REGULAR_FRAME_PING 0x07
//IQIIC Frame type (GQUIC_Q046 is iQUIC 17)
#define IQUIC_FRAME_PADDING 0x00
#define IQUIC_FRAME_PING 0x10
#define IQUIC_FRAME_ACK_HEX02 0x20
#define IQUIC_FRAME_ACK_HEX03 0x30
#define IQUIC_FRAME_RESET_STREAM 0x40
#define IQUIC_FRAME_STOP_SENDING 0x50
#define IQUIC_FRAME_CRYPTO 0x60
#define IQUIC_FRAME_NEW_TOKEN 0x70
#define IQUIC_FRAME_STREAM_HEX08 0x80
#define IQUIC_FRAME_STREAM_HEX09 0x90
#define IQUIC_FRAME_STREAM_HEX0A 0xA0
#define IQUIC_FRAME_STREAM_HEX0B 0xB0
#define IQUIC_FRAME_STREAM_HEX0C 0xC0
#define IQUIC_FRAME_STREAM_HEX0D 0xD0
#define IQUIC_FRAME_STREAM_HEX0E 0xE0
#define IQUIC_FRAME_STREAM_HEX0F 0xF0
#define IQUIC_FRAME_MAX_DATA 0x01
#define IQUIC_FRAME_MAX_STREAM_DATA 0x11
#define IQUIC_FRAME_MAX_STREAMS_HEX12 0x21
#define IQUIC_FRAME_MAX_STREAMS_HEX13 0x31
#define IQUIC_FRAME_DATA_BLOCKED 0x41
#define IQUIC_FRAME_STREAM_DATA_BLOCKED 0x51
#define IQUIC_FRAME_STREAMS_BLOCKED_HEX16 0x61
#define IQUIC_FRAME_STREAMS_BLOCKED_HEX17 0x71
#define IQUIC_FRAME_NEW_CONNECTION_ID 0x81
#define IQUIC_FRAME_RETIRE_CONNECTION_ID 0x91
#define IQUIC_FRAME_PATH_CHALLENGE 0xA1
#define IQUIC_FRAME_PATH_RESPONSE 0xB1
#define IQUIC_FRAME_CONNECTION_CLOSE_HEX1C 0xC1
#define IQUIC_FRAME_CONNECTION_CLOSE_HEX1D 0xD1
/**************************************************************************/
/* Message tag */
/**************************************************************************/
#define CHLO 0x43484C4F
#define SHLO 0x53484C4F
#define REJ 0x52454A00
#define PRST 0x50525354
/**************************************************************************/
/* Tag */
/**************************************************************************/
#define TAG_PAD 0x50414400
#define TAG_SNI 0x534E4900
#define TAG_VER 0x56455200
#define TAG_CCS 0x43435300
#define TAG_UAID 0x55414944
#define TAG_PDMD 0x50444d44
#define TAG_STK 0x53544b00
#define TAG_SNO 0x534E4F00
#define TAG_PROF 0x50524F46
#define TAG_SCFG 0x53434647
#define TAG_RREJ 0x5252454A
#define TAG_CRT 0x435254FF
#define TAG_AEAD 0x41454144
#define TAG_SCID 0x53434944
#define TAG_PUBS 0x50554253
#define TAG_KEXS 0x4B455853
#define TAG_OBIT 0x4F424954
#define TAG_EXPY 0x45585059
#define TAG_NONC 0x4E4F4E43
#define TAG_MSPC 0x4D535043
#define TAG_TCID 0x54434944
#define TAG_SRBF 0x53524246
#define TAG_ICSL 0x4943534C
#define TAG_SCLS 0x53434C53
#define TAG_COPT 0x434F5054
#define TAG_CCRT 0x43435254
#define TAG_IRTT 0x49525454
#define TAG_CFCW 0x43464357
#define TAG_SFCW 0x53464357
#define TAG_CETV 0x43455456
#define TAG_XLCT 0x584C4354
#define TAG_NONP 0x4E4F4E50
#define TAG_CSCT 0x43534354
#define TAG_CTIM 0x4354494D
#define TAG_MIDS 0x4D494453
#define TAG_FHOL 0x46484F4C
#define TAG_STTL 0x5354544C
#define TAG_SMHL 0x534D484C
#define TAG_TBKP 0x54424B50
/* Public Reset Tag */
#define TAG_RNON 0x524E4F4E
#define TAG_RSEQ 0x52534551
#define TAG_CADR 0x43414452
#define EXTENSION_SERVER_NAME 0x0000
#define EXTENSION_SUPPORT_GROUP 0x000A
#define EXTENSION_APP_PROT_NEGO 0x0010 //application layer protocol negotiation
#define EXTENSION_SIG_ALGORITHM 0x000D
#define EXTENSION_KEY_SHARE 0x0033
#define EXTENSION_PSK_EXCHANGE 0x002D
#define EXTENSION_SUPP_SSL_VER 0x002B
#define EXTENSION_QUIC_PARAM 0xFFA5
#define EXTENSION_COMPRESS_CERT 0x001B
#define EXT_QUIC_PARAM_MAX_IDLE_TIMEOUT 0x01
#define EXT_QUIC_PARAM_MAX_UDP_PAYLOAD 0x03
#define EXT_QUIC_PARAM_MAX_INIT_DATA 0x04
#define EXT_QUIC_PARAM_MAX_STREAM_BIDI_LOCAL 0x05
#define EXT_QUIC_PARAM_MAX_STREAM_BIDI_REMOTE 0x06
#define EXT_QUIC_PARAM_MAX_STREAM_UNI 0x07
#define EXT_QUIC_PARAM_MAX_STREAMS_BIDI 0x08
#define EXT_QUIC_PARAM_MAX_STREAMS_UNI 0x09
#define EXT_QUIC_PARAM_MAX_FRAME_SIZE 0x20
#define EXT_QUIC_PARAM_INIT_SRC_CONN_ID 0x0F
#define EXT_QUIC_PARAM_USER_AGENT 0x7129
#define EXT_QUIC_PARAM_NOT_YET_SUPPORTED 0x712B
#define EXT_QUIC_PARAM_QUIC_VERSION 0x80004752
#define EXT_QUIC_PARAM_GREASE_LOW4 0x91D24E9B
#define EXT_QUIC_PARAM_GREASE_HIGH4 0xEA666DE7
#define EXTENSION_QUIC_PARAM_UA 0x7129
#define EXTENSION_QUIC_PARAM_VERSION 0x4752
enum _QUIC_VERSION app_identify_get_quic_protocol(int curdir_is_c2s, const unsigned char *payload, const int payload_len)
{
enum _QUIC_VERSION quic_version = QUIC_VERSION_UNKNOWN;
if(payload_len<5)
{
return QUIC_VERSION_UNKNOWN;
}
// Q001~Q043: 0x80 is currently unused, and must be set to 0
// The most significant bit (0x80) of byte 0 (the first byte) is set to 1 for long headers
(payload[0] & 0x80) ? (quic_version = (enum _QUIC_VERSION)ntohl(*(unsigned int *)(payload + 1))) : QUIC_VERSION_UNKNOWN;
if (
(quic_version == GQUIC_VERSION_Q099) ||
(quic_version == PICOQUIC_VERSION_30) ||
(quic_version == PQUIC_VERSION_PROX) ||
(quic_version == GQUIC_VERSION_T099) ||
(quic_version >= GQUIC_VERSION_Q044 && quic_version <= GQUIC_VERSION_Q050) ||
(quic_version >= GQUIC_VERSION_Q051 && quic_version <= GQUIC_VERSION_Q059) ||
(quic_version >= GQUIC_VERSION_T048 && quic_version <= GQUIC_VERSION_T049) ||
(quic_version >= GQUIC_VERSION_T050 && quic_version <= GQUIC_VERSION_T059) ||
(quic_version >= QUANT_VERSION_00 && quic_version <= QUANT_VERSION_FF) ||
(quic_version >= QUIC_GO_VERSION_00 && quic_version <= QUIC_GO_VERSION_FF) ||
(quic_version >= QUICLY_VERSION_00 && quic_version <= QUICLY_VERSION_FF) ||
(quic_version >= MSQUIC_VERSION_00 && quic_version <= MSQUIC_VERSION_0F) ||
(quic_version >= MOZQUIC_VERSION_00 && quic_version <= MOZQUIC_VERSION_0F) ||
(quic_version >= MVFST_VERSION_00 && quic_version <= MVFST_VERSION_0F) ||
(quic_version >= IQUIC_VERSION_I001 && quic_version <= IQUIC_VERSION_I032) ||
(quic_version == IQUIC_VERSION_RFC9000))
{
return quic_version;
}
char public_flags=payload[0];
int used_len = 1;
if(curdir_is_c2s==0 && public_flags & GQUIC_PUBLIC_FLAG_VERSION)
{
return QUIC_VERSION_UNKNOWN;
}
if((!public_flags)&GQUIC_PUBLIC_FLAG_PKT_NUM)
{
if(public_flags&GQUIC_PUBLIC_FLAG_VERSION) //Public Reset Packet
{
return QUIC_VERSION_UNKNOWN;// todo
}
else // Version Negotiation Packet
{
return QUIC_VERSION_UNKNOWN;
}
}
if(public_flags&GQUIC_PUBLIC_FLAG_CID)
{
used_len+=sizeof(unsigned long long); // CID length
}
if(payload_len>=(int)(used_len+sizeof(int)) && public_flags&GQUIC_PUBLIC_FLAG_VERSION && (*(unsigned char *)(payload+used_len)==0x51))
{
quic_version=(enum _QUIC_VERSION)ntohl(*(unsigned int *)(payload+used_len));
used_len+=sizeof(int); // skip version
}
if(quic_version<GQUIC_VERSION_Q001 || quic_version>GQUIC_VERSION_Q043)
{
return QUIC_VERSION_UNKNOWN;
}
return quic_version;
}

View File

@@ -1,10 +0,0 @@
VERS_2.4{
global:
extern "C" {
lpi_plugin_load;
lpi_plugin_unload;
GIT_VERSION_*;
};
local: *;
};

View File

@@ -0,0 +1,13 @@
add_definitions(-fPIC)
add_subdirectory(libprotoident)
add_library(lpi_plus lpip_module.c lpip_extend.c)
target_include_directories(lpi_plus PUBLIC ${CMAKE_SOURCE_DIR}/deps/)
target_include_directories(lpi_plus PUBLIC ${CMAKE_SOURCE_DIR}/decoders/)
target_link_libraries(lpi_plus libprotoident appid)
set_target_properties(lpi_plus PROPERTIES LINK_FLAGS
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map")
#install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/stellar_plugin COMPONENT LIBRARIES)

View File

@@ -29,12 +29,10 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
//#include <libtrace.h>
#include <inttypes.h> #include <inttypes.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h>
#include "libprotoident.h" #include "libprotoident.h"
#include "proto_manager.h" #include "proto_manager.h"
@@ -53,7 +51,7 @@ static LPIProtocolMap lpi_protocols;
static LPICategoryMap lpi_categories; static LPICategoryMap lpi_categories;
static LPICategoryProtocolMap lpi_category_protocols; static LPICategoryProtocolMap lpi_category_protocols;
int lpi_init_library(int level) { int lpi_init_library() {
if (init_called) { if (init_called) {
fprintf(stderr, "WARNING: lpi_init_library has already been called\n"); fprintf(stderr, "WARNING: lpi_init_library has already been called\n");

View File

@@ -30,8 +30,8 @@
//#include <libtrace.h> //#include <libtrace.h>
#include <pthread.h> #include <pthread.h>
#include <list>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <netinet/in.h> #include <netinet/in.h>
@@ -716,22 +716,12 @@ struct lpi_module {
}; };
typedef std::list<lpi_module_t *> ProtoMatchList;
typedef struct lpi_thread {
int index;
lpi_module_t *module;
lpi_data_t *data;
bool result;
} lpi_thread_t;
typedef std::list<pthread_t> ThreadList;
/* Initialises the LPI library, by registering all the protocol modules. /* Initialises the LPI library, by registering all the protocol modules.
* *
* @return 0 if initialisation succeeded, -1 otherwise * @return 0 if initialisation succeeded, -1 otherwise
*/ */
int lpi_init_library(int level); int lpi_init_library();
/* Shuts down the LPI library, by de-registering all the protocol modules */ /* Shuts down the LPI library, by de-registering all the protocol modules */
void lpi_free_library(void); void lpi_free_library(void);
@@ -755,9 +745,6 @@ void lpi_init_data(lpi_data_t *data);
* *
* @return 0 if the packet was ignored, 1 if the LPI data was updated. * @return 0 if the packet was ignored, 1 if the LPI data was updated.
*/ */
int lpi_update_dpkt(lpi_data_t *data, struct streaminfo *pstream,
const char *scan_data, int scan_data_len, char tsproto, uint32_t plseq,
uint32_t _curdir);
/** Returns a unique string describing the provided protocol. /** Returns a unique string describing the provided protocol.
* *

Some files were not shown because too many files have changed in this diff Show More