--- src/openvpn/multi.h.orig 2024-03-20 00:19:35.000000000 +0300 +++ src/openvpn/multi.h 2024-06-19 00:29:08.456014000 +0300 @@ -702,6 +702,8 @@ multi_set_pending(struct multi_context *m, struct mult * postprocessed. */ void multi_assign_peer_id(struct multi_context *m, struct multi_instance *mi); +void multi_sysacct_session_start(struct multi_instance *const mi); +void multi_sysacct_session_stop(struct multi_instance *const mi); #endif /* MULTI_H */ --- src/openvpn/multi.c.orig 2024-03-20 00:19:35.000000000 +0300 +++ src/openvpn/multi.c 2024-06-19 00:40:29.796985000 +0300 @@ -21,6 +21,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include +#include +#include +#include + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -52,6 +57,70 @@ #include "dco.h" #include "reflect_filter.h" +void +multi_sysacct_session_start(struct multi_instance *const mi) +{ + struct utmpx ut; + struct in_addr ia; + const char *username = NULL; + + if (mi == NULL || mi->context.c2.tls_multi == NULL) + return; + if (getenv("OPENVPN_SYSACCT") == NULL) + return; + + if (mi->context.c1.auth_user_pass) + username = mi->context.c1.auth_user_pass->username; + if (username == NULL || username[0] == '\0') + username = tls_common_name(mi->context.c2.tls_multi, true); + if (username == NULL) + return; + + memset(&ut, 0, sizeof(ut)); + ut.ut_type = USER_PROCESS; + ut.ut_pid = getpid(); + + snprintf(ut.ut_id, sizeof(ut.ut_id), "o%x", + (unsigned)(mi->context.c2.tls_multi->peer_id & MAX_PEER_ID)); + snprintf(ut.ut_user, sizeof(ut.ut_user), "%s", username); + + ia.s_addr = htonl(mi->context.c2.push_ifconfig_local); + inet_ntop(AF_INET, &ia, ut.ut_line, sizeof(ut.ut_line)); + + switch (mi->real.type & MR_ADDR_MASK) + { + case MR_ADDR_IPV4: + inet_ntop(AF_INET, &mi->real.v4, ut.ut_host, sizeof(ut.ut_host)); + break; + case MR_ADDR_IPV6: + inet_ntop(AF_INET6, &mi->real.v6, ut.ut_host, sizeof(ut.ut_host)); + break; + default: + snprintf(ut.ut_host, sizeof(ut.ut_host), "%s", "UNKNOWN"); + } + gettimeofday(&ut.ut_tv, NULL); + pututxline(&ut); +} + +void +multi_sysacct_session_stop(struct multi_instance *const mi) +{ + struct utmpx ut; + + if (mi == NULL || mi->context.c2.tls_multi == NULL) + return; + if (getenv("OPENVPN_SYSACCT") == NULL) + return; + + memset(&ut, 0, sizeof(ut)); + ut.ut_type = DEAD_PROCESS; + ut.ut_pid = getpid(); + snprintf(ut.ut_id, sizeof(ut.ut_id), "o%x", + (unsigned)(mi->context.c2.tls_multi->peer_id & MAX_PEER_ID)); + gettimeofday(&ut.ut_tv, NULL); + pututxline(&ut); +} + /*#define MULTI_DEBUG_EVENT_LOOP*/ #ifdef MULTI_DEBUG_EVENT_LOOP @@ -610,6 +679,7 @@ multi_close_instance(struct multi_context *m, dmsg(D_MULTI_DEBUG, "MULTI: multi_close_instance called"); + multi_sysacct_session_stop(mi); /* adjust current client connection count */ m->n_clients += mi->n_clients_delta; update_mstat_n_clients(m->n_clients); @@ -2503,6 +2573,7 @@ multi_client_connect_late_setup(struct multi_context * /* set context-level authentication flag */ mi->context.c2.tls_multi->multi_state = CAS_CONNECT_DONE; + multi_sysacct_session_start(mi); /* authentication complete, calculate dynamic client specific options */ if (!multi_client_set_protocol_options(&mi->context)) --- src/openvpn/options.c.orig 2024-03-20 00:19:35.000000000 +0300 +++ src/openvpn/options.c 2024-06-19 00:29:08.460803000 +0300 @@ -8353,13 +8353,17 @@ add_option(struct options *options, #else /* ifdef _WIN32 */ else if (streq(p[0], "user") && p[1] && !p[2]) { + if(getenv("OPENVPN_SYSACCT") == NULL) { VERIFY_PERMISSION(OPT_P_GENERAL); options->username = p[1]; + } } else if (streq(p[0], "group") && p[1] && !p[2]) { + if(getenv("OPENVPN_SYSACCT") == NULL) { VERIFY_PERMISSION(OPT_P_GENERAL); options->groupname = p[1]; + } } else if (streq(p[0], "dhcp-option") && p[1] && !p[3]) {