-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathmysql.c
122 lines (102 loc) · 3.6 KB
/
mysql.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Copyright 2012-2017 AOL Inc. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "arkime.h"
typedef struct {
int versionLen;
char *version;
char ssl;
} Info_t;
LOCAL int userField;
LOCAL int versionField;
extern ArkimeConfig_t config;
/******************************************************************************/
LOCAL int mysql_parser(ArkimeSession_t *session, void *uw, const uint8_t *data, int len, int which)
{
Info_t *info = uw;
if (which != 0) {
return 0;
}
if (info->ssl) {
arkime_parsers_classify_tcp(session, data, len, which);
arkime_parsers_unregister(session, info);
return 0;
}
if ((len < 35 && len != 8) || data[1] != 0 || data[2] != 0 || data[3] > 2) {
arkime_parsers_unregister(session, info);
return 0;
}
const uint8_t *ptr = (uint8_t *)data + 36;
const uint8_t *end = (uint8_t *)data + len;
while (ptr < end) {
if (*ptr == 0)
break;
if (!isprint(*ptr)) {
arkime_parsers_unregister(session, info);
return 0;
}
ptr++;
}
arkime_session_add_protocol(session, "mysql");
arkime_field_string_add(versionField, session, info->version, info->versionLen, FALSE);
info->version = 0;
if (ptr > data + 36) {
arkime_field_string_add_lower(userField, session, (char *)data + 36, ptr - (data + 36));
}
if (data[5] & 0x08) { //CLIENT_SSL
info->ssl = 1;
} else {
arkime_parsers_unregister(session, info);
}
return 0;
}
/******************************************************************************/
LOCAL void mysql_free(ArkimeSession_t UNUSED(*session), void *uw)
{
Info_t *info = uw;
if (info->version)
g_free(info->version);
ARKIME_TYPE_FREE(Info_t, info);
}
/******************************************************************************/
LOCAL void mysql_classify(ArkimeSession_t *session, const uint8_t *data, int len, int which, void *UNUSED(uw))
{
if (which != 1)
return;
if (arkime_session_has_protocol(session, "mysql"))
return;
uint8_t *ptr = (uint8_t *)data + 5;
const uint8_t *end = (uint8_t *)data + len;
while (ptr < end) {
if (*ptr == 0)
break;
if (!isprint(*ptr)) {
return;
}
ptr++;
}
if (ptr == end || ptr == data + 5) {
return;
}
Info_t *info = ARKIME_TYPE_ALLOC0(Info_t);
info->versionLen = ptr - (data + 5);
info->version = g_strndup((char *)data + 5, info->versionLen);
arkime_parsers_register(session, mysql_parser, info, mysql_free);
}
/******************************************************************************/
void arkime_parser_init()
{
arkime_parsers_classifier_register_tcp("mysql", NULL, 1, (uint8_t *)"\x00\x00\x00\x0a", 4, mysql_classify);
userField = arkime_field_define("mysql", "lotermfield",
"mysql.user", "User", "mysql.user",
"Mysql user name",
ARKIME_FIELD_TYPE_STR, ARKIME_FIELD_FLAG_LINKED_SESSIONS,
"category", "user",
(char *)NULL);
versionField = arkime_field_define("mysql", "termfield",
"mysql.ver", "Version", "mysql.version",
"Mysql server version string",
ARKIME_FIELD_TYPE_STR, ARKIME_FIELD_FLAG_LINKED_SESSIONS,
(char *)NULL);
}