From fca8f208e96d7cc0ad44d64b5ebd37042954df3f Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 9 Apr 2013 18:33:12 +0300 Subject: [PATCH] Drop incoming packets with -0 SSIDs in callsigns. Speedup in callsign checking (array reference instead of pointer math and referencing) and stricter callsign syntax checks. --- src/incoming.c | 104 +++++++++++++++++++++++++---------------- tests/t/11misc-drops.t | 5 ++ 2 files changed, 70 insertions(+), 39 deletions(-) diff --git a/src/incoming.c b/src/incoming.c index cc450e8..addb097 100644 --- a/src/incoming.c +++ b/src/incoming.c @@ -510,20 +510,41 @@ static int digi_path_drop(char *via_start, char *path_end) int check_invalid_src_dst(const char *call, int len) { - const char *p = call; - const char *e = call + len; - //hlog(LOG_DEBUG, "check_invalid_src_dst: '%.*s'", len, call); if (len < 1 || len > CALLSIGNLEN_MAX) return -1; - while (p < e) { - /* alphanumeric and - */ - if ((!isalnum(*p)) && *p != '-') + int i = 0; + + /* go through callsign body */ + while (i < len && call[i] != '-') { + /* alphanumeric */ + if (!isalnum(call[i])) return -1; - - p++; + + i++; + } + + /* we're at end? */ + if (i == len) + return 0; + + /* We have an SSID. */ + i++; + + /* Check SSID length to be between 1 and 2 */ + if (len - i > 2 || len == i) + return -1; + + /* SSID of 0? */ + if (call[i] == '0') + return -1; + + while (i < len) { + if (!isalnum(call[i])) + return -1; + i++; } return 0; @@ -536,43 +557,48 @@ int check_invalid_src_dst(const char *call, int len) static int check_invalid_path_callsign(const char *call, int len, int after_q) { - const char *p = call; - const char *e = call + len; + //hlog(LOG_DEBUG, "check_invalid_src_dst: '%.*s'", len, call); - //hlog_packet(LOG_DEBUG, call, len, "check_invalid_path_callsign: "); + /* allow a '*' in the end, and don't check for it */ + if (len > 1 && call[len-1] == '*') + len--; - /* only check for minimum length first - max length depends on - * if there's a * in the end - */ if (len < 1) return -1; - - while (p < e) { - /* alphanumeric and - */ - /* AND '*' is allowed in the end */ - if ((!isalnum(*p)) && *p != '-' && !(*p == '*' && p == e-1)) { - //hlog(LOG_DEBUG, "check_invalid_path_callsign: invalid char '%c'", *p); - return -1; - } - p++; - } - - if (*(p-1) == '*' && len <= CALLSIGNLEN_MAX+1) { - //hlog(LOG_DEBUG, "check_invalid_path_callsign: allowing len %d due to last *", len); - return 0; - } - - /* too long? */ - if (len > CALLSIGNLEN_MAX) { - // TODO: more specific test for IPv6 trace address - if (after_q && len == 32) { - //hlog_packet(LOG_DEBUG, call, len, "check_invalid_path_callsign: ipv6 address: "); - return 0; - } - - hlog(LOG_DEBUG, "check_invalid_path_callsign: too long len %d", len); + if (len > CALLSIGNLEN_MAX && !(len == 32 && after_q)) return -1; + + int i = 0; + + /* go through callsign body */ + while (i < len && call[i] != '-') { + /* alphanumeric */ + if (!isalnum(call[i])) + return -1; + + i++; + } + + /* we're at end? */ + if (i == len) + return 0; + + /* We have an SSID. */ + i++; + + /* Check SSID length to be between 1 and 2 */ + if (len - i > 2 || len == i) + return -1; + + /* SSID of 0? */ + if (call[i] == '0') + return -1; + + while (i < len) { + if (!isalnum(call[i])) + return -1; + i++; } return 0; diff --git a/tests/t/11misc-drops.t b/tests/t/11misc-drops.t index 51175b0..11a6c45 100644 --- a/tests/t/11misc-drops.t +++ b/tests/t/11misc-drops.t @@ -77,6 +77,11 @@ my @pkts = ( "SRC2>DST,DIGI,qAX,$login:>Packet from unverified login according to qAX", "SRC2>DST,DIGI,TCPXX,qAR,$login:>Packet from unverified login according to TCPXX in path", "SRC2>DST,DIGI,TCPXX*,qAR,$login:>Packet from unverified login according to TCPXX* in path", + "SRC-0>DST,DIGI,qAR,$login:>should drop, -0 SSID in srccall", + "SRC->DST,DIGI-0,qAR,$login:>should drop, too short SSID in srccall", + "SRC-111>DST,DIGI-0,qAR,$login:>should drop, too long SSID in srccall", + "SRC>DST-0,DIGI,qAR,$login:>should drop, -0 SSID in dstcall", + "SRC>DST,DIGI-0,qAR,$login:>should drop, -0 SSID in viacall", ); # send the packets