]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Allow detection ports for alproto to be specified via the conf file.
authorAnoop Saldanha <anoopsaldanha@gmail.com>
Sat, 3 Aug 2013 09:23:13 +0000 (14:53 +0530)
committerAnoop Saldanha <anoopsaldanha@gmail.com>
Sun, 29 Sep 2013 17:43:07 +0000 (23:13 +0530)
To understand the option have a look at the option

app-layer.protocols.tls.detection-ports

src/app-layer-dns-tcp.c
src/app-layer-dns-udp.c
src/app-layer-parser.c
src/app-layer-parser.h
src/app-layer-protos.c
src/app-layer-protos.h
src/app-layer-smb.c
src/app-layer-ssl.c
src/detect-dns-query.c
src/detect-engine-proto.c
suricata.yaml.in

index a098f75f14c92d7c78ed686c0aefe3fd9120a39a..b8f60726352f883c3d3e2be09cabf5b22c26cc21 100644 (file)
@@ -579,14 +579,20 @@ void RegisterDNSTCPParsers(void) {
 
     /** DNS */
     if (AppLayerProtoDetectionEnabled(proto_name)) {
-        AppLayerRegisterProbingParser(&alp_proto_ctx,
-                                      IPPROTO_TCP,
-                                      "53",
-                                      proto_name,
-                                      ALPROTO_DNS_TCP,
-                                      0, sizeof(DNSTcpHeader),
-                                      STREAM_TOSERVER,
-                                      DNSTcpProbingParser);
+        if (RunmodeIsUnittests()) {
+            AppLayerRegisterProbingParser(&alp_proto_ctx,
+                                          IPPROTO_TCP,
+                                          "53",
+                                          proto_name,
+                                          ALPROTO_DNS_TCP,
+                                          0, sizeof(DNSTcpHeader),
+                                          STREAM_TOSERVER,
+                                          DNSTcpProbingParser);
+        } else {
+            AppLayerParseProbingParserPorts(proto_name, ALPROTO_DNS_TCP,
+                                            0, sizeof(DNSTcpHeader),
+                                            DNSTcpProbingParser);
+        }
     } else {
         SCLogInfo("Protocol detection and parser disabled for %s protocol.",
                   proto_name);
index 9857b26f1dce698c3f09c5869c6b0ae381a35d7b..91354c10ab87cfb6ec02e4a39f5d253e921ad439 100644 (file)
@@ -299,14 +299,20 @@ void RegisterDNSUDPParsers(void) {
 
     /** DNS */
     if (AppLayerProtoDetectionEnabled(proto_name)) {
-        AppLayerRegisterProbingParser(&alp_proto_ctx,
-                                      IPPROTO_UDP,
-                                      "53",
-                                      proto_name,
-                                      ALPROTO_DNS_UDP,
-                                      0, sizeof(DNSHeader),
-                                      STREAM_TOSERVER,
-                                      DNSUdpProbingParser);
+        if (RunmodeIsUnittests()) {
+            AppLayerRegisterProbingParser(&alp_proto_ctx,
+                                          IPPROTO_UDP,
+                                          "53",
+                                          proto_name,
+                                          ALPROTO_DNS_UDP,
+                                          0, sizeof(DNSHeader),
+                                          STREAM_TOSERVER,
+                                          DNSUdpProbingParser);
+        } else {
+            AppLayerParseProbingParserPorts(proto_name, ALPROTO_DNS_UDP,
+                                        0, sizeof(DNSHeader),
+                                        DNSUdpProbingParser);
+        }
     } else {
         SCLogInfo("Protocol detection and parser disabled for %s protocol.",
                   proto_name);
index f2a9710d512c6695adace6cc1a2246fe819d62e7..2360e59ea6194792a2737f32ed0ebd1f7e4c26b3 100644 (file)
@@ -1630,6 +1630,92 @@ int AppLayerProtoDetectionEnabled(const char *al_proto)
     return enabled;
 }
 
+void AppLayerParseProbingParserPorts(const char *al_proto_name, uint16_t al_proto,
+                                     uint16_t min_depth, uint16_t max_depth,
+                                     uint16_t (*ProbingParser)(uint8_t *input,
+                                                               uint32_t input_len,
+                                                               uint32_t *offset))
+{
+    char param[100];
+    int r;
+    ConfNode *node;
+    ConfNode *proto_node = NULL;
+    ConfNode *port_node = NULL;
+
+    r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.",
+                 al_proto_name, ".detection-ports");
+    if (r < 0) {
+        SCLogError(SC_ERR_FATAL, "snprintf failure.");
+        exit(EXIT_FAILURE);
+    } else if (r > (int)sizeof(param)) {
+        SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
+        exit(EXIT_FAILURE);
+    }
+    node = ConfGetNode(param);
+    if (node == NULL) {
+        SCLogDebug("Entry for %s not found.", param);
+        return;
+    }
+
+    /* for each proto */
+    TAILQ_FOREACH(proto_node, &node->head, next) {
+        DetectProto dp;
+        int ip_proto = DetectProtoParse(&dp, proto_node->name);
+        if (ip_proto <= 0) {
+            SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for "
+                       "%s.%s", param, proto_node->name);
+            exit(EXIT_FAILURE);
+        }
+
+        /* toserver */
+        r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.",
+                     al_proto_name, ".detection-ports.", proto_node->name, ".toserver");
+        if (r < 0) {
+            SCLogError(SC_ERR_FATAL, "snprintf failure.");
+            exit(EXIT_FAILURE);
+        } else if (r > (int)sizeof(param)) {
+            SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
+            exit(EXIT_FAILURE);
+        }
+        port_node = ConfGetNode(param);
+        if (port_node != NULL && port_node->val != NULL) {
+            AppLayerRegisterProbingParser(&alp_proto_ctx,
+                                          ip_proto,
+                                          port_node->val,
+                                          (char *)al_proto_name,
+                                          al_proto,
+                                          min_depth, max_depth,
+                                          STREAM_TOSERVER,
+                                          ProbingParser);
+        }
+
+        /* toclient */
+        r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.",
+                     al_proto_name, ".detection-ports.", proto_node->name, ".toclient");
+        if (r < 0) {
+            SCLogError(SC_ERR_FATAL, "snprintf failure.");
+            exit(EXIT_FAILURE);
+        } else if (r > (int)sizeof(param)) {
+            SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
+            exit(EXIT_FAILURE);
+        }
+        port_node = ConfGetNode(param);
+        if (port_node != NULL && port_node->val != NULL) {
+            AppLayerRegisterProbingParser(&alp_proto_ctx,
+                                          ip_proto,
+                                          port_node->val,
+                                          (char *)al_proto_name,
+                                          al_proto,
+                                          min_depth, max_depth,
+                                          STREAM_TOCLIENT,
+                                          ProbingParser);
+
+        }
+    }
+
+    return;
+}
+
 /********************************Probing Parsers*******************************/
 
 
index 814746d02cfa6210e3f27206b320fc19c130daad..6b16e67c2ba84cdb28918a2a450aeeecf6a8809d 100644 (file)
@@ -418,5 +418,8 @@ void AppLayerTriggerRawStreamReassembly(Flow *);
 
 int AppLayerParserEnabled(const char *alproto);
 int AppLayerProtoDetectionEnabled(const char *alproto);
+void AppLayerParseProbingParserPorts(const char *al_proto_name, uint16_t al_proto,
+                                     uint16_t min_depth, uint16_t max_depth,
+                                     uint16_t (*ProbingParser)(uint8_t *input, uint32_t input_len, uint32_t *offset));
 
 #endif /* __APP_LAYER_PARSER_H__ */
index bbeb103a864fcda9de2ed647a4abb66a6ae4fc20..37e3b3499956b540b135296cd8996a30bce1082d 100644 (file)
  *
  * \retval string equivalent for the alproto
  */
-const char *TmModuleAlprotoToString(int proto)
+const char *TmModuleAlprotoToString(enum AppProto proto)
 {
-    switch (proto) {
-        CASE_CODE (ALPROTO_UNKNOWN);
-        CASE_CODE (ALPROTO_HTTP);
-        CASE_CODE (ALPROTO_FTP);
-        CASE_CODE (ALPROTO_SMTP);
-        CASE_CODE (ALPROTO_TLS);
-        CASE_CODE (ALPROTO_SSH);
-        CASE_CODE (ALPROTO_IMAP);
-        CASE_CODE (ALPROTO_MSN);
-        CASE_CODE (ALPROTO_JABBER);
-        CASE_CODE (ALPROTO_SMB);
-        CASE_CODE (ALPROTO_SMB2);
-        CASE_CODE (ALPROTO_DCERPC);
-        CASE_CODE (ALPROTO_DCERPC_UDP);
-
-        CASE_CODE (ALPROTO_DNS);
-        CASE_CODE (ALPROTO_DNS_UDP);
-        CASE_CODE (ALPROTO_DNS_TCP);
+    const char *proto_name = NULL;
 
-        default:
-            return "ALPROTO_UNDEFINED";
+    switch (proto) {
+        case ALPROTO_HTTP:
+            proto_name = "http";
+            break;
+        case ALPROTO_FTP:
+            proto_name = "ftp";
+            break;
+        case ALPROTO_SMTP:
+            proto_name = "smtp";
+            break;
+        case ALPROTO_TLS:
+            proto_name = "tls";
+            break;
+        case ALPROTO_SSH:
+            proto_name = "ssh";
+            break;
+        case ALPROTO_IMAP:
+            proto_name = "imap";
+            break;
+        case ALPROTO_MSN:
+            proto_name = "msn";
+            break;
+        case ALPROTO_JABBER:
+            proto_name = "jabber";
+            break;
+        case ALPROTO_SMB:
+            proto_name = "smb";
+            break;
+        case ALPROTO_SMB2:
+            proto_name = "smb2";
+            break;
+        case ALPROTO_DCERPC:
+            proto_name = "dcerpc";
+            break;
+        case ALPROTO_DCERPC_UDP:
+            proto_name = "dcerpcudp";
+            break;
+        case ALPROTO_IRC:
+            proto_name = "irc";
+            break;
+        case ALPROTO_DNS_TCP:
+            proto_name = "dnstcp";
+            break;
+        case ALPROTO_DNS_UDP:
+            proto_name = "dnsudp";
+            break;
+        case ALPROTO_DNS:
+        case ALPROTO_FAILED:
+        case ALPROTO_TEST:
+        case ALPROTO_MAX:
+        case ALPROTO_UNKNOWN:
+            break;
     }
+
+    return proto_name;
 }
 
index 8c1c93154fce6c387ba437d9ac5230d081d76b34..409d8814e5ad0a07a2997200b213ee8270099c6d 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __APP_LAYER_PROTOS_H__
 #define __APP_LAYER_PROTOS_H__
 
-enum {
+enum AppProto {
     ALPROTO_UNKNOWN = 0,
     ALPROTO_HTTP,
     ALPROTO_FTP,
@@ -54,7 +54,7 @@ enum {
     ALPROTO_MAX,
 };
 
-const char *TmModuleAlprotoToString(int proto);
+const char *TmModuleAlprotoToString(enum AppProto proto);
 
 #endif /* __APP_LAYER_PROTOS_H__ */
 
index 8bcf12a155caae2cae72e440bbd24522903a51ce..7b9989ab7caf067b92bfda2e708b542c97d40be5 100644 (file)
@@ -1406,14 +1406,20 @@ void RegisterSMBParsers(void) {
         /** SMB2 */
         AlpProtoAdd(&alp_proto_ctx, "smb2", IPPROTO_TCP, ALPROTO_SMB2, "|fe|SMB", 8, 4, STREAM_TOSERVER);
 
-        AppLayerRegisterProbingParser(&alp_proto_ctx,
-                                      IPPROTO_TCP,
-                                      "139",
-                                      "smb",
-                                      ALPROTO_SMB,
-                                      SMB_PROBING_PARSER_MIN_DEPTH, 0,
-                                      STREAM_TOSERVER,
-                                      SMBProbingParser);
+        if (RunmodeIsUnittests()) {
+            AppLayerRegisterProbingParser(&alp_proto_ctx,
+                                          IPPROTO_TCP,
+                                          "139",
+                                          "smb",
+                                          ALPROTO_SMB,
+                                          SMB_PROBING_PARSER_MIN_DEPTH, 0,
+                                          STREAM_TOSERVER,
+                                          SMBProbingParser);
+        } else {
+            AppLayerParseProbingParserPorts(proto_name, ALPROTO_SMB,
+                                            SMB_PROBING_PARSER_MIN_DEPTH, 0,
+                                            SMBProbingParser);
+        }
     } else {
         SCLogInfo("Protocol detection and parser disabled for %s protocol.",
                   proto_name);
index 8771bab46db5f1a8a0d7a18fc66cac123dee2b09..0a782611f221756233d7d34aeac61851edbb1239 100644 (file)
@@ -1016,14 +1016,20 @@ void RegisterSSLParsers(void)
         AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|01 03 03|", 3, 0, STREAM_TOSERVER);
         AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|16 03 03|", 3, 0, STREAM_TOSERVER); /* client hello */
 
-        AppLayerRegisterProbingParser(&alp_proto_ctx,
-                                      IPPROTO_TCP,
-                                      "443",
-                                      proto_name,
-                                      ALPROTO_TLS,
-                                      0, 3,
-                                      STREAM_TOSERVER,
-                                      SSLProbingParser);
+        if (RunmodeIsUnittests()) {
+            AppLayerRegisterProbingParser(&alp_proto_ctx,
+                                          IPPROTO_TCP,
+                                          "443",
+                                          proto_name,
+                                          ALPROTO_TLS,
+                                          0, 3,
+                                          STREAM_TOSERVER,
+                                          SSLProbingParser);
+        } else {
+            AppLayerParseProbingParserPorts(proto_name, ALPROTO_TLS,
+                                            0, 3,
+                                            SSLProbingParser);
+        }
     } else {
         SCLogInfo("Protocol detection and parser disabled for %s protocol",
                   proto_name);
index 69d9237b67005ead338b5b77b3991bbf5a1e204f..398fa159e306b8fce0dccf6f7b6d374398429a47 100644 (file)
@@ -148,7 +148,9 @@ static int DetectDnsQueryTest01(void) {
     memset(&tv, 0, sizeof(ThreadVars));
     memset(&f, 0, sizeof(Flow));
 
-    p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_UDP);
+    p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
 
     FLOW_INITIALIZE(&f);
     f.flags |= FLOW_IPV4;
@@ -256,9 +258,15 @@ static int DetectDnsQueryTest02(void) {
     memset(&tv, 0, sizeof(ThreadVars));
     memset(&f, 0, sizeof(Flow));
 
-    p1 = UTHBuildPacket(buf1, sizeof(buf1), IPPROTO_UDP);
-    p2 = UTHBuildPacket(buf2, sizeof(buf2), IPPROTO_UDP);
-    p3 = UTHBuildPacket(buf3, sizeof(buf3), IPPROTO_UDP);
+    p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
+    p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
+    p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
 
     FLOW_INITIALIZE(&f);
     f.flags |= FLOW_IPV4;
@@ -411,7 +419,9 @@ static int DetectDnsQueryTest03(void) {
     memset(&f, 0, sizeof(Flow));
     memset(&ssn, 0, sizeof(TcpSession));
 
-    p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_TCP);
+    p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
 
     FLOW_INITIALIZE(&f);
     f.protoctx = (void *)&ssn;
@@ -503,8 +513,12 @@ static int DetectDnsQueryTest04(void) {
     memset(&f, 0, sizeof(Flow));
     memset(&ssn, 0, sizeof(TcpSession));
 
-    p1 = UTHBuildPacket(buf1, sizeof(buf1), IPPROTO_TCP);
-    p2 = UTHBuildPacket(buf2, sizeof(buf2), IPPROTO_TCP);
+    p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
+    p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
 
     FLOW_INITIALIZE(&f);
     f.protoctx = (void *)&ssn;
@@ -644,10 +658,18 @@ static int DetectDnsQueryTest05(void) {
     memset(&f, 0, sizeof(Flow));
     memset(&ssn, 0, sizeof(TcpSession));
 
-    p1 = UTHBuildPacket(buf1, sizeof(buf1), IPPROTO_TCP);
-    p2 = UTHBuildPacket(buf2, sizeof(buf2), IPPROTO_TCP);
-    p3 = UTHBuildPacket(buf3, sizeof(buf3), IPPROTO_TCP);
-    p4 = UTHBuildPacket(buf4, sizeof(buf4), IPPROTO_TCP);
+    p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
+                            "192.168.1.5", "192.168.1.1",
+                            41424, 53);
+    p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
+                            "192.168.1.5", "192.168.1.1",
+                            41424, 53);
+    p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_TCP,
+                            "192.168.1.5", "192.168.1.1",
+                            41424, 53);
+    p4 = UTHBuildPacketReal(buf4, sizeof(buf4), IPPROTO_TCP,
+                            "192.168.1.5", "192.168.1.1",
+                            41424, 53);
 
     FLOW_INITIALIZE(&f);
     f.protoctx = (void *)&ssn;
@@ -824,7 +846,9 @@ static int DetectDnsQueryTest06(void) {
     memset(&tv, 0, sizeof(ThreadVars));
     memset(&f, 0, sizeof(Flow));
 
-    p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_UDP);
+    p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
+                           "192.168.1.5", "192.168.1.1",
+                           41424, 53);
 
     FLOW_INITIALIZE(&f);
     f.flags |= FLOW_IPV4;
@@ -946,9 +970,15 @@ static int DetectDnsQueryTest07(void) {
     memset(&tv, 0, sizeof(ThreadVars));
     memset(&f, 0, sizeof(Flow));
 
-    p1 = UTHBuildPacket(buf1, sizeof(buf1), IPPROTO_UDP);
-    p2 = UTHBuildPacket(buf2, sizeof(buf2), IPPROTO_UDP);
-    p3 = UTHBuildPacket(buf3, sizeof(buf3), IPPROTO_UDP);
+    p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
+                            "192.168.1.5", "192.168.1.1",
+                            41424, 53);
+    p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_UDP,
+                            "192.168.1.5", "192.168.1.1",
+                            41424, 53);
+    p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_UDP,
+                            "192.168.1.5", "192.168.1.1",
+                            41424, 53);
 
     FLOW_INITIALIZE(&f);
     f.flags |= FLOW_IPV4;
index 7994e486e6f4e2d9f770e0f9c8183750ed1c51de..14b89ee4f15845b823a19b632edd494dc6029914 100644 (file)
@@ -154,7 +154,7 @@ int DetectProtoParse(DetectProto *dp, char *str)
         }
 #endif
     }
-    return 0;
+    return proto;
 
 error:
     return -1;
@@ -213,7 +213,7 @@ static int DetectProtoInitTest(DetectEngineCtx **de_ctx, Signature **sig,
 
     *sig = (*de_ctx)->sig_list;
 
-    if (DetectProtoParse(dp, str) != 0)
+    if (DetectProtoParse(dp, str) < 0)
         goto end;
 
     result = 1;
@@ -232,7 +232,7 @@ static int ProtoTestParse01 (void)
     memset(&dp,0,sizeof(DetectProto));
 
     int r = DetectProtoParse(&dp, "6");
-    if (r != 0) {
+    if (r < 0) {
         return 1;
     }
 
@@ -249,7 +249,7 @@ static int ProtoTestParse02 (void)
     memset(&dp,0,sizeof(DetectProto));
 
     int r = DetectProtoParse(&dp, "tcp");
-    if (r == 0 && dp.proto[(IPPROTO_TCP/8)] & (1<<(IPPROTO_TCP%8))) {
+    if (r >= 0 && dp.proto[(IPPROTO_TCP/8)] & (1<<(IPPROTO_TCP%8))) {
         return 1;
     }
 
@@ -266,7 +266,7 @@ static int ProtoTestParse03 (void)
     memset(&dp,0,sizeof(DetectProto));
 
     int r = DetectProtoParse(&dp, "ip");
-    if (r == 0 && dp.flags & DETECT_PROTO_ANY) {
+    if (r >= 0 && dp.flags & DETECT_PROTO_ANY) {
         return 1;
     }
 
@@ -285,7 +285,7 @@ static int ProtoTestParse04 (void)
 
     /* Check for a bad number */
     int r = DetectProtoParse(&dp, "4242");
-    if (r == -1) {
+    if (r < 0) {
         return 1;
     }
 
@@ -304,7 +304,7 @@ static int ProtoTestParse05 (void)
 
     /* Check for a bad string */
     int r = DetectProtoParse(&dp, "tcp/udp");
-    if (r == -1) {
+    if (r < 0) {
         return 1;
     }
 
@@ -322,7 +322,7 @@ static int ProtoTestParse06 (void)
 
     /* Check for a bad string */
     int r = DetectProtoParse(&dp, "tcp-pkt");
-    if (r == -1) {
+    if (r < -1) {
         printf("parsing tcp-pkt failed: ");
         return 0;
     }
@@ -345,7 +345,7 @@ static int ProtoTestParse07 (void)
 
     /* Check for a bad string */
     int r = DetectProtoParse(&dp, "tcp-stream");
-    if (r == -1) {
+    if (r < -1) {
         printf("parsing tcp-stream failed: ");
         return 0;
     }
index 3b31465c9949ed3c88a8f448a44ba239cd62d8cc..af24486c25b7219f404472a54511945d9b974251 100644 (file)
@@ -989,6 +989,9 @@ app-layer:
   protocols:
     tls:
       enabled: yes
+      detection-ports:
+        tcp:
+          toserver: 443
 
       #no-reassemble: yes
     dcerpc:
@@ -1005,9 +1008,22 @@ app-layer:
       enabled: detection-only
     smb:
       enabled: yes
+      detection-ports:
+        tcp:
+          toserver: 139
     # smb2 detection is disabled internally inside the engine.
     #smb2:
     #  enabled: yes
+    dnstcp:
+       enabled: yes
+       detection-ports:
+         tcp:
+           toserver: 53
+    dnsudp:
+       enabled: yes
+       detection-ports:
+         udp:
+           toserver: 53
     http:
       enabled: yes