1 /* Copyright (C) 2017-2020 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Pierre Chifflier <chifflier@wzdftpd.net>
22  *
23  * Parser registration functions.
24  */
25 
26 #include "suricata-common.h"
27 #include "stream.h"
28 #include "conf.h"
29 
30 #include "app-layer-detect-proto.h"
31 #include "app-layer-parser.h"
32 
33 #include "app-layer-register.h"
34 
35 static const char * IpProtoToString(int ip_proto);
36 
AppLayerRegisterProtocolDetection(const struct AppLayerParser * p,int enable_default)37 AppProto AppLayerRegisterProtocolDetection(const struct AppLayerParser *p, int enable_default)
38 {
39     AppProto alproto;
40     const char *ip_proto_str = NULL;
41 
42     if (p == NULL)
43         FatalError(SC_ERR_FATAL, "Call to %s with NULL pointer.", __FUNCTION__);
44 
45     alproto = StringToAppProto(p->name);
46     if (alproto == ALPROTO_UNKNOWN || alproto == ALPROTO_FAILED)
47         FatalError(SC_ERR_FATAL, "Unknown or invalid AppProto '%s'.", p->name);
48 
49     ip_proto_str = IpProtoToString(p->ip_proto);
50     if (ip_proto_str == NULL)
51         FatalError(SC_ERR_FATAL, "Unknown or unsupported ip_proto field in parser '%s'", p->name);
52 
53     SCLogDebug("%s %s protocol detection enabled.", ip_proto_str, p->name);
54 
55     AppLayerProtoDetectRegisterProtocol(alproto, p->name);
56 
57     if (p->ProbeTS == NULL && p->ProbeTC == NULL) {
58         return alproto;
59     }
60 
61     if (RunmodeIsUnittests()) {
62 
63         SCLogDebug("Unittest mode, registering default configuration.");
64         AppLayerProtoDetectPPRegister(p->ip_proto, p->default_port,
65                 alproto, p->min_depth, p->max_depth, STREAM_TOSERVER,
66                 p->ProbeTS, p->ProbeTC);
67 
68     }
69     else {
70 
71         if (!AppLayerProtoDetectPPParseConfPorts(ip_proto_str, p->ip_proto,
72                     p->name, alproto, p->min_depth, p->max_depth,
73                     p->ProbeTS, p->ProbeTC)) {
74             if (enable_default != 0) {
75                 SCLogDebug("No %s app-layer configuration, enabling %s"
76                         " detection %s detection on port %s.",
77                         p->name, p->name, ip_proto_str, p->default_port);
78                 AppLayerProtoDetectPPRegister(p->ip_proto,
79                         p->default_port, alproto,
80                         p->min_depth, p->max_depth, STREAM_TOSERVER,
81                         p->ProbeTS, p->ProbeTC);
82             } else {
83                 SCLogDebug("No %s app-layer configuration for detection port (%s).",
84                         p->name, ip_proto_str);
85             }
86         }
87 
88     }
89 
90     return alproto;
91 }
92 
AppLayerRegisterParser(const struct AppLayerParser * p,AppProto alproto)93 int AppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto)
94 {
95     const char *ip_proto_str = NULL;
96 
97     if (p == NULL)
98         FatalError(SC_ERR_FATAL, "Call to %s with NULL pointer.", __FUNCTION__);
99 
100     if (alproto == ALPROTO_UNKNOWN || alproto >= ALPROTO_FAILED)
101         FatalError(SC_ERR_FATAL, "Unknown or invalid AppProto '%s'.", p->name);
102 
103     ip_proto_str = IpProtoToString(p->ip_proto);
104     if (ip_proto_str == NULL)
105         FatalError(SC_ERR_FATAL, "Unknown or unsupported ip_proto field in parser '%s'", p->name);
106 
107     SCLogDebug("Registering %s protocol parser.", p->name);
108 
109     /* Register functions for state allocation and freeing. A
110      * state is allocated for every new flow. */
111     AppLayerParserRegisterStateFuncs(p->ip_proto, alproto,
112         p->StateAlloc, p->StateFree);
113 
114     /* Register request parser for parsing frame from server to server. */
115     AppLayerParserRegisterParser(p->ip_proto, alproto,
116         STREAM_TOSERVER, p->ParseTS);
117 
118     /* Register response parser for parsing frames from server to client. */
119     AppLayerParserRegisterParser(p->ip_proto, alproto,
120         STREAM_TOCLIENT, p->ParseTC);
121 
122     /* Register a function to be called by the application layer
123      * when a transaction is to be freed. */
124     AppLayerParserRegisterTxFreeFunc(p->ip_proto, alproto,
125         p->StateTransactionFree);
126 
127     /* Register a function to return the current transaction count. */
128     AppLayerParserRegisterGetTxCnt(p->ip_proto, alproto,
129         p->StateGetTxCnt);
130 
131     /* Transaction handling. */
132     AppLayerParserRegisterGetStateProgressCompletionStatus(alproto,
133         p->StateGetProgressCompletionStatus);
134     AppLayerParserRegisterGetStateProgressFunc(p->ip_proto, alproto,
135         p->StateGetProgress);
136     AppLayerParserRegisterGetTx(p->ip_proto, alproto,
137         p->StateGetTx);
138 
139     /* What is this being registered for? */
140     AppLayerParserRegisterDetectStateFuncs(p->ip_proto, alproto,
141         p->GetTxDetectState, p->SetTxDetectState);
142 
143     if (p->StateGetEventInfo) {
144         AppLayerParserRegisterGetEventInfo(p->ip_proto, alproto,
145                 p->StateGetEventInfo);
146     }
147     if (p->StateGetEventInfoById) {
148         AppLayerParserRegisterGetEventInfoById(p->ip_proto, alproto,
149                 p->StateGetEventInfoById);
150     }
151     if (p->StateGetEvents) {
152         AppLayerParserRegisterGetEventsFunc(p->ip_proto, alproto,
153                 p->StateGetEvents);
154     }
155     if (p->LocalStorageAlloc && p->LocalStorageFree) {
156         AppLayerParserRegisterLocalStorageFunc(p->ip_proto, alproto,
157                 p->LocalStorageAlloc, p->LocalStorageFree);
158     }
159     if (p->StateGetFiles) {
160         AppLayerParserRegisterGetFilesFunc(p->ip_proto, alproto,
161                 p->StateGetFiles);
162     }
163 
164     if (p->GetTxIterator) {
165         AppLayerParserRegisterGetTxIterator(p->ip_proto, alproto,
166                 p->GetTxIterator);
167     }
168 
169     if (p->GetTxData) {
170         AppLayerParserRegisterTxDataFunc(p->ip_proto, alproto,
171                 p->GetTxData);
172     }
173 
174     if (p->ApplyTxConfig) {
175         AppLayerParserRegisterApplyTxConfigFunc(p->ip_proto, alproto,
176                 p->ApplyTxConfig);
177     }
178 
179     if (p->flags) {
180         AppLayerParserRegisterOptionFlags(p->ip_proto, alproto,
181                 p->flags);
182 
183     }
184 
185     if (p->Truncate) {
186         AppLayerParserRegisterTruncateFunc(p->ip_proto, alproto, p->Truncate);
187     }
188 
189     return 0;
190 }
191 
IpProtoToString(int ip_proto)192 static const char * IpProtoToString(int ip_proto)
193 {
194     switch (ip_proto) {
195         case IPPROTO_TCP:
196             return "tcp";
197         case IPPROTO_UDP:
198             return "udp";
199         default:
200             return NULL;
201     };
202 
203 }
204