suricata
app-layer-tftp.c
Go to the documentation of this file.
1 /* Copyright (C) 2017-2021 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 "suricata.h"
30 #include "stream.h"
31 #include "conf.h"
32 
33 #include "util-unittest.h"
34 
35 #include "app-layer.h"
36 #include "app-layer-detect-proto.h"
37 #include "app-layer-parser.h"
38 
39 #include "app-layer-tftp.h"
40 #include "rust.h"
41 
42 /* The default port to probe if not provided in the configuration file. */
43 #define TFTP_DEFAULT_PORT "69"
44 
45 /* The minimum size for an message. For some protocols this might
46  * be the size of a header. */
47 #define TFTP_MIN_FRAME_LEN 4
48 
49 static void *TFTPStateAlloc(void *orig_state, AppProto proto_orig)
50 {
51  return rs_tftp_state_alloc();
52 }
53 
54 static void TFTPStateFree(void *state)
55 {
56  rs_tftp_state_free(state);
57 }
58 
59 /**
60  * \brief Callback from the application layer to have a transaction freed.
61  *
62  * \param state a void pointer to the TFTPState object.
63  * \param tx_id the transaction ID to free.
64  */
65 static void TFTPStateTxFree(void *state, uint64_t tx_id)
66 {
67  rs_tftp_state_tx_free(state, tx_id);
68 }
69 
70 static int TFTPStateGetEventInfo(const char *event_name, int *event_id,
71  AppLayerEventType *event_type)
72 {
73  return -1;
74 }
75 
76 /**
77  * \brief Probe the input to see if it looks like tftp.
78  *
79  * \retval ALPROTO_TFTP if it looks like tftp, otherwise
80  * ALPROTO_UNKNOWN.
81  */
82 static AppProto TFTPProbingParser(Flow *f, uint8_t direction,
83  const uint8_t *input, uint32_t input_len, uint8_t *rdir)
84 {
85  /* Very simple test - if there is input, this is tftp.
86  * Also check if it's starting by a zero */
87  if (input_len >= TFTP_MIN_FRAME_LEN && *input == 0) {
88  SCLogDebug("Detected as ALPROTO_TFTP.");
89  return ALPROTO_TFTP;
90  }
91 
92  SCLogDebug("Protocol not detected as ALPROTO_TFTP.");
93  return ALPROTO_UNKNOWN;
94 }
95 
96 static AppLayerResult TFTPParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
97  StreamSlice stream_slice, void *local_data)
98 {
99  const uint8_t *input = StreamSliceGetData(&stream_slice);
100  uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
101 
102  SCLogDebug("Parsing tftp request: len=%" PRIu32, input_len);
103 
104  /* Likely connection closed, we can just return here. */
105  if ((input == NULL || input_len == 0) &&
108  }
109 
110  /* Probably don't want to create a transaction in this case
111  * either. */
112  if (input == NULL || input_len == 0) {
114  }
115 
116  int res = rs_tftp_request(state, input, input_len);
117  if (res < 0) {
119  }
121 }
122 
123 /**
124  * \brief Response parsing is not implemented
125  */
126 static AppLayerResult TFTPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
127  StreamSlice stream_slice, void *local_data)
128 {
130 }
131 
132 static uint64_t TFTPGetTxCnt(void *state)
133 {
134  return rs_tftp_get_tx_cnt(state);
135 }
136 
137 static void *TFTPGetTx(void *state, uint64_t tx_id)
138 {
139  return rs_tftp_get_tx(state, tx_id);
140 }
141 
142 /**
143  * \brief Return the state of a transaction in a given direction.
144  *
145  * In the case of the tftp protocol, the existence of a transaction
146  * means that the request is done. However, some protocols that may
147  * need multiple chunks of data to complete the request may need more
148  * than just the existence of a transaction for the request to be
149  * considered complete.
150  *
151  * For the response to be considered done, the response for a request
152  * needs to be seen. The response_done flag is set on response for
153  * checking here.
154  */
155 static int TFTPGetStateProgress(void *tx, uint8_t direction)
156 {
157  return 1;
158 }
159 
161 {
162  const char *proto_name = "tftp";
163 
164  /* Check if TFTP UDP detection is enabled. If it does not exist in
165  * the configuration file then it will be enabled by default. */
166  if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
167 
168  SCLogDebug("TFTP UDP protocol detection enabled.");
169 
171 
172  if (RunmodeIsUnittests()) {
173  SCLogDebug("Unittest mode, registering default configuration.");
176  STREAM_TOSERVER, TFTPProbingParser,
177  TFTPProbingParser);
178  } else {
179  if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
180  proto_name, ALPROTO_TFTP,
182  TFTPProbingParser, TFTPProbingParser)) {
183  SCLogDebug("No tftp app-layer configuration, enabling tftp"
184  " detection UDP detection on port %s.",
186  AppLayerProtoDetectPPRegister(IPPROTO_UDP,
189  STREAM_TOSERVER,TFTPProbingParser,
190  TFTPProbingParser);
191  }
192  }
194  } else {
195  SCLogDebug("Protocol detector and parser disabled for TFTP.");
196  return;
197  }
198 
199  if (AppLayerParserConfParserEnabled("udp", proto_name)) {
200 
201  SCLogDebug("Registering TFTP protocol parser.");
202 
203  /* Register functions for state allocation and freeing. A
204  * state is allocated for every new TFTP flow. */
206  TFTPStateAlloc, TFTPStateFree);
207 
208  /* Register request parser for parsing frame from server to client. */
210  STREAM_TOSERVER, TFTPParseRequest);
211 
212  /* Register response parser for parsing frames from server to client. */
214  STREAM_TOCLIENT, TFTPParseResponse);
215 
216  /* Register a function to be called by the application layer
217  * when a transaction is to be freed. */
219  TFTPStateTxFree);
220 
221  /* Register a function to return the current transaction count. */
223  TFTPGetTxCnt);
224 
225  /* Transaction handling. */
228  ALPROTO_TFTP,
229  TFTPGetStateProgress);
231  TFTPGetTx);
232 
234  TFTPStateGetEventInfo);
235 
237  rs_tftp_get_tx_data);
238  AppLayerParserRegisterStateDataFunc(IPPROTO_UDP, ALPROTO_TFTP, rs_tftp_get_state_data);
239  }
240  else {
241  SCLogDebug("TFTP protocol parsing disabled.");
242  }
243 }
AppLayerParserRegisterGetStateProgressFunc
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
Definition: app-layer-parser.c:488
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:1583
app-layer-tftp.h
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:81
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:332
Flow_
Flow data structure.
Definition: flow.h:351
AppLayerParserRegisterStateProgressCompletionStatus
void AppLayerParserRegisterStateProgressCompletionStatus(AppProto alproto, const int ts, const int tc)
Definition: app-layer-parser.c:540
AppLayerParserRegisterTxFreeFunc
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))
Definition: app-layer-parser.c:499
rust.h
APP_LAYER_PARSER_EOF_TS
#define APP_LAYER_PARSER_EOF_TS
Definition: app-layer-parser.h:39
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:1543
app-layer-detect-proto.h
AppLayerParserState_
Definition: app-layer-parser.c:138
AppLayerParserRegisterLogger
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:469
AppLayerParserRegisterStateFuncs
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void *, AppProto), void(*StateFree)(void *))
Definition: app-layer-parser.c:423
app-layer-parser.h
stream.h
RegisterTFTPParsers
void RegisterTFTPParsers(void)
Definition: app-layer-tftp.c:160
TFTP_DEFAULT_PORT
#define TFTP_DEFAULT_PORT
Definition: app-layer-tftp.c:43
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:577
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1761
ALPROTO_TFTP
@ ALPROTO_TFTP
Definition: app-layer-protos.h:48
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:257
TFTP_MIN_FRAME_LEN
#define TFTP_MIN_FRAME_LEN
Definition: app-layer-tftp.c:47
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:390
AppLayerParserRegisterGetTx
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
Definition: app-layer-parser.c:521
APP_LAYER_OK
#define APP_LAYER_OK
Definition: app-layer-parser.h:88
SCReturnStruct
#define SCReturnStruct(x)
Definition: util-debug.h:291
suricata-common.h
AppLayerParserRegisterStateDataFunc
void AppLayerParserRegisterStateDataFunc(uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state))
Definition: app-layer-parser.c:599
AppLayerParserRegisterTxDataFunc
void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx))
Definition: app-layer-parser.c:589
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
suricata.h
AppLayerParserRegisterGetTxCnt
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t(*StateGetTxCnt)(void *alstate))
Definition: app-layer-parser.c:510
APP_LAYER_ERROR
#define APP_LAYER_ERROR
Definition: app-layer-parser.h:92
AppLayerParserStateIssetFlag
uint16_t AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag)
Definition: app-layer-parser.c:1794
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:1936
app-layer.h