From 84354c50f807607700b95debdd3a7ddfde0c09f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Tue, 14 Sep 2010 14:59:38 +0300 Subject: authdb: use configuration file to decide blocked categories and cache the information to authdb properly. --- Makefile | 4 +- authdb.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++-- authdb.h | 16 ++++++- squark-auth-ip.c | 9 +++- squark-auth-snmp.c | 10 ++++- squark-filter.c | 59 ++++---------------------- 6 files changed, 157 insertions(+), 63 deletions(-) diff --git a/Makefile b/Makefile index 8536d07..db683a2 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,10 @@ LIBS+=-lrt all: $(TARGETS) -squark-auth-snmp: squark-auth-snmp.o authdb.o blob.o addr.o +squark-auth-snmp: squark-auth-snmp.o filterdb.o authdb.o blob.o addr.o $(CC) -o $@ $^ $(NETSNMP_LIBS) $(LIBS) -squark-auth-ip: squark-auth-ip.o authdb.o blob.o addr.o +squark-auth-ip: squark-auth-ip.o filterdb.o authdb.o blob.o addr.o $(CC) -o $@ $^ $(LIBS) squark-filter: squark-filter.o filterdb.o authdb.o blob.o addr.o diff --git a/authdb.c b/authdb.c index 488932c..830bb94 100644 --- a/authdb.c +++ b/authdb.c @@ -4,9 +4,12 @@ #include #include #include +#include +#include #include #include "authdb.h" +#include "filterdb.h" #include "addr.h" #include "blob.h" @@ -74,10 +77,12 @@ static void authdb_me_free(struct authdb_map_entry *me) free(me); } -int authdb_open(struct authdb *adb) +int authdb_open(struct authdb *adb, struct authdb_config *cfg, struct sqdb *db) { memset(adb, 0, sizeof(*adb)); - return 0; + memset(cfg, 0, sizeof(*cfg)); + cfg->db = db; + return adbc_refresh(cfg, time(NULL)); } void authdb_close(struct authdb *adb) @@ -225,9 +230,10 @@ void authdb_clear_entry(struct authdb_entry *entry) entry->checksum = checksum; } -void authdb_commit_login(void *token, struct authdb_entry *e, time_t now) +void authdb_commit_login(void *token, struct authdb_entry *e, time_t now, struct authdb_config *cfg) { - /* fixme read stuff from config files */ + e->p.block_categories = cfg->block_categories; + e->p.hard_block_categories = cfg->hard_block_categories; e->p.login_time = now; e->last_activity_time = now; e->override_time = 0; @@ -246,3 +252,111 @@ void authdb_commit_override(void *token, struct authdb_entry *e, time_t now) mme->override_time = now; } + +static blob_t read_word(FILE *in, int *lineno, blob_t b) +{ + int ch, i, comment = 0; + blob_t r; + + ch = fgetc(in); + while (1) { + if (ch == EOF) + return BLOB_NULL; + if (ch == '#') + comment = 1; + if (!comment && !isspace(ch)) + break; + if (ch == '\n') { + (*lineno)++; + comment = 0; + } + ch = fgetc(in); + } + + r.ptr = b.ptr; + r.len = 0; + for (i = 0; i < b.len-1 && !isspace(ch); i++, r.len++) { + r.ptr[i] = ch; + ch = fgetc(in); + if (ch == EOF) + break; + if (ch == '\n') + (*lineno)++; + } + + return r; +} + +static int find_category_id(struct sqdb *db, blob_t cat) +{ + uint32_t size, *ptr; + int i; + + ptr = sqdb_section_get(db, SQDB_SECTION_CATEGORIES, &size); + if (ptr == NULL) + return -1; + + size /= sizeof(uint32_t); + for (i = 0; i < size; i++) + if (blob_cmp(cat, sqdb_get_string_literal(db, ptr[i])) == 0) + return i; + + return -1; +} + +static inline uint64_t to_category(struct sqdb *db, blob_t c) +{ + int category; + + category = find_category_id(db, c); + if (category >= 0) + return 1ULL << category; + + fprintf(stderr, "WARNING: unknown category '%.*s'\n", + c.len, c.ptr); + return 0; +} + +int adbc_refresh(struct authdb_config *cfg, time_t now) +{ + FILE *in; + int lineno = 1; + char word1[64], word2[64]; + blob_t b, p; + struct stat st; + + if (cfg->last_check != 0 && cfg->last_check + 2*60 > now) + return 0; + + if (stat("/etc/squark/filter.conf", &st) != 0) + return -1; + + if (cfg->last_change == st.st_ctime) + return 0; + + /* check timestamp */ + + in = fopen("/etc/squark/filter.conf", "r"); + if (in == NULL) + return -1; + + cfg->block_categories = 0; + cfg->hard_block_categories = 0; + while (1) { + b = read_word(in, &lineno, BLOB_BUF(word1)); + if (blob_is_null(b)) + break; + + p = read_word(in, &lineno, BLOB_BUF(word2)); + if (blob_cmp(b, BLOB_STR("redirect_path")) == 0) { + cfg->redirect_url_base = blob_dup(p); + } else if (blob_cmp(b, BLOB_STR("forbid")) == 0) { + cfg->hard_block_categories |= to_category(cfg->db, p); + } else if (blob_cmp(b, BLOB_STR("warn")) == 0) { + cfg->block_categories |= to_category(cfg->db, p); + } + } + cfg->block_categories |= cfg->hard_block_categories; + + fclose(in); +} diff --git a/authdb.h b/authdb.h index 29000bd..7bfa2f4 100644 --- a/authdb.h +++ b/authdb.h @@ -8,8 +8,18 @@ #define AUTHDB_IP_HASH_SIZE 64 +struct sqdb; struct authdb_map_entry; +struct authdb_config { + struct sqdb *db; + time_t last_check; + time_t last_change; + uint64_t block_categories; + uint64_t hard_block_categories; + blob_t redirect_url_base; +}; + struct authdb { struct authdb_map_entry *hash_bucket[AUTHDB_IP_HASH_SIZE]; }; @@ -35,7 +45,7 @@ struct authdb_map_entry { struct authdb_entry * entries; }; -int authdb_open(struct authdb *adb); +int authdb_open(struct authdb *adb, struct authdb_config *adbc, struct sqdb *db); void authdb_close(struct authdb *adb); void *authdb_get(struct authdb *adb, sockaddr_any *addr, struct authdb_entry *entry, int create); @@ -43,8 +53,10 @@ void *authdb_get(struct authdb *adb, sockaddr_any *addr, struct authdb_entry *en void authdb_clear_entry(struct authdb_entry *entry); int authdb_set(void *token, struct authdb_entry *entry); int authdb_check_login(void *token, struct authdb_entry *e, blob_t username, time_t now); -void authdb_commit_login(void *token, struct authdb_entry *e, time_t now); +void authdb_commit_login(void *token, struct authdb_entry *e, time_t now, struct authdb_config *cfg); void authdb_commit_logout(void *token); void authdb_commit_override(void *token, struct authdb_entry *entry, time_t now); +int adbc_refresh(struct authdb_config *cfg, time_t now); + #endif diff --git a/squark-auth-ip.c b/squark-auth-ip.c index 1346a2e..4f914ae 100644 --- a/squark-auth-ip.c +++ b/squark-auth-ip.c @@ -16,6 +16,7 @@ #include "blob.h" #include "authdb.h" +#include "filterdb.h" #define DO_LOGIN -1 #define DO_OVERRIDE -2 @@ -23,7 +24,9 @@ #define DO_LOGOUT -4 static int running = 1; +static struct sqdb db; static struct authdb adb; +static struct authdb_config adbc; static blob_t space = BLOB_STR_INIT(" "); static blob_t lf = BLOB_STR_INIT("\n"); static time_t now; @@ -143,7 +146,8 @@ int main(int argc, char **argv) } now = time(NULL); - authdb_open(&adb); + sqdb_open(&db, "/var/lib/squark/squark.db"); + authdb_open(&adb, &adbc, &db); if (running < 0) { struct authdb_entry entry; @@ -168,7 +172,7 @@ int main(int argc, char **argv) } authdb_clear_entry(&entry); memcpy(entry.p.login_name, username.ptr, username.len); - authdb_commit_login(token, &entry, now); + authdb_commit_login(token, &entry, now, &adbc); break; case DO_OVERRIDE: if (authdb_check_login(token, &entry, username, now)) @@ -206,4 +210,5 @@ int main(int argc, char **argv) } authdb_close(&adb); + sqdb_close(&db); } diff --git a/squark-auth-snmp.c b/squark-auth-snmp.c index bcf1858..d72c958 100644 --- a/squark-auth-snmp.c +++ b/squark-auth-snmp.c @@ -29,6 +29,7 @@ #include "blob.h" #include "addr.h" #include "authdb.h" +#include "filterdb.h" /* Compile time configurables */ #define SWITCH_HASH_SIZE 128 @@ -97,7 +98,9 @@ static int num_queries = 0; static int running = TRUE; static int kick_out = FALSE; +static struct sqdb db; static struct authdb adb; +static struct authdb_config adbc; static const char *snmp_community = NULL; static const char *username_format = "%w"; static struct switch_info *all_switches[SWITCH_HASH_SIZE]; @@ -273,6 +276,7 @@ struct auth_context { static void cache_update_time(void) { current_time = time(NULL); + adbc_refresh(&adbc, current_time); } static int cache_refresh( @@ -562,7 +566,7 @@ static void auth_completed(struct auth_context *auth) memcpy(entry.p.mac_address, auth->mac, MAC_LEN); entry.p.switch_ip = auth->current_switch->addr; entry.p.switch_port = auth->local_port; - authdb_commit_login(token, &entry, current_time); + authdb_commit_login(token, &entry, current_time, &adbc); } blob_push(&b, BLOB_STR(" OK user=")); @@ -1092,7 +1096,8 @@ int main(int argc, char **argv) return 1; } - authdb_open(&adb); + sqdb_open(&db, "/var/lib/squark/squark.db"); + authdb_open(&adb, &adbc, &db); if (l2_root == NULL) l2_root = l3_root; @@ -1133,6 +1138,7 @@ int main(int argc, char **argv) snmp_timeout(); } authdb_close(&adb); + sqdb_close(&db); return 0; } diff --git a/squark-filter.c b/squark-filter.c index 1fa1ec9..995da40 100644 --- a/squark-filter.c +++ b/squark-filter.c @@ -25,13 +25,15 @@ #define FILTER_OVERRIDE_TIMEOUT (15*60) +static struct sqdb db; +static struct authdb adb; +static struct authdb_config adbc; + static int running = 1; -static uint64_t banned_categories = 0; static const blob_t dash = BLOB_STR_INIT("-"); static const blob_t space = BLOB_STR_INIT(" "); static const blob_t slash = BLOB_STR_INIT("/"); static const blob_t lf = BLOB_STR_INIT("\n"); -static blob_t redirect_banned_page, redirect_login_page; static struct authdb adb; static time_t now; @@ -303,23 +305,6 @@ static blob_t get_category_name(struct sqdb *db, int id) return sqdb_get_string_literal(db, c[id]); } -static int find_category_id(struct sqdb *db, blob_t cat) -{ - uint32_t size, *ptr; - int i; - - ptr = sqdb_section_get(db, SQDB_SECTION_CATEGORIES, &size); - if (ptr == NULL) - return -1; - - size /= sizeof(uint32_t); - for (i = 0; i < size; i++) - if (blob_cmp(cat, sqdb_get_string_literal(db, ptr[i])) == 0) - return i; - - return -1; -} - static void send_ok(blob_t tag) { static char buffer[64]; @@ -339,6 +324,7 @@ static void send_redirect(blob_t redirect_page, blob_t tag, blob_t url, blob_t c blob_push(&b, tag); blob_push(&b, BLOB_STR(" 302:")); + blob_push(&b, adbc.redirect_url_base); blob_push(&b, redirect_page); blob_push(&b, BLOB_STR("?REASON=")); blob_push_urlencode(&b, categ); @@ -414,12 +400,12 @@ static void read_input(struct sqdb *db) } if (!auth_ok) { - send_redirect(redirect_login_page, id, url, BLOB_STR("auth"), username); + send_redirect(BLOB_STR("login.cgi"), id, url, BLOB_STR("auth"), username); } else if (((1ULL << category) & entry.p.block_categories) && (now < entry.override_time || now > entry.override_time + FILTER_OVERRIDE_TIMEOUT || ((1ULL << category) & entry.p.hard_block_categories))) { - send_redirect(redirect_banned_page, id, url, get_category_name(db, category), username); + send_redirect(BLOB_STR("warning.cgi"), id, url, get_category_name(db, category), username); } else send_ok(id); } @@ -432,39 +418,10 @@ static void read_input(struct sqdb *db) } while (b.len); } -static void ban_category(struct sqdb *db, blob_t c) -{ - int category; - - category = find_category_id(db, c); - if (category >= 0) - banned_categories |= 1ULL << category; - else - fprintf(stderr, "WARNING: unknown category '%.*s'\n", - c.len, c.ptr); -} - int main(int argc, char **argv) { - struct sqdb db; - int opt; - - authdb_open(&adb); sqdb_open(&db, "/var/lib/squark/squark.db"); - - while ((opt = getopt(argc, argv, "r:b:c:")) != -1) { - switch (opt) { - case 'r': - redirect_banned_page = BLOB_STRLEN(optarg); - break; - case 'c': - redirect_login_page = BLOB_STRLEN(optarg); - break; - case 'b': - ban_category(&db, BLOB_STRLEN(optarg)); - break; - } - } + authdb_open(&adb, &adbc, &db); while (running) read_input(&db); -- cgit v1.2.3