aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/app-layer-htp-xff.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/suricata/src/app-layer-htp-xff.c')
-rw-r--r--framework/src/suricata/src/app-layer-htp-xff.c364
1 files changed, 0 insertions, 364 deletions
diff --git a/framework/src/suricata/src/app-layer-htp-xff.c b/framework/src/suricata/src/app-layer-htp-xff.c
deleted file mode 100644
index 96c6de48..00000000
--- a/framework/src/suricata/src/app-layer-htp-xff.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/* Copyright (C) 2014 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Ignacio Sanchez <sanchezmartin.ji@gmail.com>
- * \author Duarte Silva <duarte.silva@serializing.me>
- */
-
-#include "suricata-common.h"
-#include "conf.h"
-
-#include "app-layer-parser.h"
-#include "app-layer-htp.h"
-#include "app-layer-htp-xff.h"
-
-#include "util-misc.h"
-#include "util-memrchr.h"
-#include "util-unittest.h"
-
-/** XFF header value minimal length */
-#define XFF_CHAIN_MINLEN 7
-/** XFF header value maximum length */
-#define XFF_CHAIN_MAXLEN 256
-/** Default XFF header name */
-#define XFF_DEFAULT "X-Forwarded-For"
-
-/** \internal
- * \brief parse XFF string
- * \param input input string, might be modified
- * \param output output buffer
- * \param output_size size of output buffer
- * \retval bool 1 ok, 0 fail
- */
-static int ParseXFFString(char *input, char *output, int output_size)
-{
- size_t len = strlen(input);
- if (len == 0)
- return 0;
-
- if (input[0] == '[') {
- char *end = strchr(input, ']');
- if (end == NULL) // malformed, not closed
- return 0;
-
- if (end != input+(len - 1)) {
- SCLogDebug("data after closing bracket");
- // if we ever want to parse the port, we can do it here
- }
-
- /* done, lets wrap up */
- input++; // skip past [
- *end = '\0'; // overwrite ], ignore anything after
-
- } else {
- /* lets see if the xff string ends in a port */
- int c = 0;
- int d = 0;
- char *p = input;
- while (*p != '\0') {
- if (*p == ':')
- c++;
- if (*p == '.')
- d++;
- p++;
- }
- /* 3 dots: ipv4, one ':' port */
- if (d == 3 && c == 1) {
- SCLogDebug("XFF w port %s", input);
- char *x = strchr(input, ':');
- if (x) {
- *x = '\0';
- SCLogDebug("XFF w/o port %s", input);
- // if we ever want to parse the port, we can do it here
- }
- }
- }
-
- SCLogDebug("XFF %s", input);
-
- /** Sanity check on extracted IP for IPv4 and IPv6 */
- uint32_t ip[4];
- if (inet_pton(AF_INET, input, ip) == 1 ||
- inet_pton(AF_INET6, input, ip) == 1)
- {
- strlcpy(output, input, output_size);
- return 1; // OK
- }
- return 0;
-}
-
-/**
- * \brief Function to return XFF IP if any in the selected transaction. The
- * caller needs to lock the flow.
- * \retval 1 if the IP has been found and returned in dstbuf
- * \retval 0 if the IP has not being found or error
- */
-int HttpXFFGetIPFromTx(const Packet *p, uint64_t tx_id, HttpXFFCfg *xff_cfg,
- char *dstbuf, int dstbuflen)
-{
- uint8_t xff_chain[XFF_CHAIN_MAXLEN];
- HtpState *htp_state = NULL;
- htp_tx_t *tx = NULL;
- uint64_t total_txs = 0;
- uint8_t *p_xff = NULL;
-
- htp_state = (HtpState *)FlowGetAppState(p->flow);
-
- if (htp_state == NULL) {
- SCLogDebug("no http state, XFF IP cannot be retrieved");
- return 0;
- }
-
- total_txs = AppLayerParserGetTxCnt(p->flow->proto, ALPROTO_HTTP, htp_state);
- if (tx_id >= total_txs)
- return 0;
-
- tx = AppLayerParserGetTx(p->flow->proto, ALPROTO_HTTP, htp_state, tx_id);
- if (tx == NULL) {
- SCLogDebug("tx is NULL, XFF cannot be retrieved");
- return 0;
- }
-
- htp_header_t *h_xff = NULL;
- if (tx->request_headers != NULL) {
- h_xff = htp_table_get_c(tx->request_headers, xff_cfg->header);
- }
-
- if (h_xff != NULL && bstr_len(h_xff->value) >= XFF_CHAIN_MINLEN &&
- bstr_len(h_xff->value) < XFF_CHAIN_MAXLEN) {
-
- memcpy(xff_chain, bstr_ptr(h_xff->value), bstr_len(h_xff->value));
- xff_chain[bstr_len(h_xff->value)]=0;
-
- if (xff_cfg->flags & XFF_REVERSE) {
- /** Get the last IP address from the chain */
- p_xff = memrchr(xff_chain, ' ', bstr_len(h_xff->value));
- if (p_xff == NULL) {
- p_xff = xff_chain;
- } else {
- p_xff++;
- }
- }
- else {
- /** Get the first IP address from the chain */
- p_xff = memchr(xff_chain, ',', bstr_len(h_xff->value));
- if (p_xff != NULL) {
- xff_chain[bstr_len(h_xff->value) - (p_xff - xff_chain)]=0;
- }
- p_xff = xff_chain;
- }
- return ParseXFFString((char *)p_xff, dstbuf, dstbuflen);
- }
- return 0;
-}
-
-/**
- * \brief Function to return XFF IP if any. The caller needs to lock the flow.
- * \retval 1 if the IP has been found and returned in dstbuf
- * \retval 0 if the IP has not being found or error
- */
-int HttpXFFGetIP(const Packet *p, HttpXFFCfg *xff_cfg, char *dstbuf, int dstbuflen)
-{
- HtpState *htp_state = NULL;
- uint64_t tx_id = 0;
- uint64_t total_txs = 0;
-
- htp_state = (HtpState *)FlowGetAppState(p->flow);
- if (htp_state == NULL) {
- SCLogDebug("no http state, XFF IP cannot be retrieved");
- goto end;
- }
-
- total_txs = AppLayerParserGetTxCnt(p->flow->proto, ALPROTO_HTTP, htp_state);
- for (; tx_id < total_txs; tx_id++) {
- if (HttpXFFGetIPFromTx(p, tx_id, xff_cfg, dstbuf, dstbuflen) == 1)
- return 1;
- }
-
-end:
- return 0; // Not found
-}
-
-/**
- * \brief Function to return XFF configuration from a configuration node.
- */
-void HttpXFFGetCfg(ConfNode *conf, HttpXFFCfg *result)
-{
- BUG_ON(conf == NULL || result == NULL);
-
- ConfNode *xff_node = NULL;
-
- if (conf != NULL)
- xff_node = ConfNodeLookupChild(conf, "xff");
-
- if (xff_node != NULL && ConfNodeChildValueIsTrue(xff_node, "enabled")) {
- const char *xff_mode = ConfNodeLookupChildValue(xff_node, "mode");
-
- if (xff_mode != NULL && strcasecmp(xff_mode, "overwrite") == 0) {
- result->flags |= XFF_OVERWRITE;
- } else {
- if (xff_mode == NULL) {
- SCLogWarning(SC_WARN_XFF_INVALID_MODE, "The XFF mode hasn't been defined, falling back to extra-data mode");
- }
- else if (strcasecmp(xff_mode, "extra-data") != 0) {
- SCLogWarning(SC_WARN_XFF_INVALID_MODE, "The XFF mode %s is invalid, falling back to extra-data mode",
- xff_mode);
- }
- result->flags |= XFF_EXTRADATA;
- }
-
- const char *xff_deployment = ConfNodeLookupChildValue(xff_node, "deployment");
-
- if (xff_deployment != NULL && strcasecmp(xff_deployment, "forward") == 0) {
- result->flags |= XFF_FORWARD;
- } else {
- if (xff_deployment == NULL) {
- SCLogWarning(SC_WARN_XFF_INVALID_DEPLOYMENT, "The XFF deployment hasn't been defined, falling back to reverse proxy deployment");
- }
- else if (strcasecmp(xff_deployment, "reverse") != 0) {
- SCLogWarning(SC_WARN_XFF_INVALID_DEPLOYMENT, "The XFF mode %s is invalid, falling back to reverse proxy deployment",
- xff_deployment);
- }
- result->flags |= XFF_REVERSE;
- }
-
- const char *xff_header = ConfNodeLookupChildValue(xff_node, "header");
-
- if (xff_header != NULL) {
- result->header = (char *) xff_header;
- } else {
- SCLogWarning(SC_WARN_XFF_INVALID_HEADER, "The XFF header hasn't been defined, using the default %s",
- XFF_DEFAULT);
- result->header = XFF_DEFAULT;
- }
- }
- else {
- result->flags = XFF_DISABLED;
- }
-}
-
-
-#ifdef UNITTESTS
-static int XFFTest01(void) {
- char input[] = "1.2.3.4:5678";
- char output[16];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 1 && strcmp(output, "1.2.3.4") == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest02(void) {
- char input[] = "[12::34]:1234"; // thanks chort!
- char output[16];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 1 && strcmp(output, "12::34") == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest03(void) {
- char input[] = "[2a03:2880:1010:3f02:face:b00c:0:2]:80"; // thanks chort!
- char output[46];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 1 && strcmp(output, "2a03:2880:1010:3f02:face:b00c:0:2") == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest04(void) {
- char input[] = "[2a03:2880:1010:3f02:face:b00c:0:2]"; // thanks chort!
- char output[46];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 1 && strcmp(output, "2a03:2880:1010:3f02:face:b00c:0:2") == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest05(void) {
- char input[] = "[::ffff:1.2.3.4]:1234"; // thanks double-p
- char output[46];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 1 && strcmp(output, "::ffff:1.2.3.4") == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest06(void) {
- char input[] = "12::34";
- char output[46];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 1 && strcmp(output, "12::34") == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest07(void) {
- char input[] = "1.2.3.4";
- char output[46];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 1 && strcmp(output, "1.2.3.4") == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest08(void) {
- char input[] = "[1.2.3.4:1234";
- char output[46];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 0) {
- return 1;
- }
- return 0;
-}
-
-static int XFFTest09(void) {
- char input[] = "999.999.999.999:1234";
- char output[46];
- int r = ParseXFFString(input, output, sizeof(output));
- if (r == 0) {
- return 1;
- }
- return 0;
-}
-
-#endif
-
-void HTPXFFParserRegisterTests(void)
-{
-#ifdef UNITTESTS
- UtRegisterTest("XFFTest01", XFFTest01, 1);
- UtRegisterTest("XFFTest02", XFFTest02, 1);
- UtRegisterTest("XFFTest03", XFFTest03, 1);
- UtRegisterTest("XFFTest04", XFFTest04, 1);
- UtRegisterTest("XFFTest05", XFFTest05, 1);
- UtRegisterTest("XFFTest06", XFFTest06, 1);
- UtRegisterTest("XFFTest07", XFFTest07, 1);
- UtRegisterTest("XFFTest08", XFFTest08, 1);
- UtRegisterTest("XFFTest09", XFFTest09, 1);
-#endif
-}