From 25593b5e6fea76ed7c08db586924032c0810c27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sun, 7 Nov 2010 00:47:39 +0200 Subject: squark: reorganize sources to src directory --- src/squark-auth-ip.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/squark-auth-ip.c (limited to 'src/squark-auth-ip.c') diff --git a/src/squark-auth-ip.c b/src/squark-auth-ip.c new file mode 100644 index 0000000..3cdea0b --- /dev/null +++ b/src/squark-auth-ip.c @@ -0,0 +1,218 @@ +/* squark-auth-ip.c - Squid User Authentication and Rating Kit + * An external acl helper for Squid which collects authentication + * information about an IP-address from local shared memory database. + * + * Copyright (C) 2010 Timo Teräs + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. See http://www.gnu.org/ for details. + */ + +#include +#include +#include + +#include "blob.h" +#include "authdb.h" +#include "filterdb.h" + +#define DO_LOGIN -1 +#define DO_OVERRIDE -2 +#define DO_PRINT -3 +#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; + +static void handle_line(blob_t line) +{ + char reply[128]; + blob_t b, id, ipaddr; + struct authdb_entry entry; + sockaddr_any addr; + void *token; + int auth_ok = 0; + + id = blob_pull_cspn(&line, space); + blob_pull_spn(&line, space); + ipaddr = blob_pull_cspn(&line, space); + + if (addr_parse(ipaddr, &addr)) { + token = authdb_get(&adb, &addr, &entry, 1); + + if (authdb_check_login(token, &entry, BLOB_NULL, now)) + auth_ok = 1; + } + + b = BLOB_BUF(reply); + blob_push(&b, id); + if (auth_ok) { + blob_push(&b, BLOB_STR(" OK user=")); + blob_push(&b, BLOB_STRLEN(entry.p.login_name)); + blob_push(&b, BLOB_PTR_LEN("\n", 1)); + } else { + blob_push(&b, BLOB_STR(" ERR\n")); + } + + b = blob_pushed(BLOB_BUF(reply), b); + write(STDOUT_FILENO, b.ptr, b.len); +} + +static void read_input(void) +{ + static char buffer[256]; + static blob_t left; + + blob_t b, line; + int r; + + if (blob_is_null(left)) + left = BLOB_BUF(buffer); + + r = read(STDIN_FILENO, left.ptr, left.len); + if (r < 0) + return; + if (r == 0) { + running = 0; + return; + } + left.ptr += r; + left.len -= r; + + now = time(NULL); + + b = blob_pushed(BLOB_BUF(buffer), left); + do { + line = blob_pull_cspn(&b, lf); + if (!blob_pull_matching(&b, lf)) + return; + + handle_line(line); + + if (b.len) { + memcpy(buffer, b.ptr, b.len); + b.ptr = buffer; + } + left = BLOB_PTR_LEN(buffer + b.len, sizeof(buffer) - b.len); + } while (b.len); +} + +#define DUMPPAR(b, name, fn) \ + do { \ + blob_push(b, BLOB_STR("squark_" name "='")); \ + fn; \ + blob_push(b, BLOB_STR("'; ")); \ + } while (0) + +int main(int argc, char **argv) +{ + int opt; + sockaddr_any ipaddr = { .any.sa_family = AF_UNSPEC }; + blob_t ip = BLOB_NULL, username = BLOB_NULL; + + while ((opt = getopt(argc, argv, "i:u:olpL")) != -1) { + switch (opt) { + case 'i': + ip = BLOB_STRLEN(optarg); + if (!addr_parse(ip, &ipaddr)) { + fprintf(stderr, "'%s' does not look like IP-address\n", + optarg); + return 1; + } + break; + case 'u': + username = BLOB_STRLEN(optarg); + break; + case 'o': + running = DO_OVERRIDE; + break; + case 'l': + running = DO_LOGIN; + break; + case 'p': + running = DO_PRINT; + break; + case 'L': + running = DO_LOGOUT; + break; + } + } + + now = time(NULL); + sqdb_open(&db, "/var/lib/squark/squark.db"); + authdb_open(&adb, &adbc, &db); + + if (running < 0) { + struct authdb_entry entry; + void *token; + + if (ipaddr.any.sa_family == AF_UNSPEC) { + fprintf(stderr, "IP-address not specified\n"); + return 2; + } + + token = authdb_get(&adb, &ipaddr, &entry, 1); + if (token == NULL) { + fprintf(stderr, "Failed to get authdb record\n"); + return 3; + } + + switch (running) { + case DO_LOGIN: + if (blob_is_null(username)) { + fprintf(stderr, "Username not specified\n"); + return 2; + } + authdb_clear_entry(&entry); + memcpy(entry.p.login_name, username.ptr, username.len); + authdb_commit_login(token, &entry, now, &adbc); + break; + case DO_OVERRIDE: + if (authdb_check_login(token, &entry, username, now)) + authdb_commit_override(token, &entry, now); + break; + case DO_PRINT: { + char buf[512]; + blob_t b = BLOB_BUF(buf); + + DUMPPAR(&b, "ip_address", + addr_push_hostaddr(&b, &ipaddr)); + DUMPPAR(&b, "username", + blob_push(&b, BLOB_BUF(entry.p.login_name))); + DUMPPAR(&b, "mac_address", + blob_push_hexdump(&b, BLOB_BUF(entry.p.mac_address))); + DUMPPAR(&b, "login_time", + blob_push_ctime(&b, entry.p.login_time)); + DUMPPAR(&b, "activity_time", + blob_push_ctime(&b, entry.last_activity_time)); + DUMPPAR(&b, "override_time", + blob_push_ctime(&b, entry.override_time)); + DUMPPAR(&b, "block_categories", + blob_push_hexdump(&b, BLOB_BUF(&entry.p.block_categories))); + DUMPPAR(&b, "hard_block_categories", + blob_push_hexdump(&b, BLOB_BUF(&entry.p.hard_block_categories))); + blob_push(&b, BLOB_STR("\n")); + b = blob_pushed(BLOB_BUF(buf), b); + fwrite(b.ptr, b.len, 1, stdout); + break; + } + case DO_LOGOUT: + if (authdb_check_login(token, &entry, username, now)) + authdb_commit_logout(token); + break; + } + } else { + while (running) + read_input(); + } + + authdb_close(&adb); + sqdb_close(&db); +} -- cgit v1.2.3