From e380053caa7c5379a15a1116418cd617661766e5 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Wed, 6 Feb 2013 19:03:02 +0100 Subject: [PATCH] Added explicit logging to UTMP file. --- src/Makefile.am | 2 +- src/config.c | 14 +++++ src/main-auth.c | 2 +- src/{main-script.c => main-user.c} | 84 ++++++++++++++++++++++++++++++ src/main.c | 2 +- src/main.h | 4 +- src/ocserv-args.c | 2 +- src/ocserv-args.def | 3 ++ src/ocserv-args.h | 2 +- src/sample.config | 3 ++ src/vpn.h | 1 + 11 files changed, 112 insertions(+), 7 deletions(-) rename src/{main-script.c => main-user.c} (67%) diff --git a/src/Makefile.am b/src/Makefile.am index 56f30535..f46776be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \ cookies.c http-parser/http_parser.c ipc.h \ vpn.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \ config.c pam.c pam.h worker-resume.c worker.h main-resume.c main.h \ - main-script.c $(CCAN_SOURCES) + main-user.c $(CCAN_SOURCES) ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h diff --git a/src/config.c b/src/config.c index 719bd4d2..26b90c69 100644 --- a/src/config.c +++ b/src/config.c @@ -69,6 +69,18 @@ else if (mand != 0) { \ fprintf(stderr, "Configuration option %s is mandatory.\n", name); \ } + +#define READ_TF(name, s_name, mand, def) \ + { char* tmp_tf = NULL; \ + READ_STRING(name, tmp_tf, mand); \ + if (tmp_tf == NULL) s_name = def; \ + else { \ + if (strcasecmp(tmp_tf, "true") == 0 || strcasecmp(tmp_tf, "yes") == 0) \ + s_name = 1; \ + else \ + s_name = 0; \ + } \ + } #define READ_NUMERIC(name, s_name, mand) \ val = optionGetValue(pov, name); \ @@ -125,6 +137,8 @@ unsigned j; READ_STRING("connect-script", config->connect_script, 0); READ_STRING("disconnect-script", config->disconnect_script, 0); + READ_TF("use-utmp", config->use_utmp, 0, 1); + READ_STRING("tls-priorities", config->priorities, 0); READ_STRING("chroot-dir", config->chroot_dir, 0); diff --git a/src/main-auth.c b/src/main-auth.c index 33cd3bde..5ea043e9 100644 --- a/src/main-auth.c +++ b/src/main-auth.c @@ -301,7 +301,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) } if (ret == 0) { - ret = call_connect_script(s, proc, lease); + ret = user_connected(s, proc, lease); if (ret < 0) { syslog(LOG_INFO, "User '%s' disconnected due to script", proc->username); } diff --git a/src/main-script.c b/src/main-user.c similarity index 67% rename from src/main-script.c rename to src/main-user.c index 678eac47..1ec338ec 100644 --- a/src/main-script.c +++ b/src/main-user.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,7 @@ #include #include +static void call_disconnect_script(main_server_st *s, struct proc_st* proc) { pid_t pid; @@ -89,6 +92,7 @@ int ret; } } +static int call_connect_script(main_server_st *s, struct proc_st* proc, struct lease_st* lease) { pid_t pid; @@ -97,6 +101,16 @@ int ret, status; if (s->config->connect_script == NULL) return 0; + if (s->config->auth_types & AUTH_TYPE_PAM) { + static int warned = 0; + + if (warned == 0) { + syslog(LOG_WARNING, "PAM authentication and UTMP are mutually exclusive. Turn off UTMP and use PAM for accounting."); + warned = 1; + } + return 0; + } + pid = fork(); if (pid == 0) { char real[64]; @@ -141,3 +155,73 @@ int ret, status; return 0; return -1; } + +static void +add_utmp_entry(main_server_st *s, struct proc_st* proc, struct lease_st* lease) +{ + struct utmpx entry; + struct timespec tv; + + if (s->config->use_utmp == 0) + return; + + memset(&entry, 0, sizeof(entry)); + entry.ut_type = USER_PROCESS; + entry.ut_pid = proc->pid; + snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", lease->name); + snprintf(entry.ut_user, sizeof(entry.ut_user), "%s", proc->username); + if (proc->remote_addr_len == sizeof(struct sockaddr_in)) + memcpy(entry.ut_addr_v6, SA_IN_P(&proc->remote_addr), sizeof(struct in_addr)); + else + memcpy(entry.ut_addr_v6, SA_IN6_P(&proc->remote_addr), sizeof(struct in6_addr)); + + gettime(&tv); + entry.ut_tv.tv_sec = tv.tv_sec; + entry.ut_tv.tv_usec = tv.tv_nsec / 1000; + getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, entry.ut_host, sizeof(entry.ut_host), NULL, 0, NI_NUMERICHOST); + + setutxent(); + pututxline(&entry); + endutxent(); + + return; +} + +static void remove_utmp_entry(main_server_st *s, struct proc_st* proc) +{ + struct utmpx entry; + + if (s->config->use_utmp == 0) + return; + + memset(&entry, 0, sizeof(entry)); + entry.ut_type = DEAD_PROCESS; + snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", proc->lease->name); + entry.ut_pid = proc->pid; + + setutxent(); + pututxline(&entry); + endutxent(); + + return; +} + +int user_connected(main_server_st *s, struct proc_st* proc, struct lease_st* lease) +{ +int ret; + + add_utmp_entry(s, proc, lease); + + ret = call_connect_script(s, proc, lease); + if (ret < 0) + return ret; + + return 0; +} + +void user_disconnected(main_server_st *s, struct proc_st* proc) +{ + remove_utmp_entry(s, proc); + call_disconnect_script(s, proc); +} + diff --git a/src/main.c b/src/main.c index 11be462b..7209f03e 100644 --- a/src/main.c +++ b/src/main.c @@ -575,7 +575,7 @@ fork_failed: /* received a bad command from worker */ kill(ctmp->pid, SIGTERM); } - call_disconnect_script(&s, ctmp); + user_disconnected(&s, ctmp); remove_proc(ctmp); active_clients--; } diff --git a/src/main.h b/src/main.h index 54f94a5d..a0a6319b 100644 --- a/src/main.h +++ b/src/main.h @@ -54,8 +54,8 @@ void clear_lists(main_server_st *s); int handle_commands(main_server_st *s, struct proc_st* cur); -int call_connect_script(main_server_st *s, struct proc_st* cur, struct lease_st*); -void call_disconnect_script(main_server_st *s, struct proc_st* cur); +int user_connected(main_server_st *s, struct proc_st* cur, struct lease_st*); +void user_disconnected(main_server_st *s, struct proc_st* cur); void expire_tls_sessions(main_server_st *s); diff --git a/src/ocserv-args.c b/src/ocserv-args.c index c8011194..4bf6e7ff 100644 --- a/src/ocserv-args.c +++ b/src/ocserv-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.c) * - * It has been AutoGen-ed February 5, 2013 at 10:37:10 PM by AutoGen 5.16 + * It has been AutoGen-ed February 6, 2013 at 06:03:52 PM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 4b9c1422..3271e36b 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -117,6 +117,9 @@ disconnect-script = /bin/echo # Cookie database file. Where to store the cookies. cookie-db = /path/to/db +# UTMP +use-utmp = true + run-as-user = nobody run-as-group = nogroup diff --git a/src/ocserv-args.h b/src/ocserv-args.h index af82161c..b6168a39 100644 --- a/src/ocserv-args.h +++ b/src/ocserv-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.h) * - * It has been AutoGen-ed February 5, 2013 at 10:37:10 PM by AutoGen 5.16 + * It has been AutoGen-ed February 6, 2013 at 06:03:51 PM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/sample.config b/src/sample.config index ade5fdbc..1e380890 100644 --- a/src/sample.config +++ b/src/sample.config @@ -3,6 +3,9 @@ # Options: certificate, pam. auth = "pam" +# UTMP +use-utmp = true + # Limit the number of clients. Set to zero for unlimited. # max-clients = 1024 max-clients = 4 diff --git a/src/vpn.h b/src/vpn.h index b653bba1..5dbec66d 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -62,6 +62,7 @@ struct cfg_st { unsigned tls_debug; unsigned debug; unsigned max_clients; + unsigned use_utmp; const char *connect_script; const char *disconnect_script;