]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
external acl helper for tracking user sessions
authorhno <>
Sun, 19 Mar 2006 08:11:44 +0000 (08:11 +0000)
committerhno <>
Sun, 19 Mar 2006 08:11:44 +0000 (08:11 +0000)
helpers/external_acl/session/Makefile [new file with mode: 0644]
helpers/external_acl/session/Makefile.am [new file with mode: 0644]
helpers/external_acl/session/squid_session.8 [new file with mode: 0644]
helpers/external_acl/session/squid_session.c [new file with mode: 0644]

diff --git a/helpers/external_acl/session/Makefile b/helpers/external_acl/session/Makefile
new file mode 100644 (file)
index 0000000..a951ceb
--- /dev/null
@@ -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 (file)
index 0000000..f1f0925
--- /dev/null
@@ -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 (file)
index 0000000..eedb560
--- /dev/null
@@ -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 <henrik@henriknordstrom.net>
+.
+.SH QUESTIONS
+Any questions on usage can be sent to 
+.IR "Squid Users <squid-users@squid-cache.org>" .
+.
+.SH REPORTING BUGS
+Report bugs or bug-fixes to
+.I Squid Bugs <squid-bugs@squid-cache.org>
+or ideas for new improvements to 
+.I Squid Developers <squid-dev@squid-cache.org>
+.
+.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 (file)
index 0000000..730b126
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * squid_session: Squid external acl helper for tracking sessions
+ *
+ * Copyright (C) 2006 Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+
+#include <db_185.h>
+
+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(&timestamp, 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;
+}