WTMP support for OpenVPN 2.1
Hi!
This is an initial attempt to let OpenVPN 2.1 write a wtmp log of all connections including the username, it's VPN IP and the real remote IP the user connected from.
This provides an OpenVPN admin with a simple database of all connections of his VPN servers and the possibility to easily see if anyone is using the VPN server currently.
It is possible to let multiple instances of OpenVPN on the same host use the same wtmp file by specifying different "server ids" which are a two digit integer which will be used in the wtmp line string to distinguish between vpn sessions.
This implementation does work, but has some things which have to be done better:
* There has to be used a unique session id per VPN session which does not change between reconnecteds (currently the ssl session_id is used as identifier)
* At the moment the uid/gid for the username/groupname config options are looked up by hand in wtmp_init() as the context->c0 struct is not yet available.
Maybe wtmp_init() could be called a bit later at a usefull place to avoid this doulbe lookup.
These are the "known bugs" my implementation has, but which are still on my todo list (the second one is kind of WORKS_FOR_ME) :)
So if anyone has comments or ideas how to do things better, don't hasitate and let me know.
I would very much like to get thos included in OpenVPN as it will help people to have an overview about the usage of the VPNs and was requested earlier.
Ciao
Max
PATCH 1/1 Let multi.c call wtmp_* routines when ENABLE_WTMP is defined.
--- multi.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
multi.c +16 -0
@@ -42,6 +42,10 @@#include "forward-inline.h" +#ifdef ENABLE_WTMP +#include "wtmp.h" +#endif +/*#define MULTI_DEBUG_EVENT_LOOP*/ #ifdef MULTI_DEBUG_EVENT_LOOP
@@ -457,6 +461,10 @@ multi_close_instance (struct multi_context *m,dmsg (D_MULTI_DEBUG ,"MULTI: multi_close_instance called" ); +#ifdef ENABLE_WTMP +wtmp_stop (mi); +#endif +/* prevent dangling pointers */ if (m->pending == mi)multi_set_pending (m,NULL );
@@ -1444,6 +1452,10 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi }#endif +#ifdef ENABLE_WTMP +wtmp_start (mi); +#endif +/* * Run --client-connect script. */
@@ -2289,6 +2301,10 @@ tunnel_server (struct context *top) {ASSERT (top->options.mode ==MODE_SERVER ); +#ifdef ENABLE_WTMP +wtmp_init (); +#endif +switch (top->options.proto) {case PROTO_UDPv4:tunnel_server_udp (top);
Signature · 1 line
1.5.2.4
PATCH 1/1 Added the ability to configure wtmp logging:
In reply to Maximilian Wilhelm --log-wtmp server_id [file] : Enable logging to wtmp file using the two digit
server_id a prefix for the utmp line. Optionally you can write to an own wtmp file. (Default is /var/log/ovpnwtmp.
--- options.c | 31 +++++++++++++++++++++++++++++++ options.h | 6 ++++++ 2 files changed, 37 insertions(+), 0 deletions(-)
options.c +31 -0
@@ -266,6 +266,11 @@ static const char usage_message[] = "--suppress-timestamps : Don't log timestamps to stdout/stderr.\n" "--writepid file : Write main process ID to file.\n" "--nice n : Change process priority (>0 = lower, <0 = higher).\n" +#ifdef ENABLE_WTMP + "--log-wtmp server_id [file] : Enable logging to wtmp file using the two digit\n" + " server_id a prefix for the utmp line. Optionally you can write\n" + " to an own wtmp file. (Default is /var/log/ovpnwtmp.\n" +#endif#if 0 #ifdef USE_PTHREAD "--nice-work n : Change thread priority of work thread. The work\n"
@@ -697,6 +702,12 @@ init_options (struct options *o)#ifdef ENABLE_PKCS11 o->pkcs11_pin_cache_period =-1 ;#endif /* ENABLE_PKCS11 */ + +#ifdef ENABLE_WTMP + o->log_wtmp =0 ; + o->wtmp_server_id =1 ; + o->wtmp_file ="/var/log/ovpnwtmp" ; +#endif }void
@@ -3473,6 +3484,25 @@ add_option (struct options *options, options->log = true;redirect_stdout_stderr (p[1 ], false); } + +#ifdef ENABLE_WTMP + else if (streq (p[0], "log-wtmp") && p[1]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); + +/* Activate WTMP logging */ + options->log_wtmp =1 ; + +/* Use server_id if set */ +if (p[1 ]) + options->wtmp_server_id =atoi (p[1 ]); + +/* User specified wtmp file if set */ +if (p[2 ]) + options->wtmp_file = p[2 ]; + } +#endif + else if (streq (p[0], "suppress-timestamps")) {VERIFY_PERMISSION (OPT_P_GENERAL );
@@ -3773,6 +3803,7 @@ add_option (struct options *options,openvpn_exit (OPENVPN_EXIT_STATUS_GOOD );/* exit point */ }#endif /* GENERAL_PROXY_SUPPORT */ +#ifdef ENABLE_HTTP_PROXY else if (streq (p[0], "http-proxy") && p[1]) {
options.h +6 -0
@@ -214,6 +214,12 @@ struct options/* inetd modes defined in socket.h */ int inetd; +#ifdef ENABLE_WTMP +int log_wtmp; +int wtmp_server_id; +char *wtmp_file; +#endif +bool log;bool suppress_timestamps;int nice;
Signature · 1 line
1.5.2.4
PATCH 1/1 Let OpenVPN write wtmp entries if configured so.
In reply to Maximilian Wilhelm--- multi.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-)
multi.c +7 -3
@@ -462,7 +462,9 @@ multi_close_instance (struct multi_context *m,dmsg (D_MULTI_DEBUG ,"MULTI: multi_close_instance called" );#ifdef ENABLE_WTMP -wtmp_stop (mi); +if (m->top.options.log_wtmp ==1 ) +wtmp_stop (mi); +#endif /* prevent dangling pointers */
@@ -1453,7 +1455,8 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi#endif #ifdef ENABLE_WTMP -wtmp_start (mi); +if (m->top.options.log_wtmp ==1 ) +wtmp_start (mi);#endif /*
@@ -2302,7 +2305,8 @@ tunnel_server (struct context *top)ASSERT (top->options.mode ==MODE_SERVER );#ifdef ENABLE_WTMP -wtmp_init (); +if (top->options.log_wtmp ==1 ) +wtmp_init (top->options.wtmp_server_id, top->options.wtmp_file);#endif switch (top->options.proto) {
Signature · 1 line
1.5.2.4
PATCH 1/1 Added WTMP support for OpenVPN
In reply to Maximilian Wilhelm--- wtmp.c | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ wtmp.h | 27 +++++ 2 files changed, 360 insertions(+), 0 deletions(-) create mode 100644 wtmp.c create mode 100644 wtmp.h
wtmp.c new file +333 -0
@@ -0,0 +1,333 @@ +/* +* OpenVPN wtmp support +* +* Copyright: 2007 Maximilian Wilhelm <[email protected]...> +* +*/ + +#include "config.h" +#include "syshead.h" + +#ifdef ENABLE_WTMP + +#define _GNU_SOURCE + +#include <assert.h> +#include <dirent.h> /* opendir() */ +#include <stdio.h> /* fopen() */ +#include <stdlib.h> /* *alloc(), free() */ +#include <string.h> /* strncpy(), strlen() */ +#include <sys/stat.h> /* stat() */ +#include <sys/time.h> /* struct timeval */ +#include <sys/types.h> /* opendir() */ +#include <utmp.h> /* utmp foo */ + +#include "openvpn.h" /* struct context* */ +#include "forward.h" +#include "forward-inline.h" +#include "multi.h" /* struct multi_instance */ +#include "buffer.h" /* struct buffer */ + +#include "wtmp.h" + +int wtmp_active =0 ; + +#define HAVE_ENDUTENT 1 + +#define OVPN_WTMP_DEBUG 1 + +/* +* Initialize wtmp subsystem +*/ +int +wtmp_init (unsigned int server_id,const char *wtmp_file_path) +{ +#ifdef OVPN_WTMP_DEBUG +fprintf (stderr,"%s() called.\n" , __FUNCTION__); +#endif + +struct stat wtmp_stat; +char *wtmp_file_dirname; +char *wtmp_file_path_copy; + +/* Only initialize once */ +if (wtmp_active ==1 ) +return 1 ; + +#ifdef OVPN_WTMP_DEBUG +fprintf (stderr,"wtmp_file_path = %s\n" , wtmp_file_path); +#endif + + wtmp_file_path_copy =strdup (wtmp_file_path); + wtmp_file_dirname =dirname (wtmp_file_path_copy); + +/* Check if WTMP_DIR exists and try to create it if not */ +if (!opendir (wtmp_file_dirname)) { +fprintf (stderr,"%s: wtmp_file_dirname %s does not exist. Trying to create it.\n" , + __FUNCTION__, wtmp_file_dirname); + +if (mkdir (wtmp_file_dirname,0700 )) { +fprintf (stderr,"%s: Could not create directory %s\n" , + __FUNCTION__, wtmp_file_dirname); + wtmp_active =0 ; + goto out; + } + +fprintf (stderr,"%s: Successfully created wtmp_file_dirname %s.\n" , + __FUNCTION__, wtmp_file_dirname); + } + +/* Check if wtmp_file_path exists and try to create it if not */ +if (stat (wtmp_file_path, &wtmp_stat)) { +fprintf (stderr,"%s: wtmp_file %s does not exist or is not accessable. Trying to create it.\n" , + __FUNCTION__, wtmp_file_path); + +/* Touch wtmp_file */ +if (!fopen (wtmp_file_path,"a" )) { +fprintf (stderr,"%s: Could not create file %s.\n" , + __FUNCTION__, wtmp_file_path); + wtmp_active =0 ; + goto out; + } + +fprintf (stderr,"%s: Successfully created wtmp_file %s.\n" , + __FUNCTION__, wtmp_file_path); + }/* [ ! -f wtmp_file ] */ + +/* OK wtmp_file is (now) there, use it */ +utmpname (wtmp_file_path); + +/* Everything is fine */ + wtmp_active =1 ; + +out: +free (wtmp_file_path_copy); + +return wtmp_active; +} + + +void +wtmp_start (const struct multi_instance *mi) +{ +#ifdef OVPN_WTMP_DEBUG +fprintf (stderr,"%s() called.\n" , __FUNCTION__); +#endif + +struct utmp entry; +struct sockaddr_in *remote_addr; + +char *temp; + +if (wtmp_active ==0 ) +return ; + +/* Get IP address of this connection +* FIXME: IPv6?! +*/ + remote_addr =get_remote_sockaddr_from_multi_instance (mi); +if (! remote_addr) { +fprintf (stderr,"%s: get_remote_sockaddr_from_multi_instance (mi) failed.\n" , + __FUNCTION__); + } + +/* Clear entry */ +memset (&entry,'\0' ,sizeof (entry)); + +/* This entry is a user process */ + entry.ut_type =USER_PROCESS ; + +/* The connection started now, so set epoch time */ +set_utmp_time (&entry); + +/* Set the user name */ +set_utmp_username (mi, &entry); + +/* Set the line */ +set_utmp_line (mi, &entry); + +/* Store the IP we gave this client as the hostname */ +set_utmp_hostname (mi, &entry); + +/* Use the first 4 chars of the session ID as id */ +set_utmp_id (mi, &entry); + +/* Store the remote client IP(v4), if available */ + entry.ut_addr = remote_addr->sin_addr.s_addr; + +#ifdef OVPN_WTMP_DEBUG +fprintf (stderr,"%s: entry.ut_line = \"%s\"\n" , __FUNCTION__, entry.ut_line); +fprintf (stderr,"%s: entry.ut_id = \"%s\"\n" , __FUNCTION__, entry.ut_id); +fprintf (stderr,"%s: entry.ut_user = \"%s\"\n" , __FUNCTION__, entry.ut_user); +fprintf (stderr,"%s: entry.ut_host = \"%s\"\n" , __FUNCTION__, entry.ut_host); + +unsigned int ip =ntohl (entry.ut_addr); +fprintf (stderr,"%s: entry.ut_addr = %d.%d.%d.%d\n" , __FUNCTION__, ip >>24 , (ip >>16 ) &0xff , (ip >>8 ) &0xff , (ip >>0 ) &0xff ); +#endif + +updwtmp (mi->context.options.wtmp_file, &entry); +} + + +void +wtmp_stop (const struct multi_instance *mi) +{ +#ifdef OVPN_WTMP_DEBUG +fprintf (stderr,"%s() called.\n" , __FUNCTION__); +#endif + +struct utmp entry; + +if (wtmp_active ==0 ) +return ; + +/* Clear entry */ +memset (&entry,'\0' ,sizeof (entry)); + +/* The connection stopped now, so set epoch time */ +set_utmp_time (&entry); + +/* He's dead jim */ + entry.ut_type =DEAD_PROCESS ; + +/* Set current epoch time */ +set_utmp_time (&entry); + +/* Set the line */ +set_utmp_line (mi, &entry); + +/* Use the first 4 chars of the session ID as id */ +set_utmp_id (mi, &entry); + + entry.ut_host[0 ] =0 ; + +#ifdef OVPN_WTMP_DEBUG +fprintf (stderr,"%s: entry.ut_line = %s\n" , __FUNCTION__, entry.ut_line); +fprintf (stderr,"%s: entry.ut_id = %s\n" , __FUNCTION__, entry.ut_id); +#endif + +updwtmp (mi->context.options.wtmp_file, &entry); +} + + + + + +/* Build up and store an utmp line */ +void +set_utmp_line (const struct multi_instance *mi,struct utmp *entry) +{ +struct gc_arena gc =gc_new (); +char *temp; + +char line[UT_LINESIZE ]; + +/* Should be config option */ +unsigned int server_num =1 ; + +assert (mi); +assert (entry); + + temp =format_hex_ex (mi->context.c2.tls_multi->session[TM_ACTIVE ].session_id.id,SID_SIZE ,0 ,4 ,"" , &gc); + +if (temp) { +snprintf (entry->ut_line,UT_LINESIZE ,"ovpn%02d-%s" , server_num, temp); + }else { +snprintf (entry->ut_line,UT_LINESIZE ,"ovpn%02d" , server_num); + } +} + + +/* Store the first 4 chars of the session_id as the utmp id */ +void +set_utmp_id (const struct multi_instance *mi,struct utmp *entry) +{ +struct gc_arena gc =gc_new (); +char *temp; + +assert (mi); +assert (entry); + + temp =format_hex_ex (mi->context.c2.tls_multi->session[TM_ACTIVE ].session_id.id,SID_SIZE ,0 ,4 ," " , &gc); +if (temp) { +snprintf (entry->ut_id,4 ,"%s" , temp); + } +} + + +/* Store a human readable format of the VPN ip address we gave to the client as utmp hostname */ +void +set_utmp_hostname (const struct multi_instance *mi,struct utmp *entry) +{ +unsigned int ip; + +assert (mi); +assert (entry); + +memset (entry->ut_host,'\0' ,UT_HOSTSIZE ); + + ip = mi->context.c2.push_ifconfig_local; +snprintf (entry->ut_host,UT_HOSTSIZE ,"%d.%d.%d.%d" , ip >>24 , (ip >>16 ) &0xff , (ip >>8 ) &0xff , (ip >>0 ) &0xff ); +} + + +/* Store the username of the current session in the utmp entry */ +void +set_utmp_username (const struct multi_instance *mi,struct utmp *entry) +{ +const char *username; + +assert (mi); +assert (entry); + + username =tls_common_name (mi->context.c2.tls_multi, false); +if (username) { +snprintf (entry->ut_user,UT_NAMESIZE ,"%s" , username); + }else { +snprintf (entry->ut_user,UT_NAMESIZE ,"unknown" ); + } +} + + +/* Get a sockaddr_in struct containing the real IP of the remote host */ +static struct sockaddr_in * +get_remote_sockaddr_from_multi_instance (const struct multi_instance *mi) +{ +struct buffer buf ; +struct link_socket_actual *lsa; + +assert (mi); + + lsa =calloc (1 ,sizeof (struct link_socket_actual )); +if (! lsa) +return NULL ; + +link_socket_get_outgoing_addr (&buf,get_link_socket_info (&mi->context), &lsa); + +return &lsa->dest.sa; +} + + +/* +* Some helper functions, partly stolen from OpenSSH/loginrec.c +* +*/ + + +/* Store the current time in utmp struct */ +static void +set_utmp_time (struct utmp *ut) +{ +struct timeval tv; + +assert (ut); + +gettimeofday (&tv,NULL ); + ut->ut_tv.tv_sec = tv.tv_sec; + ut->ut_tv.tv_usec = tv.tv_usec; + + ut->ut_time = tv.tv_sec; +} +#endif /* ENABLE_WTMP */ + +
wtmp.h new file +27 -0
@@ -0,0 +1,27 @@ +#ifndef _OPENVPN_WTMP_H +#define _OPENVPN_WTMP_H + +#include <utmp.h> + +#include "multi.h" + +#define OVPN_WTMP_DIR "/tmp" +#define OVPN_WTMP_FILENAME "ovpnwtmp" + +enum local_remote {LOCAL ,REMOTE }; + +int wtmp_init (); + +void wtmp_start (const struct multi_instance *mi); +void wtmp_stop (const struct multi_instance *mi); + +static void set_utmp_time (struct utmp *ut); + +void set_utmp_hostname (const struct multi_instance *mi,struct utmp *entry); +void set_utmp_id (const struct multi_instance *mi,struct utmp *entry); +void set_utmp_line (const struct multi_instance *mi,struct utmp *entry); +void set_utmp_username (const struct multi_instance *mi,struct utmp *entry); + +static struct sockaddr_in *get_remote_sockaddr_from_multi_instance (const struct multi_instance *mi); + +#endif /* _OPENVPN_WTMP_H */
Signature · 1 line
1.5.2.4
PATCH 1/1 Let Makefile.am build wtmp, too.
In reply to Maximilian Wilhelm--- Makefile.am | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
Makefile.am +2 -1
@@ -94,7 +94,8 @@ openvpn_SOURCES = \ status.c status.h \ syshead.h \ thread.c thread.h \ - tun.c tun.h + tun.c tun.h \ + wtmp.c wtmp .h LDADD = @LIBOBJS@
Signature · 1 line
1.5.2.4
PATCH 1/1 Push a pointer to the whole options struct to wtmp_init()
In reply to Maximilian WilhelmThis change introduces the ability to figure out as which user OpenVPN will run after dropping privileges. This is very usefull when creating the wtmp file, which by default is owned by root resulting in OpenVPN not being able to write to it.
So now the owner and group can be changed to the names specified in the configuration.
--- multi.c | 2 +- options.c | 3 ++- wtmp.c | 13 +++++++++---- wtmp.h | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-)
multi.c +1 -1
@@ -2306,7 +2306,7 @@ tunnel_server (struct context *top)#ifdef ENABLE_WTMP if (top->options.log_wtmp ==1 ) -wtmp_init (top->options.wtmp_server_id, top->options.wtmp_file); +wtmp_init (&top->options);#endif switch (top->options.proto) {
options.c +2 -1
@@ -3500,7 +3500,8 @@ add_option (struct options *options,/* User specified wtmp file if set */ if (p[2 ]) options->wtmp_file = p[2 ]; - } + + }#endif else if (streq (p[0], "suppress-timestamps"))
wtmp.c +9 -4
@@ -32,28 +32,33 @@int wtmp_active =0 ; -#define HAVE_ENDUTENT 1 - -#define OVPN_WTMP_DEBUG 1 +// #define OVPN_WTMP_DEBUG 1 /* * Initialize wtmp subsystem */ int -wtmp_init (unsigned int server_id,const char *wtmp_file_path) +wtmp_init (const struct options *vpn_options) {#ifdef OVPN_WTMP_DEBUG fprintf (stderr,"%s() called.\n" , __FUNCTION__);#endif struct stat wtmp_stat; + +char *wtmp_file_path; +char *wtmp_file_dirname;char *wtmp_file_path_copy; +assert (options); +/* Only initialize once */ if (wtmp_active ==1 )return 1 ; + wtmp_file_path = vpn_options->wtmp_file; +#ifdef OVPN_WTMP_DEBUG fprintf (stderr,"wtmp_file_path = %s\n" , wtmp_file_path);#endif
wtmp.h +1 -1
@@ -10,7 +10,7 @@enum local_remote {LOCAL ,REMOTE }; -int wtmp_init (); +int wtmp_init (const struct options *vpn_options);void wtmp_start (const struct multi_instance *mi);void wtmp_stop (const struct multi_instance *mi);
Signature · 1 line
1.5.2.4
PATCH 1/1 Let set_utmp_line() use the configured 'server_id' as prefix in utmp line string
In reply to Maximilian Wilhelm Now every utmp line will look like "ovpn%d-%s" where %d are the two last digits of the server_id and %s some chars of the session_id (as many as fit into the remaining space in 'ut_line'.
This provides the ability to let at most 100 OpenVPN instances on one single maschine write to the same wtmp file and you are still able to distinguish which instance created which entry.
--- wtmp.c | 14 +++++--------- 1 files changed, 5 insertions(+), 9 deletions(-)
wtmp.c +5 -9
@@ -216,29 +216,25 @@ fprintf (stderr, "%s: entry.ut_id = %s\n", __FUNCTION__, entry.ut_id); - -/* Build up and store an utmp line */ void set_utmp_line (const struct multi_instance *mi,struct utmp *entry) {struct gc_arena gc =gc_new (); -char *temp; -char line[UT_LINESIZE ]; - -/* Should be config option */ -unsigned int server_num =1 ; +char *temp; +unsigned int server_id assert (mi);assert (entry); + server_id = mi->context.options.wtmp_server_id %100 ; temp =format_hex_ex (mi->context.c2.tls_multi->session[TM_ACTIVE ].session_id.id,SID_SIZE ,0 ,4 ,"" , &gc);if (temp) { -snprintf (entry->ut_line,UT_LINESIZE ,"ovpn%02d-%s" , server_num, temp); +snprintf (entry->ut_line,UT_LINESIZE ,"ovpn%02d-%s" , server_id, temp); }else { -snprintf (entry->ut_line,UT_LINESIZE ,"ovpn%02d" , server_num); +snprintf (entry->ut_line,UT_LINESIZE ,"ovpn%02d" , server_id); } }
Signature · 1 line
1.5.2.4
PATCH 1/1 wtmp_init() does not honor username/groupname config options and chown()s wtmp file
In reply to Maximilian Wilhelm Now wtmp_init() does try to lookup the uid for "username" and the gid for "groupname" if configured and - if successfull - chown the wtmp file to this combination.
(The lookup of uid/gid is neccessary here as 'context->c0' is no yet
initialized at the point wtmp_init() is called.)
--- wtmp.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 43 insertions(+), 4 deletions(-)
wtmp.c +43 -4
@@ -12,14 +12,16 @@#define _GNU_SOURCE -#include <assert.h> +#include <assert.h> /* assert() */ #include <dirent.h> /* opendir() */ +#include <pwd.h> /* struct passwd */ #include <stdio.h> /* fopen() */ #include <stdlib.h> /* *alloc(), free() */ #include <string.h> /* strncpy(), strlen() */ #include <sys/stat.h> /* stat() */ #include <sys/time.h> /* struct timeval */ -#include <sys/types.h> /* opendir() */ +#include <sys/types.h> /* opendir() chown() */ +#include <unistd.h> /* chown() */ #include <utmp.h> /* utmp foo */ #include "openvpn.h" /* struct context* */
@@ -46,12 +48,20 @@ wtmp_init (const struct options *vpn_options)struct stat wtmp_stat; +/* These will be used when getting the uid/gid to chown the wtmp file */ +struct passwd *pw; +struct group *grp; +unsigned short do_chmod =2 ; +uid_t uid =-1 ; +gid_t gid =-1 ; + +/* The wtmp file we're going to write to */ char *wtmp_file_path;char *wtmp_file_dirname;char *wtmp_file_path_copy; -assert (options); +assert (vpn_options);/* Only initialize once */ if (wtmp_active ==1 )
@@ -66,6 +76,24 @@ wtmp_init (const struct options *vpn_options) wtmp_file_path_copy =strdup (wtmp_file_path); wtmp_file_dirname =dirname (wtmp_file_path_copy); +/* Get UID and GID of the configured user and group */ +if (vpn_options->username) { + pw =getpwnam (vpn_options->username); +if (pw) + uid = pw->pw_uid; +else + do_chmod -=1 ; + } + +if (vpn_options->groupname) { + grp =getgrnam (vpn_options->groupname); +if (grp) + gid = grp->gr_gid; +else + do_chmod -=1 ; + + } +/* Check if WTMP_DIR exists and try to create it if not */ if (!opendir (wtmp_file_dirname)) { fprintf (stderr, "%s: wtmp_file_dirname %s does not exist. Trying to create it.\n",
@@ -99,6 +127,17 @@ wtmp_init (const struct options *vpn_options) __FUNCTION__, wtmp_file_path); }/* [ ! -f wtmp_file ] */ +/* Maybe one changed "username" and "group" config options */ +if (do_chmod ==2 ) { +if (chown (wtmp_file_path, uid, gid)) { +fprintf (stderr,"%s: Could not set owner/group of wtmp file %s.\n" , + __FUNCTION__, wtmp_file_path); + wtmp_active =0 ; + goto out; + } + } + +/* OK wtmp_file is (now) there, use it */ utmpname (wtmp_file_path);
@@ -223,7 +262,7 @@ set_utmp_line (const struct multi_instance *mi, struct utmp *entry)struct gc_arena gc =gc_new ();char *temp; -unsigned int server_id +unsigned int server_id;assert (mi);assert (entry);
Signature · 1 line
1.5.2.4
Am Monday, den 3 September hub Maximilian Wilhelm folgendes in die Tasten:
Hi!
Quoted 3 lines
This is an initial attempt to let OpenVPN 2.1 write a wtmp log of all connections including the username, it's VPN IP and the real remote IP the user connected from.
[...]
Is nobody interested in this?
That would be very sad.
Ciao
Max
Signature · 1 line
Follow the white penguin.