summaryrefslogtreecommitdiffstats
path: root/squark-filter.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2010-08-27 17:05:18 +0300
committerTimo Teräs <timo.teras@iki.fi>2010-08-27 17:05:18 +0300
commitb8944ab71ccdc9951c6b74ef8ed8686d0329f99c (patch)
treea44327faefdfb99bf61d1249c044bfef66419267 /squark-filter.c
parent29331f1c5e940499f282aea8155b89fae69f3fb8 (diff)
downloadsquark-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.c67
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);
}