diff options
Diffstat (limited to 'authdb.c')
-rw-r--r-- | authdb.c | 122 |
1 files changed, 118 insertions, 4 deletions
@@ -4,9 +4,12 @@ #include <malloc.h> #include <sched.h> #include <fcntl.h> +#include <ctype.h> +#include <time.h> #include <grp.h> #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); +} |