diff options
author | Timo Teräs <timo.teras@iki.fi> | 2010-08-27 17:05:18 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2010-08-27 17:05:18 +0300 |
commit | b8944ab71ccdc9951c6b74ef8ed8686d0329f99c (patch) | |
tree | a44327faefdfb99bf61d1249c044bfef66419267 /squark-filter.c | |
parent | 29331f1c5e940499f282aea8155b89fae69f3fb8 (diff) | |
download | squark-b8944ab71ccdc9951c6b74ef8ed8686d0329f99c.tar.bz2 squark-b8944ab71ccdc9951c6b74ef8ed8686d0329f99c.tar.xz |
authdb: implement basics
Implement a shared memory based authentication cache. It's a simple
local cache indexed by IP-address, and keeps track of that IP's
auth info such as username, allowed categories and timeouts. This
provides basis for captive portal, per-user definable category
restrictions and implementation of soft blocks (block which can
be overridden by user by clicking a button on the blocked page).
Diffstat (limited to 'squark-filter.c')
-rw-r--r-- | squark-filter.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/squark-filter.c b/squark-filter.c index 588eb73..7a005e1 100644 --- a/squark-filter.c +++ b/squark-filter.c @@ -10,6 +10,7 @@ * by the Free Software Foundation. See http://www.gnu.org/ for details. */ +#include <time.h> #include <stdio.h> #include <ctype.h> #include <string.h> @@ -17,14 +18,20 @@ #include <cmph.h> -#include "filterdb.h" #include "blob.h" +#include "addr.h" +#include "filterdb.h" +#include "authdb.h" 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_page; +static blob_t redirect_banned_page, redirect_login_page; +static struct authdb adb; +static time_t now; struct url_info { blob_t protocol; @@ -321,7 +328,7 @@ static void send_ok(blob_t tag) write(STDOUT_FILENO, b.ptr, b.len); } -static void send_redirect(struct sqdb *db, blob_t tag, blob_t url, int categ, blob_t username) +static void send_redirect(blob_t redirect_page, blob_t tag, blob_t url, blob_t categ, blob_t username) { static char buffer[8*1024]; blob_t b = BLOB_BUF(buffer); @@ -330,7 +337,7 @@ static void send_redirect(struct sqdb *db, blob_t tag, blob_t url, int categ, bl blob_push(&b, BLOB_STR(" 302:")); blob_push(&b, redirect_page); blob_push(&b, BLOB_STR("?REASON=")); - blob_push_urlencode(&b, get_category_name(db, categ)); + blob_push_urlencode(&b, categ); blob_push(&b, BLOB_STR("&USER=")); blob_push_urlencode(&b, username); blob_push(&b, BLOB_STR("&DENIEDURL=")); @@ -346,9 +353,12 @@ static void read_input(struct sqdb *db) static char buffer[8 * 1024]; static blob_t left; - blob_t b, line, id, url, username; + blob_t b, line, id, ipaddr, url, username; struct url_info nfo; - int r, category; + int r, category, auth_ok; + sockaddr_any addr; + struct authdb_entry entry; + void *token; if (blob_is_null(left)) left = BLOB_BUF(buffer); @@ -363,6 +373,8 @@ static void read_input(struct sqdb *db) left.ptr += r; left.len -= r; + now = time(NULL); + b = blob_pushed(BLOB_BUF(buffer), left); do { line = blob_pull_cspn(&b, lf); @@ -373,16 +385,16 @@ static void read_input(struct sqdb *db) blob_pull_spn(&line, space); url = blob_pull_cspn(&line, space); blob_pull_spn(&line, space); - blob_pull_cspn(&line, space); /* client addr / fqdn */ + ipaddr = blob_pull_cspn(&line, slash); /* client addr */ + blob_pull_cspn(&line, space); /* fqdn */ blob_pull_spn(&line, space); username = blob_pull_cspn(&line, space); /* http method */ /* urlgroup */ /* myaddr=xxx myport=xxx etc */ - if (!blob_is_null(url)) { - if (blob_is_null(username)) - username = BLOB_STR("-"); + if (!blob_is_null(url) && + addr_parse(ipaddr, &addr)) { /* valid request, handle it */ if (url_parse(url, &nfo)) { url_print(&nfo); @@ -390,9 +402,29 @@ static void read_input(struct sqdb *db) } else category = 0; - if ((1ULL << category) & banned_categories) - send_redirect(db, id, url, category, username); - else + token = authdb_get(&adb, &addr, &entry, 1); + if (authdb_check_login(token, &entry, username, now)) { + auth_ok = 1; + username = BLOB_STRLEN(entry.p.login_name); + } else if (blob_cmp(username, dash) != 0 || + blob_is_null(redirect_login_page)) { + auth_ok = 1; + authdb_clear_entry(&entry); + entry.p.block_categories = banned_categories; + memcpy(entry.p.login_name, username.ptr, username.len); + authdb_commit_login(token, &entry, now); + } else { + auth_ok = 0; + } + + if (!auth_ok) { + send_redirect(redirect_login_page, id, url, BLOB_STR("auth"), username); + } else if (((1ULL << category) & entry.p.block_categories) && + (entry.u.override_time < now || + entry.u.override_time + 15*60 > now || + ((1ULL << category) & entry.p.hard_block_categories))) { + send_redirect(redirect_banned_page, id, url, get_category_name(db, category), username); + } else send_ok(id); } @@ -421,12 +453,16 @@ 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:")) != -1) { + while ((opt = getopt(argc, argv, "r:b:c:")) != -1) { switch (opt) { case 'r': - redirect_page = BLOB_STRLEN(optarg); + redirect_banned_page = BLOB_STRLEN(optarg); + break; + case 'c': + redirect_login_page = BLOB_STRLEN(optarg); break; case 'b': ban_category(&db, BLOB_STRLEN(optarg)); @@ -438,4 +474,5 @@ int main(int argc, char **argv) read_input(&db); sqdb_close(&db); + authdb_close(&adb); } |