--- src/libcharon/plugins/updown/updown_listener.c.orig 2023-03-28 04:00:49.000000000 +0700 +++ src/libcharon/plugins/updown/updown_listener.c 2023-11-10 11:27:27.939500000 +0700 @@ -16,6 +16,11 @@ * for more details. */ +#include +#include +#include +#include + #define _GNU_SOURCE #include #include @@ -25,6 +30,7 @@ #include #include #include +#include typedef struct private_updown_listener_t private_updown_listener_t; @@ -254,6 +260,7 @@ static char* get_port(traffic_selector_t *me, traffic_ */ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, child_cfg_t *config, bool up, + bool sysacct, traffic_selector_t *my_ts, traffic_selector_t *other_ts) { host_t *me, *other, *host; @@ -267,6 +274,7 @@ static void invoke_once(private_updown_listener_t *thi process_t *process; char port_buf[PORT_BUF_LEN]; char *envp[128] = {}; + struct utmpx ut; me = ike_sa->get_my_host(ike_sa); other = ike_sa->get_other_host(ike_sa); @@ -310,6 +318,16 @@ static void invoke_once(private_updown_listener_t *thi iface ? iface : "unknown"); push_env(envp, countof(envp), "PLUTO_REQID=%u", child_sa->get_reqid(child_sa)); + if (sysacct) { + memset(&ut, 0, sizeof(ut)); + ut.ut_type = USER_PROCESS; + ut.ut_pid = getpid(); + gettimeofday(&ut.ut_tv, NULL); + /* ut.ut_id has space for 7 chars plus terminating zero */ + snprintf(ut.ut_id, sizeof(ut.ut_id), "rid%hx", + (unsigned short)child_sa->get_reqid(child_sa)); + } + push_env(envp, countof(envp), "PLUTO_PROTO=%s", child_sa->get_protocol(child_sa) == PROTO_ESP ? "esp" : "ah"); push_env(envp, countof(envp), "PLUTO_UNIQUEID=%u", @@ -328,6 +346,8 @@ static void invoke_once(private_updown_listener_t *thi push_env(envp, countof(envp), "PLUTO_MY_PROTOCOL=%u", my_ts->get_protocol(my_ts)); push_env(envp, countof(envp), "PLUTO_PEER=%H", other); + if (sysacct) + snprintf(ut.ut_host, sizeof(ut.ut_host), "%H", other); push_env(envp, countof(envp), "PLUTO_PEER_ID=%Y", ike_sa->get_other_id(ike_sa)); if (!other_ts->to_subnet(other_ts, &host, &mask)) @@ -336,6 +356,8 @@ static void invoke_once(private_updown_listener_t *thi "by next larger subnet", other_ts); } push_env(envp, countof(envp), "PLUTO_PEER_CLIENT=%+H/%u", host, mask); + if (sysacct) + snprintf(ut.ut_line, sizeof(ut.ut_line), "%H", host); host->destroy(host); push_env(envp, countof(envp), "PLUTO_PEER_PORT=%s", get_port(my_ts, other_ts, port_buf, FALSE)); @@ -346,7 +368,18 @@ static void invoke_once(private_updown_listener_t *thi { push_env(envp, countof(envp), "PLUTO_XAUTH_ID=%Y", ike_sa->get_other_eap_id(ike_sa)); + if (sysacct) + snprintf(ut.ut_user, sizeof(ut.ut_user), "%Y", + ike_sa->get_other_eap_id(ike_sa)); } + if (sysacct) { + if (!ut.ut_user[0]) + snprintf(ut.ut_user, sizeof(ut.ut_user), "%Y", + ike_sa->get_other_id(ike_sa)); + gettimeofday(&ut.ut_tv, NULL); + pututxline(&ut); + } + push_vip_env(this, ike_sa, envp, countof(envp), TRUE); push_vip_env(this, ike_sa, envp, countof(envp), FALSE); mark = child_sa->get_mark(child_sa, TRUE); @@ -434,14 +467,18 @@ METHOD(listener_t, child_updown, bool, traffic_selector_t *my_ts, *other_ts; enumerator_t *enumerator; child_cfg_t *config; + int count; config = child_sa->get_config(child_sa); if (config->get_updown(config)) { + count = getenv("STRONGSWAN_SYSACCT") ? 0 : -1; enumerator = child_sa->create_policy_enumerator(child_sa); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - invoke_once(this, ike_sa, child_sa, config, up, my_ts, other_ts); + if (count >= 0) + count++; + invoke_once(this, ike_sa, child_sa, config, up, count == 1, my_ts, other_ts); } enumerator->destroy(enumerator); } --- src/libcharon/bus/bus.c.orig 2023-03-28 04:00:49.000000000 +0700 +++ src/libcharon/bus/bus.c 2023-11-10 11:36:34.124367000 +0700 @@ -17,7 +17,13 @@ #include "bus.h" +#include +#include #include +#include +#include +#include +#include #include #include @@ -801,6 +807,8 @@ METHOD(bus_t, ike_updown, void, enumerator_t *enumerator; entry_t *entry; bool keep; + int count; + struct utmpx ut; this->mutex->lock(this->mutex); enumerator = this->listeners->create_enumerator(this->listeners); @@ -827,6 +835,7 @@ METHOD(bus_t, ike_updown, void, enumerator_t *enumerator; child_sa_t *child_sa; + count = 0; enumerator = ike_sa->create_child_sa_enumerator(ike_sa); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { @@ -834,6 +843,15 @@ METHOD(bus_t, ike_updown, void, child_sa->get_state(child_sa) != CHILD_DELETED) { child_updown(this, child_sa, FALSE); + if (++count == 1 && getenv("STRONGSWAN_SYSACCT")) { + memset(&ut, 0, sizeof(ut)); + ut.ut_type = DEAD_PROCESS; + ut.ut_pid = getpid(); + snprintf(ut.ut_id, sizeof(ut.ut_id), "rid%hx", + (unsigned short)child_sa->get_reqid(child_sa)); + gettimeofday(&ut.ut_tv, NULL); + pututxline(&ut); + } } } enumerator->destroy(enumerator);