]>
git.ipfire.org Git - thirdparty/squid.git/blob - helpers/external_acl/session/ext_session_acl.cc
2 * ext_session_acl: Squid external acl helper for tracking sessions
4 * Copyright (C) 2006 Henrik Nordstrom <henrik@henriknordstrom.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 #include "helpers/defines.h"
26 #include <sys/types.h>
40 /* At this point all Bit Types are already defined, so we must
41 protect from multiple type definition on platform where
42 __BIT_TYPES_DEFINED__ is not defined.
44 #ifndef __BIT_TYPES_DEFINED__
45 #define __BIT_TYPES_DEFINED__
54 static int session_ttl
= 3600;
55 static int fixed_timeout
= 0;
57 const char *program_name
;
61 static void init_db(void)
63 db
= dbopen(db_path
, O_CREAT
| O_RDWR
, 0666, DB_BTREE
, NULL
);
65 fprintf(stderr
, "FATAL: %s: Failed to open session db '%s'\n", program_name
, db_path
);
70 static void shutdown_db(void)
75 int session_is_active
= 0;
77 static int session_active(const char *details
, size_t len
)
80 key
.data
= (void *)details
;
82 if (db
->get(db
, &key
, &data
, 0) == 0) {
84 if (data
.size
!= sizeof(timestamp
)) {
85 fprintf(stderr
, "ERROR: %s: CORRUPTED DATABASE (%s)\n", program_name
, details
);
89 memcpy(×tamp
, data
.data
, sizeof(timestamp
));
90 if (timestamp
+ session_ttl
>= time(NULL
))
96 static void session_login(const char *details
, size_t len
)
99 time_t now
= time(NULL
);
100 key
.data
= (void *)details
;
103 data
.size
= sizeof(now
);
104 db
->put(db
, &key
, &data
, 0);
108 static void session_logout(const char *details
, size_t len
)
111 key
.data
= (void *)details
;
113 db
->del(db
, &key
, 0);
116 static void usage(void)
118 fprintf(stderr
, "Usage: %s [-t|-T session_timeout] [-b dbpath] [-a]\n", program_name
);
119 fprintf(stderr
, " -t sessiontimeout Idle timeout after which sessions will be forgotten (user activity will reset)\n");
120 fprintf(stderr
, " -T sessiontimeout Fixed timeout after which sessions will be forgotten (regardless of user activity)\n");
121 fprintf(stderr
, " -b dbpath Path where persistent session database will be kept\n");
122 fprintf(stderr
, " -a Active mode requiring LOGIN argument to start a session\n");
124 int main(int argc
, char **argv
)
126 char request
[HELPER_INPUT_BUFFER
];
128 int default_action
= 1;
130 program_name
= argv
[0];
132 while ((opt
= getopt(argc
, argv
, "t:T:b:a?")) != -1) {
137 session_ttl
= strtol(optarg
, NULL
, 0);
152 setbuf(stdout
, NULL
);
156 while (fgets(request
, HELPER_INPUT_BUFFER
, stdin
)) {
158 const char *channel_id
= strtok(request
, " ");
159 const char *detail
= strtok(NULL
, "\n");
160 if (detail
== NULL
) {
161 // Only 1 paramater supplied. We are expecting at least 2 (including the channel ID)
162 fprintf(stderr
, "FATAL: %s is concurrent and requires the concurrency option to be specified.\n", program_name
);
165 const char *lastdetail
= strrchr(detail
, ' ');
166 size_t detail_len
= strlen(detail
);
168 if (strcmp(lastdetail
, " LOGIN") == 0) {
170 detail_len
= (size_t)(lastdetail
-detail
);
171 } else if (strcmp(lastdetail
, " LOGOUT") == 0) {
173 detail_len
= (size_t)(lastdetail
-detail
);
177 session_logout(detail
, detail_len
);
178 printf("%s OK message=\"Bye\"\n", channel_id
);
179 } else if (action
== 1) {
180 session_login(detail
, detail_len
);
181 printf("%s OK message=\"Welcome\"\n", channel_id
);
182 } else if (session_active(detail
, detail_len
)) {
183 if (fixed_timeout
== 0) {
184 session_login(detail
, detail_len
);
186 printf("%s OK\n", channel_id
);
187 } else if (default_action
== 1) {
188 session_login(detail
, detail_len
);
189 printf("%s ERR message=\"Welcome\"\n", channel_id
);
191 printf("%s ERR message=\"No session available\"\n", channel_id
);