summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2010-09-14 14:59:38 +0300
committerTimo Teräs <timo.teras@iki.fi>2010-09-14 14:59:38 +0300
commit84354c50f807607700b95debdd3a7ddfde0c09f9 (patch)
tree56065d6d7a34b45a6cbb5eef662ae1f1bad64484
parent4be1e8fd5e352a54e87a81979d5ad303efdcbffe (diff)
downloadsquark-84354c50f807607700b95debdd3a7ddfde0c09f9.tar.bz2
squark-84354c50f807607700b95debdd3a7ddfde0c09f9.tar.xz
authdb: use configuration file to decide blocked categories
and cache the information to authdb properly.
-rw-r--r--Makefile4
-rw-r--r--authdb.c122
-rw-r--r--authdb.h16
-rw-r--r--squark-auth-ip.c9
-rw-r--r--squark-auth-snmp.c10
-rw-r--r--squark-filter.c59
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 <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);
+}
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);