From 8875cfb8fdf0162623f2bda96d8063077fa0aef1 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Sun, 6 Sep 2015 11:51:36 +0300 Subject: [PATCH] New config option DisallowLoginCall to reject logins by glob match --- src/incoming.c | 2 +- src/incoming.h | 1 + src/login.c | 17 ++++++++++++++++- tests/cfg-aprsc/basic | 2 +- tests/libperl/Ham/APRS/IS.pm | 6 +++++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/incoming.c b/src/incoming.c index aaa763a..1afd893 100644 --- a/src/incoming.c +++ b/src/incoming.c @@ -566,7 +566,7 @@ static int check_call_prefix_match(char **set, const char *call, int len) } #define MAX_TEST_CALL_LEN 32 -static int check_call_glob_match(char **set, const char *call, int len) +int check_call_glob_match(char **set, const char *call, int len) { int i; char ts[MAX_TEST_CALL_LEN+1]; diff --git a/src/incoming.h b/src/incoming.h index 24dab96..f43828b 100644 --- a/src/incoming.h +++ b/src/incoming.h @@ -18,6 +18,7 @@ extern const char *inerr_labels[]; extern int check_invalid_src_dst(const char *call, int len); extern int check_call_match(const char **set, const char *call, int len); +extern int check_call_glob_match(char **set, const char *call, int len); extern int check_path_calls(const char *via_start, const char *path_end); extern void incoming_flush(struct worker_t *self); diff --git a/src/login.c b/src/login.c index 8021959..70b007b 100644 --- a/src/login.c +++ b/src/login.c @@ -45,6 +45,8 @@ static const char *quirks_mode_blacklist[] = { /* * Parse the login string in a HTTP POST or UDP submit packet * Argh, why are these not in standard POST parameters in HTTP? + * + * TODO: Used for UDP too, so should not say HTTP in log errors... */ int http_udp_upload_login(const char *addr_rem, char *s, char **username) @@ -84,6 +86,12 @@ int http_udp_upload_login(const char *addr_rem, char *s, char **username) } } + /* check the username against a dynamic list of disallowed usernames */ + if (disallow_login_glob && check_call_glob_match(disallow_login_glob, *username, username_len)) { + hlog(LOG_WARNING, "%s: HTTP POST: Login by user '%s' not allowed due to config", addr_rem, *username); + return -1; + } + /* make sure the callsign is OK on the APRS-IS */ if (check_invalid_q_callsign(*username, username_len)) { hlog(LOG_WARNING, "%s: HTTP POST: Invalid login string, invalid 'user': '%s'", addr_rem, *username); @@ -254,10 +262,17 @@ int login_handler(struct worker_t *self, struct client_t *c, int l4proto, char * } } + /* check the username against a dynamic list of disallowed usernames */ + if (disallow_login_glob && check_call_glob_match(disallow_login_glob, c->username, c->username_len)) { + hlog(LOG_WARNING, "%s: Login by user '%s' not allowed due to config", c->addr_rem, c->username); + rc = client_printf(self, c, "# Login by user not allowed\r\n"); + goto failed_login; + } + /* make sure the callsign is OK on the APRS-IS */ if (check_invalid_q_callsign(c->username, c->username_len)) { hlog(LOG_WARNING, "%s: Invalid login string, invalid 'user': '%s'", c->addr_rem, c->username); - rc = client_printf(self, c, "# Invalid username format\r\n"); + rc = client_printf(self, c, "# Invalid username format, not allowed\r\n"); goto failed_login; } diff --git a/tests/cfg-aprsc/basic b/tests/cfg-aprsc/basic index 71cb2fe..b447fbe 100644 --- a/tests/cfg-aprsc/basic +++ b/tests/cfg-aprsc/basic @@ -86,5 +86,5 @@ FileLimit 10000 # Additional callsigns blocked DisallowSourceCall N7CALL N8CALL* *DROP DRG* OH?DRU O*ZZZ -DisallowLoginCall LOGINB LOGINC +DisallowLoginCall LOGINA LOGINB *prrej mi*rej sufre* diff --git a/tests/libperl/Ham/APRS/IS.pm b/tests/libperl/Ham/APRS/IS.pm index 7a9b0b1..d43c77f 100644 --- a/tests/libperl/Ham/APRS/IS.pm +++ b/tests/libperl/Ham/APRS/IS.pm @@ -196,13 +196,17 @@ sub connect($;%) while (my $l = $self->getline()) { #warn "login got: $l\n"; return 1 if ($l =~ /^#\s+logresp\s+/); + if ($l =~ /^#\s+(.*)(not allowed|invalid)(.*)/i) { + $self->{'error'} = "Login rejected: $1$2$3"; + return 0; + } if (time() - $t > 5) { $self->{'error'} = "Login command timed out"; return 0; } } - return 1; + return 0; } =head1 connected()