suricata
app-layer-tftp.c
Go to the documentation of this file.
1 /* Copyright (C) 2017-2024 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 
31 #include "app-layer.h"
32 #include "app-layer-detect-proto.h"
33 #include "app-layer-parser.h"
34 
35 #include "app-layer-tftp.h"
36 
37 /* The default port to probe if not provided in the configuration file. */
38 #define TFTP_DEFAULT_PORT "69"
39 
40 /* The minimum size for an message. For some protocols this might
41  * be the size of a header. */
42 #define TFTP_MIN_FRAME_LEN 4
43 
44 static void *TFTPStateAlloc(void *orig_state, AppProto proto_orig)
45 {
46  return SCTftpStateAlloc();
47 }
48 
49 static void TFTPStateFree(void *state)
50 {
51  SCTftpStateFree(state);
52 }
53 
54 /**
55  * \brief Callback from the application layer to have a transaction freed.
56  *
57  * \param state a void pointer to the TFTPState object.
58  * \param tx_id the transaction ID to free.
59  */
60 static void TFTPStateTxFree(void *state, uint64_t tx_id)
61 {
62  SCTftpStateTxFree(state, tx_id);
63 }
64 
65 static int TFTPStateGetEventInfo(
66  const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
67 {
68  return -1;
69 }
70 
71 /**
72  * \brief Probe the input to see if it looks like tftp.
73  *
74  * \retval ALPROTO_TFTP if it looks like tftp, otherwise
75  * ALPROTO_UNKNOWN.
76  */
77 static AppProto TFTPProbingParser(
78  const Flow *f, uint8_t direction, const uint8_t *input, uint32_t input_len, uint8_t *rdir)
79 {
80  /* Very simple test - if there is input, this is tftp.
81  * Also check if it's starting by a zero */
82  if (input_len >= TFTP_MIN_FRAME_LEN && *input == 0) {
83  SCLogDebug("Detected as ALPROTO_TFTP.");
84  return ALPROTO_TFTP;
85  }
86 
87  SCLogDebug("Protocol not detected as ALPROTO_TFTP.");
88  return ALPROTO_UNKNOWN;
89 }
90 
91 static AppLayerResult TFTPParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
92  StreamSlice stream_slice, void *local_data)
93 {
94  const uint8_t *input = StreamSliceGetData(&stream_slice);
95  uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
96 
97  SCLogDebug("Parsing tftp request: len=%" PRIu32, input_len);
98 
99  /* Likely connection closed, we can just return here. */
100  if ((input == NULL || input_len == 0) &&
103  }
104 
105  /* Probably don't want to create a transaction in this case
106  * either. */
107  if (input == NULL || input_len == 0) {
109  }
110 
111  int64_t res = SCTftpParseRequest(state, input, input_len);
112  if (res < 0) {
114  }
116 }
117 
118 /**
119  * \brief Response parsing is not implemented
120  */
121 static AppLayerResult TFTPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
122  StreamSlice stream_slice, void *local_data)
123 {
125 }
126 
127 static uint64_t TFTPGetTxCnt(void *state)
128 {
129  return SCTftpGetTxCnt(state);
130 }
131 
132 static void *TFTPGetTx(void *state, uint64_t tx_id)
133 {
134  return SCTftpGetTx(state, tx_id);
135 }
136 
137 /**
138  * \brief Return the state of a transaction in a given direction.
139  *
140  * In the case of the tftp protocol, the existence of a transaction
141  * means that the request is done. However, some protocols that may
142  * need multiple chunks of data to complete the request may need more
143  * than just the existence of a transaction for the request to be
144  * considered complete.
145  *
146  * For the response to be considered done, the response for a request
147  * needs to be seen. The response_done flag is set on response for
148  * checking here.
149  */
150 static int TFTPGetStateProgress(void *tx, uint8_t direction)
151 {
152  return 1;
153 }
154 
156 {
157  const char *proto_name = "tftp";
158 
159  /* Check if TFTP UDP detection is enabled. If it does not exist in
160  * the configuration file then it will be enabled by default. */
161  if (SCAppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
162 
163  SCLogDebug("TFTP UDP protocol detection enabled.");
164 
166 
167  if (RunmodeIsUnittests()) {
168  SCLogDebug("Unittest mode, registering default configuration.");
170  TFTP_MIN_FRAME_LEN, STREAM_TOSERVER, TFTPProbingParser, TFTPProbingParser);
171  } else {
172  if (!SCAppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP, proto_name, ALPROTO_TFTP,
173  0, TFTP_MIN_FRAME_LEN, TFTPProbingParser, TFTPProbingParser)) {
174  SCLogDebug("No tftp app-layer configuration, enabling tftp"
175  " detection UDP detection on port %s.",
178  TFTP_MIN_FRAME_LEN, STREAM_TOSERVER, TFTPProbingParser, TFTPProbingParser);
179  }
180  }
182  } else {
183  SCLogDebug("Protocol detector and parser disabled for TFTP.");
184  return;
185  }
186 
187  if (SCAppLayerParserConfParserEnabled("udp", proto_name)) {
188 
189  SCLogDebug("Registering TFTP protocol parser.");
190 
191  /* Register functions for state allocation and freeing. A
192  * state is allocated for every new TFTP flow. */
194  TFTPStateAlloc, TFTPStateFree);
195 
196  /* Register request parser for parsing frame from server to client. */
198  STREAM_TOSERVER, TFTPParseRequest);
199 
200  /* Register response parser for parsing frames from server to client. */
202  STREAM_TOCLIENT, TFTPParseResponse);
203 
204  /* Register a function to be called by the application layer
205  * when a transaction is to be freed. */
207  TFTPStateTxFree);
208 
209  /* Register a function to return the current transaction count. */
211  TFTPGetTxCnt);
212 
213  /* Transaction handling. */
216  ALPROTO_TFTP,
217  TFTPGetStateProgress);
219  TFTPGetTx);
220 
222  TFTPStateGetEventInfo);
223 
224  AppLayerParserRegisterTxDataFunc(IPPROTO_UDP, ALPROTO_TFTP, SCTftpGetTxData);
225  AppLayerParserRegisterStateDataFunc(IPPROTO_UDP, ALPROTO_TFTP, SCTftpGetStateData);
226  } else {
227  SCLogDebug("TFTP protocol parsing disabled.");
228  }
229 }
AppLayerParserRegisterGetStateProgressFunc
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
Definition: app-layer-parser.c:500
SCAppLayerParserStateIssetFlag
uint16_t SCAppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag)
Definition: app-layer-parser.c:1829
app-layer-tftp.h
StreamSlice
struct StreamSlice StreamSlice
Definition: app-layer-parser.h:38
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:275
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:86
Flow_
Flow data structure.
Definition: flow.h:356
AppLayerParserRegisterStateProgressCompletionStatus
void AppLayerParserRegisterStateProgressCompletionStatus(AppProto alproto, const int ts, const int tc)
Definition: app-layer-parser.c:548
AppLayerParserRegisterTxFreeFunc
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))
Definition: app-layer-parser.c:510
AppLayerEventType
enum AppLayerEventType AppLayerEventType
Definition: app-layer-parser.h:43
APP_LAYER_PARSER_EOF_TS
#define APP_LAYER_PARSER_EOF_TS
Definition: app-layer-parser.h:53
SCAppLayerProtoDetectConfProtoDetectionEnabled
int SCAppLayerProtoDetectConfProtoDetectionEnabled(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:1942
app-layer-detect-proto.h
AppLayerResult
struct AppLayerResult AppLayerResult
Definition: app-layer-parser.h:39
AppLayerParserState_
Definition: app-layer-parser.c:135
SCAppLayerParserConfParserEnabled
int SCAppLayerParserConfParserEnabled(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:345
SCAppLayerParserRegisterLogger
void SCAppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:491
AppLayerParserRegisterStateFuncs
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void *, AppProto), void(*StateFree)(void *))
Definition: app-layer-parser.c:435
app-layer-parser.h
AppLayerParserRegisterGetEventInfo
void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfo)(const char *event_name, uint8_t *event_id, AppLayerEventType *event_type))
Definition: app-layer-parser.c:595
RegisterTFTPParsers
void RegisterTFTPParsers(void)
Definition: app-layer-tftp.c:155
TFTP_DEFAULT_PORT
#define TFTP_DEFAULT_PORT
Definition: app-layer-tftp.c:38
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1742
ALPROTO_TFTP
@ ALPROTO_TFTP
Definition: app-layer-protos.h:54
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:270
TFTP_MIN_FRAME_LEN
#define TFTP_MIN_FRAME_LEN
Definition: app-layer-tftp.c:42
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:402
SCAppLayerProtoDetectPPRegister
void SCAppLayerProtoDetectPPRegister(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:1527
AppLayerParserRegisterGetTx
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
Definition: app-layer-parser.c:530
APP_LAYER_OK
#define APP_LAYER_OK
Definition: app-layer-parser.h:77
SCReturnStruct
#define SCReturnStruct(x)
Definition: util-debug.h:297
suricata-common.h
AppLayerParserRegisterStateDataFunc
void AppLayerParserRegisterStateDataFunc(uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state))
Definition: app-layer-parser.c:616
AppLayerParserRegisterTxDataFunc
void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx))
Definition: app-layer-parser.c:606
SCAppLayerProtoDetectPPParseConfPorts
int SCAppLayerProtoDetectPPParseConfPorts(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:1563
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:520
APP_LAYER_ERROR
#define APP_LAYER_ERROR
Definition: app-layer-parser.h:81
app-layer.h