From 890b3c0497ddf4f143c8cb3479c16abb4d4fb9ce Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Sun, 6 Sep 2015 10:44:59 +0300 Subject: [PATCH] New DisallowSourceCall config option to drop packets from additional source callsigns (glob match) --- src/cfgfile.c | 24 ++++++++++++++++++++++++ src/cfgfile.h | 1 + src/config.c | 29 +++++++++++++++++++++++++++++ src/config.h | 3 +++ src/incoming.c | 29 +++++++++++++++++++++++++++-- tests/cfg-aprsc/basic | 4 ++++ tests/t/11misc-drops.t | 6 ++++++ 7 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/cfgfile.c b/src/cfgfile.c index 1a15c5f..66ceea5 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -61,6 +61,30 @@ int do_string(char **dest, int argc, char **argv) return 0; } +int do_string_array(char ***dest, int argc, char **argv) +{ + int i, n; + char **vars; + + if (argc < 2) + return -1; + + if (*dest) // TODO free the actual referenced strings + hfree(*dest); + + n = argc - 1; + + vars = hmalloc(sizeof(char *) * (n+1)); + for (i = 0; i < n; i++) + vars[i] = hstrdup(argv[i + 1]); + + vars[i] = NULL; + + *dest = vars; + + return 0; +} + int do_int(int *dest, int argc, char **argv) { if (argc < 2) diff --git a/src/cfgfile.h b/src/cfgfile.h index ff9a7b9..64778b6 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -25,6 +25,7 @@ extern char *argstr(int arg, int argc, char **argv); extern int read_cfgfile(char *f, struct cfgcmd *cmds); extern int do_string(char **dest, int argc, char **argv); +extern int do_string_array(char ***dest, int argc, char **argv); extern int do_int(int *dest, int argc, char **argv); extern int do_boolean(int *dest, int argc, char **argv); diff --git a/src/config.c b/src/config.c index 7f28098..6532c76 100644 --- a/src/config.c +++ b/src/config.c @@ -61,6 +61,9 @@ char *new_myemail; char *new_myadmin; char *new_fake_version; +char **disallow_srccall_glob, **new_disallow_srccall_glob; +char **disallow_login_glob, **new_disallow_login_glob; + int listen_low_ports = 0; /* do we have any < 1024 ports set? need POSIX capabilities? */ struct sockaddr_in uplink_bind_v4; @@ -175,6 +178,8 @@ static struct cfgcmd cfg_cmds[] = { { "disallow_unverified",_CFUNC_ do_boolean, &disallow_unverified }, { "quirks_mode", _CFUNC_ do_boolean, &quirks_mode }, { "fake_version", _CFUNC_ do_string, &new_fake_version }, + { "disallowlogincall", _CFUNC_ do_string_array, &new_disallow_login_glob }, + { "disallowsourcecall", _CFUNC_ do_string_array, &new_disallow_srccall_glob }, { NULL, NULL, NULL } }; @@ -1361,6 +1366,30 @@ int read_config(void) hfree(o); } + if (new_disallow_srccall_glob) { + char **o = disallow_srccall_glob; + disallow_srccall_glob = new_disallow_srccall_glob; + new_disallow_srccall_glob = NULL; + if (o) + hfree(o); + } else { + char **o = disallow_srccall_glob; + disallow_srccall_glob = NULL; + hfree(o); + } + + if (new_disallow_login_glob) { + char **o = disallow_login_glob; + disallow_login_glob = new_disallow_login_glob; + new_disallow_login_glob = NULL; + if (o) + hfree(o); + } else { + char **o = disallow_login_glob; + disallow_login_glob = NULL; + hfree(o); + } + /* validate uplink config: if there is a single 'multiro' connection * configured, all of the uplinks must be 'multiro' */ diff --git a/src/config.h b/src/config.h index c9469d9..72b4541 100644 --- a/src/config.h +++ b/src/config.h @@ -104,6 +104,9 @@ extern char *myadmin; extern char *http_status_options; extern char *fake_version; +extern char **disallow_srccall_glob; +extern char **disallow_login_glob; + extern char def_cfgfile[]; extern char *cfgfile; extern char *pidfile; diff --git a/src/incoming.c b/src/incoming.c index bc2b4ed..aaa763a 100644 --- a/src/incoming.c +++ b/src/incoming.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef HAVE_ALLOCA_H #include @@ -86,7 +87,7 @@ const char *inerr_labels[] = { /* a static list of source callsigns which are dropped */ -static const char *disallow_srccalls[] = { +static char *disallow_srccalls[] = { "N0CALL", /* default in some apps */ "NOCALL", /* default in some apps */ "SERVER", /* originated by APRS-IS server */ @@ -551,7 +552,7 @@ int check_call_match(const char **set, const char *call, int len) return 0; } -static int check_call_prefix_match(const char **set, const char *call, int len) +static int check_call_prefix_match(char **set, const char *call, int len) { int i, l; @@ -564,6 +565,27 @@ static int check_call_prefix_match(const char **set, const char *call, int len) return 0; } +#define MAX_TEST_CALL_LEN 32 +static int check_call_glob_match(char **set, const char *call, int len) +{ + int i; + char ts[MAX_TEST_CALL_LEN+1]; + + if (len > MAX_TEST_CALL_LEN) + return 0; /* no match */ + + /* glob match requires having a null-terminated string */ + memcpy(ts, call, len); + ts[len] = 0; + + for (i = 0; (set[i]); i++) { + if (fnmatch(set[i], ts, FNM_CASEFOLD) == 0) + return -1; + } + + return 0; +} + /* * Check if a callsign is good for a digi path entry * (valid APRS-IS callsign, * allowed in end) @@ -854,6 +876,9 @@ int incoming_parse(struct worker_t *self, struct client_t *c, char *s, int len) if (check_call_prefix_match(disallow_srccalls, s, src_len)) return INERR_DIS_SRCCALL; /* disallowed srccall */ + if (disallow_srccall_glob && check_call_glob_match(disallow_srccall_glob, s, src_len)) + return INERR_DIS_SRCCALL; /* disallowed srccall */ + info_start = path_end+1; // @":"+1 - first char of the payload if (info_start >= packet_end) return INERR_NO_BODY; diff --git a/tests/cfg-aprsc/basic b/tests/cfg-aprsc/basic index e75e79d..8684dd1 100644 --- a/tests/cfg-aprsc/basic +++ b/tests/cfg-aprsc/basic @@ -84,3 +84,7 @@ WorkerThreads 3 # FileLimit 10000 +# Additional callsigns blocked +DisallowSourceCall N7CALL N8CALL *DROP DRG* OH?DRU O*ZZZ +DisallowLoginCall LOGINB LOGINC + diff --git a/tests/t/11misc-drops.t b/tests/t/11misc-drops.t index eee06fe..648f066 100644 --- a/tests/t/11misc-drops.t +++ b/tests/t/11misc-drops.t @@ -86,6 +86,12 @@ my @pkts = ( "NOCALL>DST,DIGI,qAR,$login:>should drop, NOCALL as source callsign", "NOCALL-1>DST,DIGI,qAR,$login:>should drop, N0CALL-1 as source callsign", "SERVER>DST,DIGI,qAR,$login:>should drop, SERVER as source callsign", + # additionally configured disallowed source callsigns: N7CALL N8CALL + "N7CALL>DST,DIGI,qAR,$login:>should drop, N7CALL as source callsign", + "N8CALL>DST,DIGI,qAR,$login:>should drop, N8CALL as source callsign", + "GLDROP>DST,DIGI,qAR,$login:>should drop, GLDROP as source callsign matches *DROP", + "DRGLOB>DST,DIGI,qAR,$login:>should drop, DRGLOB as source callsign matches DRG*", + "OH7DRU>DST,DIGI,qAR,$login:>should drop, OH7DRU as source callsign matches OH?DRUP", # DX spots "SRC>DST,DIGI,qAR,$login:DX de FOO: BAR - should drop", # Disallowed message recipients, status messages and such