From: hno <> Date: Sun, 19 Mar 2006 08:11:44 +0000 (+0000) Subject: external acl helper for tracking user sessions X-Git-Tag: SQUID_3_0_PRE4~293 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b0c8f295e67451cc061bbd60ec6533ef1c2b9bde;p=thirdparty%2Fsquid.git external acl helper for tracking user sessions --- diff --git a/helpers/external_acl/session/Makefile b/helpers/external_acl/session/Makefile new file mode 100644 index 0000000000..a951cebaf3 --- /dev/null +++ b/helpers/external_acl/session/Makefile @@ -0,0 +1,7 @@ +#CFLAGS=-Wall -Wextra +LDLIBS=-ldb + +squid_session: squid_session.o + +clean: + rm -f *.o squid_session diff --git a/helpers/external_acl/session/Makefile.am b/helpers/external_acl/session/Makefile.am new file mode 100644 index 0000000000..f1f0925146 --- /dev/null +++ b/helpers/external_acl/session/Makefile.am @@ -0,0 +1,15 @@ +# +# Makefile for the Squid LDAP authentication helper +# +# $Id: Makefile.am,v 1.1 2006/03/19 01:11:44 hno Exp $ +# +# Uncomment and customize the following to suit your needs: +# + +libexec_PROGRAMS = squid_session +man_MANS = squid_session.8 +EXTRA_DIST = squid_session.8 +squid_session_SOURCES = squid_session.c + +LDADD = -ldb +INCLUDES = -I. -I$(top_builddir)/include -I$(top_srcdir)/include diff --git a/helpers/external_acl/session/squid_session.8 b/helpers/external_acl/session/squid_session.8 new file mode 100644 index 0000000000..eedb560c02 --- /dev/null +++ b/helpers/external_acl/session/squid_session.8 @@ -0,0 +1,49 @@ +.TH squid_session 8 "19 March 2006" "Version 1.0" +. +.SH NAME +squid_session - Squid session tracking external acl group helper +. +.SH SYNOPSIS +squid_session [-t idle_timeout] [-b dbpath] [-a] +. +.SH DESCRIPTION +This helper maintains a concept of sessions by monitoring requests +and timing out sessions if no requests have been seen for the idle timeout +timer. +.P +Intended use is for displaying "terms of use" pages, ad popups etc. +. +.TP +.BI "-t " "idletimeout " "(default 3600)" +Specifies the session idle timeout timer. +. +.TP +.BI "-b " "dbpath" +Path to persistent database. If not specified the session details +will be kept in memory only and all sessions will reset each time +Squid restarts it's helpers (Squid restart or rotation of logs). +. +.TP +.B "-a" +Active mode. In this mode sessions are started by evaluating an +acl with the argument LOGIN, or terminated by the argument LOGOUT. +.P +Without this flag the helper automatically starts the session after +the first request. +. +.SH AUTHOR +This helper and documentation was written by +.I Henrik Nordstrom +. +.SH QUESTIONS +Any questions on usage can be sent to +.IR "Squid Users " . +. +.SH REPORTING BUGS +Report bugs or bug-fixes to +.I Squid Bugs +or ideas for new improvements to +.I Squid Developers +. +.SH "SEE ALSO" +.BR squid ( 8 ) diff --git a/helpers/external_acl/session/squid_session.c b/helpers/external_acl/session/squid_session.c new file mode 100644 index 0000000000..730b126445 --- /dev/null +++ b/helpers/external_acl/session/squid_session.c @@ -0,0 +1,163 @@ +/* + * squid_session: Squid external acl helper for tracking sessions + * + * Copyright (C) 2006 Henrik Nordstrom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int session_ttl = 3600; +char *db_path = NULL; +const char *program_name; + +DB *db = NULL; + +static void init_db(void) +{ + db = dbopen(db_path, O_CREAT | O_RDWR, 0666, DB_BTREE, NULL); + if (!db) { + fprintf(stderr, "%s: Failed to open session db '%s'\n", program_name, db_path); + exit(1); + } +} + +static void shutdown_db(void) +{ + db->close(db); +} + +int session_is_active = 0; + +static int session_active(const char *details) +{ + DBT key, data; + key.data = (void *)details; + key.size = strlen(details); + if (db->get(db, &key, &data, 0) == 0) { + time_t timestamp; + if (data.size != sizeof(timestamp)) { + fprintf(stderr, "%s: CORRUPTED DATABASE (%s)\n", program_name, details); + db->del(db, &key, 0); + return 0; + } + memcpy(×tamp, data.data, sizeof(timestamp)); + if (timestamp + session_ttl >= time(NULL)) + return 1; + } + return 0; +} + +static void session_login(const char *details) +{ + DBT key, data; + time_t now = time(NULL); + key.data = (void *)details; + key.size = strlen(details); + data.data = &now; + data.size = sizeof(now); + db->put(db, &key, &data, 0); +} + +static void session_logout(const char *details) +{ + DBT key; + key.data = (void *)details; + key.size = strlen(details); + db->del(db, &key, 0); +} + +static void usage(void) +{ + fprintf(stderr, "Usage: %s [-t session_timeout] [-b dbpath] [-a]\n", program_name); + fprintf(stderr, " -t sessiontimeout Idle timeout after which sessions will be forgotten\n"); + fprintf(stderr, " -b dbpath Path where persistent session database will be kept\n"); + fprintf(stderr, " -a Active mode requiring LOGIN argument to start a session\n"); +} +int main(int argc, char **argv) +{ + char request[256]; + int opt; + int default_action = 1; + + program_name = argv[0]; + + while ((opt = getopt(argc, argv, "t:b:a?")) != -1) { + switch(opt) { + case 't': + session_ttl = strtol(optarg, NULL, 0); + break; + case 'b': + db_path = optarg; + break; + case 'a': + default_action = 0; + break; + case '?': + usage(); + exit(0); + break; + } + } + + setbuf(stdout, NULL); + + init_db(); + + while (fgets(request, sizeof(request), stdin)) { + const char *index, *detail; + char *lastdetail; + int action = 0; + index = strtok(request, " \n"); + detail = strtok(NULL, "\n"); + lastdetail = strrchr(detail, ' '); + if (lastdetail) { + if (strcmp(lastdetail, " LOGIN") == 0) { + *lastdetail++ = '\0'; + action = 1; + } else if (strcmp(lastdetail, " LOGOUT") == 0) { + action = -1; + *lastdetail++ = '\0'; + } + } + if (action == -1) { + session_logout(detail); + printf("%s OK message=\"Bye\"\n", index); + } else if (action == 1) { + session_login(detail); + printf("%s OK message=\"Welcome\"\n", index); + } else if (session_active(detail)) { + session_login(detail); + printf("%s OK\n", index); + } else if (default_action == 1) { + session_login(detail); + printf("%s ERR message=\"Welcome\"\n", index); + } else { + printf("%s ERR message=\"No session available\"\n", index); + } + } + shutdown_db(); + return 0; +}