Here is the diff I made,
it simply calls a program when a user logs in with authpf and when a
user logs out.
to use this diff you must add these lines to authpf.conf
start=/path/to/startsession.pl
end=/path/to/endsession.pl
follows is the diff
Index: src/usr.sbin/authpf/authpf.c
===================================================================
RCS file: /cvs/src/usr.sbin/authpf/authpf.c,v
retrieving revision 1.123
diff -u -r1.123 authpf.c
--- src/usr.sbin/authpf/authpf.c 21 Jan 2015 21:50:32 -0000 1.123
+++ src/usr.sbin/authpf/authpf.c 8 Oct 2015 01:21:58 -0000
@@ -52,12 +52,15 @@
static int change_filter(int, const char *, const char *);
static int change_table(int, const char *);
static void authpf_kill_states(void);
+static int exec_callback(int);
int dev; /* pf device */
char anchorname[PF_ANCHOR_NAME_SIZE] = "authpf";
char rulesetname[PATH_MAX - PF_ANCHOR_NAME_SIZE - 2];
char tablename[PF_TABLE_NAME_SIZE] = "authpf_users";
int user_ip = 1; /* controls whether $user_ip is set */
+char startcommand[PATH_MAX - PF_ANCHOR_NAME_SIZE - 2] = "";
+char endcommand[PATH_MAX - PF_ANCHOR_NAME_SIZE - 2] = "";
FILE *pidfp;
int pidfd = -1;
@@ -411,6 +414,19 @@
sizeof(tablename)) >= sizeof(tablename))
goto parse_error;
}
+ if (strcasecmp(pair[0], "start") == 0) {
+ if (!pair[1][0] || strlcpy(startcommand, pair[1],
+ sizeof(startcommand)) >= sizeof(startcommand))
+ goto parse_error;
+ syslog(LOG_INFO, "start: %s", startcommand);
+ }
+
+ if (strcasecmp(pair[0], "end") == 0) {
+ if (!pair[1][0] || strlcpy(endcommand, pair[1],
+ sizeof(endcommand)) >= sizeof(endcommand))
+ goto parse_error;
+ syslog(LOG_INFO, "end: %s", endcommand);
+ }
} while (!feof(f) && !ferror(f));
fclose(f);
return (0);
@@ -821,11 +837,23 @@
goto error;
}
+ if (startcommand != NULL) {
+ if (exec_callback(0) != 0) {
+ goto error;
+ }
+ }
+
gettimeofday(&Tstart, NULL);
syslog(LOG_INFO, "allowing %s, user %s", ipsrc, luser);
} else {
remove_stale_rulesets();
+ if (endcommand != NULL) {
+ if (exec_callback(1) != 0) {
+ goto error;
+ }
+ }
+
gettimeofday(&Tend, NULL);
syslog(LOG_INFO, "removed %s, user %s - duration %d seconds",
ipsrc, luser, (int)(Tend.tv_sec - Tstart.tv_sec));
@@ -952,3 +980,78 @@
syslog(LOG_ERR, "cannot unlink %s (%m)", pidfile);
exit(ret);
}
+
+/*
+ * execute an external program on start and or end of session
+ */
+static int
+exec_callback(int end)
+{
+ pid_t pid;
+ gid_t gid;
+ int s;
+ char prog[PATH_MAX - PF_ANCHOR_NAME_SIZE - 2];
+ char *pargv[5] = {"/bin/ls", "luser", "ip", "pid", NULL};
+
+ if (end == 0) {
+ if (startcommand != NULL) {
+ strlcpy(prog, startcommand, sizeof(startcommand));
+ } else {
+ goto done;
+ }
+ }
+
+ if (end == 1) {
+ if (endcommand != NULL) {
+ strlcpy(prog, endcommand, sizeof(endcommand));
+ } else {
+ goto done;
+ }
+ }
+
+ pargv[0] = prog;
+ pargv[1] = luser;
+ pargv[2] = ipsrc;
+ if (asprintf(&pargv[3], "%ld", (long)getpid()) == -1)
+ goto no_mem;
+
+ switch (pid = fork()) {
+ case -1:
+ syslog(LOG_ERR, "fork failed");
+ goto error;
+ case 0:
+ /* revoke group privs before exec */
+ gid = getgid();
+ if (setregid(gid, gid) == -1) {
+ err(1, "setregid");
+ }
+
+ execvp(prog, pargv);
+ syslog(LOG_INFO, "exec of %s %s %s %s", prog, pargv[1],
+ pargv[2], pargv[3]);
+ warn("exec of %s %s %s %s [] failed", prog, pargv[1],
+ pargv[2], pargv[3]);
+ _exit(1);
+ }
+
+ /* parent */
+ waitpid(pid, &s, 0);
+ if (s != 0) {
+ syslog(LOG_ERR, "%s exited abnormally", prog);
+ goto error;
+ }
+done:
+ return (0);
+
+no_mem:
+ if (errno == ENOMEM)
+ syslog(LOG_ERR, "calloc failed");
+ syslog(LOG_ERR, "NO MEM");
+ return (-1);
+
+error:
+ free(pargv[3]);
+ syslog(LOG_ERR, "ERROR RETURNING -1");
+ return (-1);
+}
+
PS: I have used this for a little pocket money ISP for three years now
along side a custom sqlite db for authentication on web, scraping
zeroed users in pf is the way to go with a cron job.
On 10/06/2015 07:43 AM, C. L. Martinez wrote:
On Mon, Oct 5, 2015 at 1:26 PM, laudarch <lauda...@host.sk> wrote:
I made a custom implementation and a diff to authpf, will share that
later just in case anyone wants it.
I hope this helps you, it pretty simple
http://bastienceriani.fr/?p=70
Thanks laudarch ... Very close to what I am searching... I will try
your config.