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
35static void DetectFtpReplyReceivedFree(DetectEngineCtx *, void *);
36static int g_ftp_reply_received_buffer_id = 0;
37
38static 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 */
62static 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 */
84static 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 */
108static 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}
@ ALPROTO_FTP
uint8_t flags
Definition decode-gre.h:0
@ DETECT_FTP_REPLY_RECEIVED
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
int DetectBufferTypeGetByName(const char *name)
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.
void DetectFtpReplyReceivedRegister(void)
Registration function for ftp.reply_received: keyword.
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
#define SIG_FLAG_TOCLIENT
Definition detect.h:272
SCMutex m
Definition flow-hash.h:6
DetectEngineCtx * de_ctx
main detection engine ctx
Definition detect.h:932
FtpCommandInfo command_descriptor
Flow data structure.
Definition flow.h:356
FtpRequestCommand command_code
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
const char * desc
Definition detect.h:1461
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition detect.h:1424
const char * name
Definition detect.h:1459
Signature container.
Definition detect.h:668
#define str(s)
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define unlikely(expr)