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