suricata
detect-ftp-reply-received.c
Go to the documentation of this file.
1 /* Copyright (C) 2025 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 Jeff Lucovsky <jlucovsky@oisf.net>
22  *
23  * Match on FTP reply received.
24  */
25 
26 #include "suricata-common.h"
27 
28 #include "detect-parse.h"
29 #include "detect-engine.h"
30 
31 #include "app-layer-ftp.h"
32 
34 
35 static void DetectFtpReplyReceivedFree(DetectEngineCtx *, void *);
36 static int g_ftp_reply_received_buffer_id = 0;
37 
38 static int DetectFtpReplyReceivedMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
39  void *state, void *txv, const Signature *s, const SigMatchCtx *m)
40 {
41  FTPTransaction *tx = (FTPTransaction *)txv;
42  if (tx->command_descriptor.command_code == FTP_COMMAND_UNKNOWN) {
43  return 0;
44  }
45 
46  const DetectFtpReplyReceivedData *ftprrd = (const DetectFtpReplyReceivedData *)m;
47  if (ftprrd->received == tx->done)
48  return 1;
49 
50  return 0;
51 }
52 
53 /**
54  * \brief This function is used to parse ftp.reply_received options passed via ftp.reply_received
55  * keyword
56  *
57  * \param str Pointer to the user provided ftp.reply_received options
58  *
59  * \retval pointer to DetectFtpReplyReceivedData on success
60  * \retval NULL on failure
61  */
62 static DetectFtpReplyReceivedData *DetectFtpdataParse(const char *optstr)
63 {
64  DetectFtpReplyReceivedData *frrd = SCFTPParseReplyReceived(optstr);
65  if (unlikely(frrd == NULL)) {
66  SCLogError("invalid value; specify yes or no");
67  return NULL;
68  }
69 
70  return frrd;
71 }
72 
73 /**
74  * \brief parse the options from the 'ftp.reply_received' keyword in the rule into
75  * the Signature data structure.
76  *
77  * \param de_ctx pointer to the Detection Engine Context
78  * \param s pointer to the Current Signature
79  * \param str pointer to the user provided ftp.reply_received options
80  *
81  * \retval 0 on Success
82  * \retval -1 on Failure
83  */
84 static int DetectFtpReplyReceivedSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
85 {
86  DetectFtpReplyReceivedData *frrd = DetectFtpdataParse(str);
87  if (frrd == NULL)
88  return -1;
89 
91  DetectFtpReplyReceivedFree(de_ctx, frrd);
92  return -1;
93  }
94 
96  g_ftp_reply_received_buffer_id) == NULL) {
97  DetectFtpReplyReceivedFree(de_ctx, frrd);
98  return -1;
99  }
100  return 0;
101 }
102 
103 /**
104  * \brief this function will free memory associated with DetectFtpReplyReceivedData
105  *
106  * \param ptr pointer to DetectFtpReplyReceivedData
107  */
108 static void DetectFtpReplyReceivedFree(DetectEngineCtx *de_ctx, void *ptr)
109 {
110  if (ptr) {
111  DetectFtpReplyReceivedData *frrd = (DetectFtpReplyReceivedData *)ptr;
112  SCFTPFreeReplyReceivedData(frrd);
113  }
114 }
115 
116 /**
117  * \brief Registration function for ftp.reply_received: keyword
118  *
119  * This function is called once in the 'lifetime' of the engine.
120  */
122 {
123  sigmatch_table[DETECT_FTP_REPLY_RECEIVED].name = "ftp.reply_received";
124  sigmatch_table[DETECT_FTP_REPLY_RECEIVED].desc = "match on FTP whether a reply was received";
125  sigmatch_table[DETECT_FTP_REPLY_RECEIVED].url = "/rules/ftp-keywords.html#ftp.reply_received";
126  sigmatch_table[DETECT_FTP_REPLY_RECEIVED].AppLayerTxMatch = DetectFtpReplyReceivedMatch;
127  sigmatch_table[DETECT_FTP_REPLY_RECEIVED].Setup = DetectFtpReplyReceivedSetup;
128  sigmatch_table[DETECT_FTP_REPLY_RECEIVED].Free = DetectFtpReplyReceivedFree;
129 
132  g_ftp_reply_received_buffer_id = DetectBufferTypeGetByName("ftp.reply_received");
133 }
DetectFtpReplyReceivedRegister
void DetectFtpReplyReceivedRegister(void)
Registration function for ftp.reply_received: keyword.
Definition: detect-ftp-reply-received.c:121
detect-ftp-reply-received.h
SigTableElmt_::url
const char * url
Definition: detect.h:1422
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1421
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1409
SigTableElmt_::name
const char * name
Definition: detect.h:1419
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
Flow_
Flow data structure.
Definition: flow.h:356
FTPTransaction_::done
bool done
Definition: app-layer-ftp.h:75
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:919
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1387
ALPROTO_FTP
@ ALPROTO_FTP
Definition: app-layer-protos.h:37
m
SCMutex m
Definition: flow-hash.h:6
SCDetectSignatureSetAppProto
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:2212
app-layer-ftp.h
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:272
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1404
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1256
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1211
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:388
FTPTransaction_::command_descriptor
FtpCommandInfo command_descriptor
Definition: app-layer-ftp.h:72
FtpCommandInfo_::command_code
FtpRequestCommand command_code
Definition: app-layer-ftp.h:57
DETECT_FTP_REPLY_RECEIVED
@ DETECT_FTP_REPLY_RECEIVED
Definition: detect-engine-register.h:336
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:352
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
DetectEngineInspectGenericList
uint8_t DetectEngineInspectGenericList(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:1933
str
#define str(s)
Definition: suricata-common.h:308
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:262
detect-parse.h
Signature_
Signature container.
Definition: detect.h:657
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:249
FTPTransaction_
Definition: app-layer-ftp.h:60