suricata
app-layer-tftp.c
Go to the documentation of this file.
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 /**
20  * \file
21  *
22  * \author ClĂ©ment Galland <clement.galland@epita.fr>
23  *
24  * Parser for NTP application layer running on UDP port 69.
25  */
26 
27 
28 #include "suricata-common.h"
29 #include "stream.h"
30 #include "conf.h"
31 
32 #include "util-unittest.h"
33 
34 #include "app-layer-detect-proto.h"
35 #include "app-layer-parser.h"
36 
37 #include "app-layer-tftp.h"
38 #include "rust.h"
39 
40 /* The default port to probe if not provided in the configuration file. */
41 #define TFTP_DEFAULT_PORT "69"
42 
43 /* The minimum size for an message. For some protocols this might
44  * be the size of a header. */
45 #define TFTP_MIN_FRAME_LEN 4
46 
47 static void *TFTPStateAlloc(void *orig_state, AppProto proto_orig)
48 {
49  return rs_tftp_state_alloc();
50 }
51 
52 static void TFTPStateFree(void *state)
53 {
54  rs_tftp_state_free(state);
55 }
56 
57 /**
58  * \brief Callback from the application layer to have a transaction freed.
59  *
60  * \param state a void pointer to the TFTPState object.
61  * \param tx_id the transaction ID to free.
62  */
63 static void TFTPStateTxFree(void *state, uint64_t tx_id)
64 {
65  rs_tftp_state_tx_free(state, tx_id);
66 }
67 
68 static int TFTPStateGetEventInfo(const char *event_name, int *event_id,
69  AppLayerEventType *event_type)
70 {
71  return -1;
72 }
73 
74 static AppLayerDecoderEvents *TFTPGetEvents(void *tx)
75 {
76  return NULL;
77 }
78 
79 /**
80  * \brief Probe the input to see if it looks like echo.
81  *
82  * \retval ALPROTO_TFTP if it looks like echo, otherwise
83  * ALPROTO_UNKNOWN.
84  */
85 static AppProto TFTPProbingParser(Flow *f, uint8_t direction,
86  const uint8_t *input, uint32_t input_len, uint8_t *rdir)
87 {
88  /* Very simple test - if there is input, this is tftp.
89  * Also check if it's starting by a zero */
90  if (input_len >= TFTP_MIN_FRAME_LEN && *input == 0) {
91  SCLogDebug("Detected as ALPROTO_TFTP.");
92  return ALPROTO_TFTP;
93  }
94 
95  SCLogDebug("Protocol not detected as ALPROTO_TFTP.");
96  return ALPROTO_UNKNOWN;
97 }
98 
99 static AppLayerResult TFTPParseRequest(Flow *f, void *state,
100  AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
101  void *local_data, const uint8_t flags)
102 {
103  SCLogDebug("Parsing echo request: len=%"PRIu32, input_len);
104 
105  /* Likely connection closed, we can just return here. */
106  if ((input == NULL || input_len == 0) &&
109  }
110 
111  /* Probably don't want to create a transaction in this case
112  * either. */
113  if (input == NULL || input_len == 0) {
115  }
116 
117  int res = rs_tftp_request(state, input, input_len);
118  if (res < 0) {
120  }
122 }
123 
124 /**
125  * \brief Response parsing is not implemented
126  */
127 static AppLayerResult TFTPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
128  const uint8_t *input, uint32_t input_len, void *local_data,
129  const uint8_t flags)
130 {
132 }
133 
134 static uint64_t TFTPGetTxCnt(void *state)
135 {
136  return rs_tftp_get_tx_cnt(state);
137 }
138 
139 static void *TFTPGetTx(void *state, uint64_t tx_id)
140 {
141  return rs_tftp_get_tx(state, tx_id);
142 }
143 
144 /**
145  * \brief Called by the application layer.
146  *
147  * In most cases 1 can be returned here.
148  */
149 static int TFTPGetAlstateProgressCompletionStatus(uint8_t direction) {
150  return 1;
151 }
152 
153 /**
154  * \brief Return the state of a transaction in a given direction.
155  *
156  * In the case of the echo protocol, the existence of a transaction
157  * means that the request is done. However, some protocols that may
158  * need multiple chunks of data to complete the request may need more
159  * than just the existence of a transaction for the request to be
160  * considered complete.
161  *
162  * For the response to be considered done, the response for a request
163  * needs to be seen. The response_done flag is set on response for
164  * checking here.
165  */
166 static int TFTPGetStateProgress(void *tx, uint8_t direction)
167 {
168  return 1;
169 }
170 
171 static DetectEngineState *TFTPGetTxDetectState(void *vtx)
172 {
173  return NULL;
174 }
175 
176 static int TFTPSetTxDetectState(void *vtx,
178 {
179  return 0;
180 }
181 
183 {
184  const char *proto_name = "tftp";
185 
186  /* Check if TFTP UDP detection is enabled. If it does not exist in
187  * the configuration file then it will be enabled by default. */
188  if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
189 
190  SCLogDebug("TFTP UDP protocol detection enabled.");
191 
193 
194  if (RunmodeIsUnittests()) {
195  SCLogDebug("Unittest mode, registeringd default configuration.");
198  STREAM_TOSERVER, TFTPProbingParser,
199  TFTPProbingParser);
200  } else {
201  if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
202  proto_name, ALPROTO_TFTP,
204  TFTPProbingParser, TFTPProbingParser)) {
205  SCLogDebug("No echo app-layer configuration, enabling echo"
206  " detection UDP detection on port %s.",
208  AppLayerProtoDetectPPRegister(IPPROTO_UDP,
211  STREAM_TOSERVER,TFTPProbingParser,
212  TFTPProbingParser);
213  }
214  }
215  } else {
216  SCLogDebug("Protocol detecter and parser disabled for TFTP.");
217  return;
218  }
219 
220  if (AppLayerParserConfParserEnabled("udp", proto_name)) {
221 
222  SCLogDebug("Registering TFTP protocol parser.");
223 
224  /* Register functions for state allocation and freeing. A
225  * state is allocated for every new TFTP flow. */
227  TFTPStateAlloc, TFTPStateFree);
228 
229  /* Register request parser for parsing frame from server to client. */
231  STREAM_TOSERVER, TFTPParseRequest);
232 
233  /* Register response parser for parsing frames from server to client. */
235  STREAM_TOCLIENT, TFTPParseResponse);
236 
237  /* Register a function to be called by the application layer
238  * when a transaction is to be freed. */
240  TFTPStateTxFree);
241 
242  /* Register a function to return the current transaction count. */
244  TFTPGetTxCnt);
245 
246  /* Transaction handling. */
248  TFTPGetAlstateProgressCompletionStatus);
250  ALPROTO_TFTP,
251  TFTPGetStateProgress);
253  TFTPGetTx);
254 
255  /* What is this being registered for? */
257  TFTPGetTxDetectState,
258  TFTPSetTxDetectState);
259 
261  TFTPStateGetEventInfo);
263  TFTPGetEvents);
264 
266  rs_tftp_get_tx_data);
267  }
268  else {
269  SCLogDebug("TFTP protocol parsing disabled.");
270  }
271 }
AppLayerParserRegisterGetStateProgressFunc
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
Definition: app-layer-parser.c:475
AppLayerProtoDetectPPParseConfPorts
int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name, uint8_t ipproto, const char *alproto_name, AppProto alproto, uint16_t min_depth, uint16_t max_depth, ProbingParserFPtr ProbingParserTs, ProbingParserFPtr ProbingParserTc)
Definition: app-layer-detect-proto.c:1699
app-layer-tftp.h
DetectEngineState_
Definition: detect-engine-state.h:92
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:73
AppLayerParserConfParserEnabled
int AppLayerParserConfParserEnabled(const char *ipproto, const char *alproto_name)
check if a parser is enabled in the config Returns enabled always if: were running unittests
Definition: app-layer-parser.c:301
Flow_
Flow data structure.
Definition: flow.h:347
AppLayerEventType
enum AppLayerEventType_ AppLayerEventType
AppLayerParserRegisterGetEventsFunc
void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto, AppLayerDecoderEvents *(*StateGetEvents)(void *))
Definition: app-layer-parser.c:436
AppLayerParserRegisterTxFreeFunc
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))
Definition: app-layer-parser.c:486
rust.h
AppLayerParserRegisterDetectStateFuncs
void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto, DetectEngineState *(*GetTxDetectState)(void *tx), int(*SetTxDetectState)(void *tx, DetectEngineState *))
Definition: app-layer-parser.c:562
APP_LAYER_PARSER_EOF_TS
#define APP_LAYER_PARSER_EOF_TS
Definition: app-layer-parser.h:41
AppLayerDecoderEvents_
Data structure to store app layer decoder events.
Definition: app-layer-events.h:34
util-unittest.h
AppLayerProtoDetectPPRegister
void AppLayerProtoDetectPPRegister(uint8_t ipproto, const char *portstr, AppProto alproto, uint16_t min_depth, uint16_t max_depth, uint8_t direction, ProbingParserFPtr ProbingParser1, ProbingParserFPtr ProbingParser2)
register parser at a port
Definition: app-layer-detect-proto.c:1665
app-layer-detect-proto.h
AppLayerParserStateIssetFlag
int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag)
Definition: app-layer-parser.c:1648
AppLayerParserState_
Definition: app-layer-parser.c:154
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
AppLayerParserRegisterStateFuncs
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void *, AppProto), void(*StateFree)(void *))
Definition: app-layer-parser.c:398
app-layer-parser.h
stream.h
RegisterTFTPParsers
void RegisterTFTPParsers(void)
Definition: app-layer-tftp.c:182
TFTP_DEFAULT_PORT
#define TFTP_DEFAULT_PORT
Definition: app-layer-tftp.c:41
conf.h
AppLayerParserRegisterGetEventInfo
void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type))
Definition: app-layer-parser.c:550
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1875
ALPROTO_TFTP
@ ALPROTO_TFTP
Definition: app-layer-protos.h:48
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:264
TFTP_MIN_FRAME_LEN
#define TFTP_MIN_FRAME_LEN
Definition: app-layer-tftp.c:45
AppLayerParserRegisterParser
int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, uint8_t direction, AppLayerParserFPtr Parser)
Register app layer parser for the protocol.
Definition: app-layer-parser.c:359
AppLayerParserRegisterGetStateProgressCompletionStatus
void AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto, int(*StateGetProgressCompletionStatus)(uint8_t direction))
Definition: app-layer-parser.c:527
AppLayerParserRegisterGetTx
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
Definition: app-layer-parser.c:508
APP_LAYER_OK
#define APP_LAYER_OK
Definition: app-layer-parser.h:60
SCReturnStruct
#define SCReturnStruct(x)
Definition: util-debug.h:320
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
AppLayerParserRegisterTxDataFunc
void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx))
Definition: app-layer-parser.c:574
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
AppLayerParserRegisterGetTxCnt
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t(*StateGetTxCnt)(void *alstate))
Definition: app-layer-parser.c:497
APP_LAYER_ERROR
#define APP_LAYER_ERROR
Definition: app-layer-parser.h:64
AppLayerProtoDetectConfProtoDetectionEnabled
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
Definition: app-layer-detect-proto.c:1938