Thanks for the clarifications! I like the idea of moving some functionality into more general-purpose libraries whenever possible. Those libraries could then be - at least theoretically - used by other projects, so that the code gets more exposure and testing, as well as taking some of the maintenance load of our shoulders.
I give this one a feature-ACK, but could somebody else take a better look at the actual code changes? -- Samuli Seppänen Community Manager OpenVPN Technologies, Inc irc freenode net: mattock > Well, at first I wanted to split it into its own libplatform distinct > from libcompat. > > libcompat - emulation of missing library functions, drop-in replacement. > libplatform - extensions to library functions, such as unicode or > security additions. > > But then I've seen that there is too much openvpn specific logic, > especially in log messages. So I left what I would have placed in > libplatform in platform.c for now. > > After this round we should consider if we want to progress in this. > > One missing part is the exec wrappers which needs some work before > moving to platform. > > Alon. > > 2012/3/8 Samuli Seppänen <sam...@openvpn.net>: >> This probably makes sense, lots of good refactorings. That said, I'd >> like to know how you selected what goes to platform.c? >> >> -- >> Samuli Seppänen >> Community Manager >> OpenVPN Technologies, Inc >> >> irc freenode net: mattock >> >> >>> + Some fixups within the platform.c functions. >>> - need to check environment set on Windows. >>> >>> Signed-off-by: Alon Bar-Lev <alon.bar...@gmail.com> >>> --- >>> src/openvpn/Makefile.am | 1 + >>> src/openvpn/buffer.c | 2 +- >>> src/openvpn/crypto.c | 6 +- >>> src/openvpn/error.c | 2 +- >>> src/openvpn/init.c | 18 +- >>> src/openvpn/manage.c | 16 +- >>> src/openvpn/misc.c | 295 ++---------------------------------- >>> src/openvpn/misc.h | 106 +------------- >>> src/openvpn/mstats.c | 2 +- >>> src/openvpn/multi.c | 2 +- >>> src/openvpn/openvpn.h | 4 +- >>> src/openvpn/openvpn.vcproj | 8 + >>> src/openvpn/options.c | 14 +- >>> src/openvpn/packet_id.c | 2 +- >>> src/openvpn/pf.c | 6 +- >>> src/openvpn/platform.c | 369 >>> ++++++++++++++++++++++++++++++++++++++++++++ >>> src/openvpn/platform.h | 142 +++++++++++++++++ >>> src/openvpn/ps.c | 2 +- >>> src/openvpn/ssl_openssl.c | 2 +- >>> src/openvpn/ssl_verify.c | 8 +- >>> src/openvpn/status.c | 6 +- >>> src/openvpn/tun.c | 12 +- >>> src/openvpn/win32.c | 27 ---- >>> 23 files changed, 584 insertions(+), 468 deletions(-) >>> create mode 100644 src/openvpn/platform.c >>> create mode 100644 src/openvpn/platform.h >>> >>> diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am >>> index 333eebc..6ba12b8 100644 >>> --- a/src/openvpn/Makefile.am >>> +++ b/src/openvpn/Makefile.am >>> @@ -58,6 +58,7 @@ openvpn_SOURCES = \ >>> mbuf.c mbuf.h \ >>> memdbg.h \ >>> misc.c misc.h \ >>> + platform.c platform.h \ >>> console.c console.h \ >>> mroute.c mroute.h \ >>> mss.c mss.h \ >>> diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c >>> index ad30223..5eee3ee 100644 >>> --- a/src/openvpn/buffer.c >>> +++ b/src/openvpn/buffer.c >>> @@ -1080,7 +1080,7 @@ buffer_list_advance (struct buffer_list *ol, int n) >>> struct buffer_list * >>> buffer_list_file (const char *fn, int max_line_len) >>> { >>> - FILE *fp = openvpn_fopen (fn, "r"); >>> + FILE *fp = platform_fopen (fn, "r"); >>> struct buffer_list *bl = NULL; >>> >>> if (fp) >>> diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c >>> index 2e2e5d7..f811966 100644 >>> --- a/src/openvpn/crypto.c >>> +++ b/src/openvpn/crypto.c >>> @@ -868,7 +868,7 @@ read_key_file (struct key2 *key2, const char *file, >>> const unsigned int flags) >>> #endif >>> { >>> in = alloc_buf_gc (2048, &gc); >>> - fd = openvpn_open (file, O_RDONLY, 0); >>> + fd = platform_open (file, O_RDONLY, 0); >>> if (fd == -1) >>> msg (M_ERR, "Cannot open file key file '%s'", file); >>> size = read (fd, in.data, in.capacity); >>> @@ -1029,7 +1029,7 @@ read_passphrase_hash (const char *passphrase_file, >>> const int min_passphrase_size = 8; >>> uint8_t buf[64]; >>> int total_size = 0; >>> - int fd = openvpn_open (passphrase_file, O_RDONLY, 0); >>> + int fd = platform_open (passphrase_file, O_RDONLY, 0); >>> >>> if (fd == -1) >>> msg (M_ERR, "Cannot open passphrase file: '%s'", passphrase_file); >>> @@ -1079,7 +1079,7 @@ write_key_file (const int nkeys, const char *filename) >>> const int bytes_per_line = 16; >>> >>> /* open key file */ >>> - fd = openvpn_open (filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | >>> S_IWUSR); >>> + fd = platform_open (filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | >>> S_IWUSR); >>> >>> if (fd == -1) >>> msg (M_ERR, "Cannot open shared secret file '%s' for write", filename); >>> diff --git a/src/openvpn/error.c b/src/openvpn/error.c >>> index 1f2dd86..d6ad639 100644 >>> --- a/src/openvpn/error.c >>> +++ b/src/openvpn/error.c >>> @@ -640,7 +640,7 @@ x_check_status (int status, >>> my_errno); >>> >>> if (x_cs_err_delay_ms) >>> - sleep_milliseconds (x_cs_err_delay_ms); >>> + platform_sleep_milliseconds (x_cs_err_delay_ms); >>> } >>> gc_free (&gc); >>> } >>> diff --git a/src/openvpn/init.c b/src/openvpn/init.c >>> index bba3cf8..bc7718e 100644 >>> --- a/src/openvpn/init.c >>> +++ b/src/openvpn/init.c >>> @@ -935,7 +935,7 @@ do_genkey (const struct options * options) >>> "shared secret output file (--secret)"); >>> >>> if (options->mlock) /* should we disable paging? */ >>> - do_mlockall (true); >>> + platform_mlockall (true); >>> >>> nbits_written = write_key_file (2, options->shared_secret_file); >>> >>> @@ -1022,7 +1022,7 @@ do_uid_gid_chroot (struct context *c, bool no_delay) >>> if (c->options.chroot_dir) >>> { >>> if (no_delay) >>> - do_chroot (c->options.chroot_dir); >>> + platform_chroot (c->options.chroot_dir); >>> else >>> msg (M_INFO, "NOTE: chroot %s", why_not); >>> } >>> @@ -1030,8 +1030,8 @@ do_uid_gid_chroot (struct context *c, bool no_delay) >>> /* set user and/or group that we want to setuid/setgid to */ >>> if (no_delay) >>> { >>> - set_group (&c0->group_state); >>> - set_user (&c0->user_state); >>> + platform_group_set (&c0->platform_state_group); >>> + platform_user_set (&c0->platform_state_user); >>> c0->uid_gid_set = true; >>> } >>> else if (c0->uid_gid_specified) >>> @@ -2780,8 +2780,8 @@ do_init_first_time (struct context *c) >>> >>> /* get user and/or group that we want to setuid/setgid to */ >>> c0->uid_gid_specified = >>> - get_group (c->options.groupname, &c0->group_state) | >>> - get_user (c->options.username, &c0->user_state); >>> + platform_group_get (c->options.groupname, >>> &c0->platform_state_group) | >>> + platform_user_get (c->options.username, &c0->platform_state_user); >>> >>> /* get --writepid file descriptor */ >>> get_pid_file (c->options.writepid, &c0->pid_state); >>> @@ -2791,13 +2791,13 @@ do_init_first_time (struct context *c) >>> >>> /* should we disable paging? */ >>> if (c->options.mlock && c->did_we_daemonize) >>> - do_mlockall (true); /* call again in case we daemonized */ >>> + platform_mlockall (true); /* call again in case we daemonized >>> */ >>> >>> /* save process ID in a file */ >>> write_pid (&c0->pid_state); >>> >>> /* should we change scheduling priority? */ >>> - set_nice (c->options.nice); >>> + platform_nice (c->options.nice); >>> } >>> } >>> >>> @@ -3342,7 +3342,7 @@ init_instance (struct context *c, const struct >>> env_set *env, const unsigned int >>> >>> /* should we disable paging? */ >>> if (c->first_time && options->mlock) >>> - do_mlockall (true); >>> + platform_mlockall (true); >>> >>> #if P2MP >>> /* get passwords if undefined */ >>> diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c >>> index 85c9aca..1dddd41 100644 >>> --- a/src/openvpn/manage.c >>> +++ b/src/openvpn/manage.c >>> @@ -1146,7 +1146,7 @@ man_dispatch_command (struct management *man, struct >>> status_output *so, const ch >>> } >>> else if (streq (p[0], "pid")) >>> { >>> - msg (M_CLIENT, "SUCCESS: pid=%d", openvpn_getpid ()); >>> + msg (M_CLIENT, "SUCCESS: pid=%d", platform_getpid ()); >>> } >>> #ifdef MANAGEMENT_DEF_AUTH >>> else if (streq (p[0], "nclients")) >>> @@ -1429,7 +1429,7 @@ man_record_peer_info (struct management *man) >>> { >>> const in_addr_t a = ntohl (addr.sin_addr.s_addr); >>> const int p = ntohs (addr.sin_port); >>> - FILE *fp = openvpn_fopen (man->settings.write_peer_info_file, >>> "w"); >>> + FILE *fp = platform_fopen >>> (man->settings.write_peer_info_file, "w"); >>> if (fp) >>> { >>> fprintf (fp, "%s\n%d\n", print_in_addr_t (a, 0, &gc), p); >>> @@ -2013,17 +2013,17 @@ man_settings_init (struct man_settings *ms, >>> */ >>> if (client_user) >>> { >>> - struct user_state s; >>> - get_user (client_user, &s); >>> - ms->client_uid = user_state_uid (&s); >>> + struct platform_state_user s; >>> + platform_user_get (client_user, &s); >>> + ms->client_uid = platform_state_user_uid (&s); >>> msg (D_MANAGEMENT, "MANAGEMENT: client_uid=%d", ms->client_uid); >>> ASSERT (ms->client_uid >= 0); >>> } >>> if (client_group) >>> { >>> - struct group_state s; >>> - get_group (client_group, &s); >>> - ms->client_gid = group_state_gid (&s); >>> + struct platform_state_group s; >>> + platform_group_get (client_group, &s); >>> + ms->client_gid = platform_state_group_gid (&s); >>> msg (D_MANAGEMENT, "MANAGEMENT: client_gid=%d", ms->client_gid); >>> ASSERT (ms->client_gid >= 0); >>> } >>> diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c >>> index 2571194..2ded9bf 100644 >>> --- a/src/openvpn/misc.c >>> +++ b/src/openvpn/misc.c >>> @@ -56,122 +56,6 @@ int script_security = SSEC_BUILT_IN; /* GLOBAL */ >>> /* contains SM_x value defined in misc.h */ >>> int script_method = SM_EXECVE; /* GLOBAL */ >>> >>> -/* Redefine the top level directory of the filesystem >>> - to restrict access to files for security */ >>> -void >>> -do_chroot (const char *path) >>> -{ >>> - if (path) >>> - { >>> -#ifdef HAVE_CHROOT >>> - const char *top = "/"; >>> - if (chroot (path)) >>> - msg (M_ERR, "chroot to '%s' failed", path); >>> - if (openvpn_chdir (top)) >>> - msg (M_ERR, "cd to '%s' failed", top); >>> - msg (M_INFO, "chroot to '%s' and cd to '%s' succeeded", path, top); >>> -#else >>> - msg (M_FATAL, "Sorry but I can't chroot to '%s' because this >>> operating system doesn't appear to support the chroot() system call", path); >>> -#endif >>> - } >>> -} >>> - >>> -/* Get/Set UID of process */ >>> - >>> -bool >>> -get_user (const char *username, struct user_state *state) >>> -{ >>> - bool ret = false; >>> - CLEAR (*state); >>> - if (username) >>> - { >>> -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> - state->pw = getpwnam (username); >>> - if (!state->pw) >>> - msg (M_ERR, "failed to find UID for user %s", username); >>> - state->username = username; >>> - ret = true; >>> -#else >>> - msg (M_FATAL, "cannot get UID for user %s -- platform lacks >>> getpwname() or setuid() system calls", username); >>> -#endif >>> - } >>> - return ret; >>> -} >>> - >>> -void >>> -set_user (const struct user_state *state) >>> -{ >>> -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> - if (state->username && state->pw) >>> - { >>> - if (setuid (state->pw->pw_uid)) >>> - msg (M_ERR, "setuid('%s') failed", state->username); >>> - msg (M_INFO, "UID set to %s", state->username); >>> - } >>> -#endif >>> -} >>> - >>> -/* Get/Set GID of process */ >>> - >>> -bool >>> -get_group (const char *groupname, struct group_state *state) >>> -{ >>> - bool ret = false; >>> - CLEAR (*state); >>> - if (groupname) >>> - { >>> -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> - state->gr = getgrnam (groupname); >>> - if (!state->gr) >>> - msg (M_ERR, "failed to find GID for group %s", groupname); >>> - state->groupname = groupname; >>> - ret = true; >>> -#else >>> - msg (M_FATAL, "cannot get GID for group %s -- platform lacks >>> getgrnam() or setgid() system calls", groupname); >>> -#endif >>> - } >>> - return ret; >>> -} >>> - >>> -void >>> -set_group (const struct group_state *state) >>> -{ >>> -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> - if (state->groupname && state->gr) >>> - { >>> - if (setgid (state->gr->gr_gid)) >>> - msg (M_ERR, "setgid('%s') failed", state->groupname); >>> - msg (M_INFO, "GID set to %s", state->groupname); >>> -#ifdef HAVE_SETGROUPS >>> - { >>> - gid_t gr_list[1]; >>> - gr_list[0] = state->gr->gr_gid; >>> - if (setgroups (1, gr_list)) >>> - msg (M_ERR, "setgroups('%s') failed", state->groupname); >>> - } >>> -#endif >>> - } >>> -#endif >>> -} >>> - >>> -/* Change process priority */ >>> -void >>> -set_nice (int niceval) >>> -{ >>> - if (niceval) >>> - { >>> -#ifdef HAVE_NICE >>> - errno = 0; >>> - if (nice (niceval) < 0 && errno != 0) >>> - msg (M_WARN | M_ERRNO, "WARNING: nice %d failed: %s", niceval, >>> strerror(errno)); >>> - else >>> - msg (M_INFO, "nice %d succeeded", niceval); >>> -#else >>> - msg (M_WARN, "WARNING: nice %d failed (function not implemented)", >>> niceval); >>> -#endif >>> - } >>> -} >>> - >>> /* >>> * Pass tunnel endpoint and MTU parms to a user-supplied script. >>> * Used to execute the up/down script/plugins. >>> @@ -253,7 +137,7 @@ get_pid_file (const char* filename, struct pid_state >>> *state) >>> CLEAR (*state); >>> if (filename) >>> { >>> - state->fp = openvpn_fopen (filename, "w"); >>> + state->fp = platform_fopen (filename, "w"); >>> if (!state->fp) >>> msg (M_ERR, "Open error on pid file %s", filename); >>> state->filename = filename; >>> @@ -266,42 +150,13 @@ write_pid (const struct pid_state *state) >>> { >>> if (state->filename && state->fp) >>> { >>> - unsigned int pid = openvpn_getpid (); >>> + unsigned int pid = platform_getpid (); >>> fprintf(state->fp, "%u\n", pid); >>> if (fclose (state->fp)) >>> msg (M_ERR, "Close error on pid file %s", state->filename); >>> } >>> } >>> >>> -/* Get current PID */ >>> -unsigned int >>> -openvpn_getpid () >>> -{ >>> -#ifdef WIN32 >>> - return (unsigned int) GetCurrentProcessId (); >>> -#else >>> -#ifdef HAVE_GETPID >>> - return (unsigned int) getpid (); >>> -#else >>> - return 0; >>> -#endif >>> -#endif >>> -} >>> - >>> -/* Disable paging */ >>> -void >>> -do_mlockall(bool print_msg) >>> -{ >>> -#ifdef HAVE_MLOCKALL >>> - if (mlockall (MCL_CURRENT | MCL_FUTURE)) >>> - msg (M_WARN | M_ERRNO, "WARNING: mlockall call failed"); >>> - else if (print_msg) >>> - msg (M_INFO, "mlockall call succeeded"); >>> -#else >>> - msg (M_WARN, "WARNING: mlockall call failed (function not implemented)"); >>> -#endif >>> -} >>> - >>> /* >>> * Set standard file descriptors to /dev/null >>> */ >>> @@ -325,27 +180,6 @@ set_std_files_to_null (bool stdin_only) >>> } >>> >>> /* >>> - * Wrapper for chdir library function >>> - */ >>> -int >>> -openvpn_chdir (const char* dir) >>> -{ >>> -#ifdef HAVE_CHDIR >>> -#ifdef WIN32 >>> - int res; >>> - struct gc_arena gc = gc_new (); >>> - res = _wchdir (wide_string (dir, &gc)); >>> - gc_free (&gc); >>> - return res; >>> -#else >>> - return chdir (dir); >>> -#endif >>> -#else >>> - return -1; >>> -#endif >>> -} >>> - >>> -/* >>> * dup inetd/xinetd socket descriptor and save >>> */ >>> >>> @@ -391,32 +225,6 @@ warn_if_group_others_accessible (const char* filename) >>> } >>> >>> /* >>> - * convert system() return into a success/failure value >>> - */ >>> -bool >>> -system_ok (int stat) >>> -{ >>> -#ifdef WIN32 >>> - return stat == 0; >>> -#else >>> - return stat != -1 && WIFEXITED (stat) && WEXITSTATUS (stat) == 0; >>> -#endif >>> -} >>> - >>> -/* >>> - * did system() call execute the given command? >>> - */ >>> -bool >>> -system_executed (int stat) >>> -{ >>> -#ifdef WIN32 >>> - return stat != -1; >>> -#else >>> - return stat != -1 && WEXITSTATUS (stat) != 127; >>> -#endif >>> -} >>> - >>> -/* >>> * Print an error message based on the status code returned by system(). >>> */ >>> const char * >>> @@ -456,7 +264,7 @@ openvpn_execve_check (const struct argv *a, const >>> struct env_set *es, const unsi >>> const int stat = openvpn_execve (a, es, flags); >>> int ret = false; >>> >>> - if (system_ok (stat)) >>> + if (platform_system_ok (stat)) >>> ret = true; >>> else >>> { >>> @@ -554,7 +362,6 @@ openvpn_system (const char *command, const struct >>> env_set *es, unsigned int flag >>> { >>> #ifdef HAVE_SYSTEM >>> int ret; >>> - struct gc_arena gc; >>> >>> perf_push (PERF_SCRIPT); >>> >>> @@ -573,13 +380,7 @@ openvpn_system (const char *command, const struct >>> env_set *es, unsigned int flag >>> /* >>> * execute the command >>> */ >>> -#ifdef WIN32 >>> - gc = gc_new (); >>> - ret = _wsystem (wide_string (command, &gc)); >>> - gc_free (&gc); >>> -#else >>> - ret = system (command); >>> -#endif >>> + ret = platform_system(command); >>> >>> /* debugging */ >>> dmsg (D_SCRIPT, "SYSTEM return=%u", ret); >>> @@ -599,19 +400,6 @@ openvpn_system (const char *command, const struct >>> env_set *es, unsigned int flag >>> #endif >>> } >>> >>> -int >>> -openvpn_access (const char *path, int mode) >>> -{ >>> -#ifdef WIN32 >>> - struct gc_arena gc = gc_new (); >>> - int ret = _waccess (wide_string (path, &gc), mode); >>> - gc_free (&gc); >>> - return ret; >>> -#else >>> - return access (path, mode); >>> -#endif >>> -} >>> - >>> /* >>> * Run execve() inside a fork(), duping stdout. Designed to replicate the >>> semantics of popen() but >>> * in a safer way that doesn't require the invocation of a shell or the >>> risks >>> @@ -981,7 +769,7 @@ env_set_remove_from_environment (const struct env_set >>> *es) >>> >>> static struct env_item *global_env = NULL; /* GLOBAL */ >>> >>> -static void >>> +void >>> manage_env (char *str) >>> { >>> remove_env_item (str, true, &global_env); >>> @@ -1078,27 +866,11 @@ setenv_str_ex (struct env_set *es, >>> } >>> else >>> { >>> -#if defined(WIN32) >>> + char *str = construct_name_value (name_tmp, val_tmp, NULL); >>> + if (platform_putenv(str)) >>> { >>> - if (!SetEnvironmentVariableW (wide_string (name_tmp, &gc), >>> - wide_string (val_tmp, &gc))) >>> - msg (M_WARN | M_ERRNO, "SetEnvironmentVariable failed, name='%s', >>> value='%s'", >>> - name_tmp, >>> - val_tmp ? val_tmp : "NULL"); >>> + msg (M_WARN | M_ERRNO, "putenv('%s') failed", str); >>> } >>> -#elif defined(HAVE_PUTENV) >>> - { >>> - char *str = construct_name_value (name_tmp, val_tmp, NULL); >>> - int status; >>> - >>> - status = putenv (str); >>> - /*msg (M_INFO, "PUTENV '%s'", str);*/ >>> - if (!status) >>> - manage_env (str); >>> - if (status) >>> - msg (M_WARN | M_ERRNO, "putenv('%s') failed", str); >>> - } >>> -#endif >>> } >>> >>> gc_free (&gc); >>> @@ -1162,35 +934,6 @@ count_netmask_bits(const char *dotted_quad) >>> return ((int)result); >>> } >>> >>> -/* >>> - * Go to sleep for n milliseconds. >>> - */ >>> -void >>> -sleep_milliseconds (unsigned int n) >>> -{ >>> -#ifdef WIN32 >>> - Sleep (n); >>> -#else >>> - struct timeval tv; >>> - tv.tv_sec = n / 1000; >>> - tv.tv_usec = (n % 1000) * 1000; >>> - select (0, NULL, NULL, NULL, &tv); >>> -#endif >>> -} >>> - >>> -/* >>> - * Go to sleep indefinitely. >>> - */ >>> -void >>> -sleep_until_signal (void) >>> -{ >>> -#ifdef WIN32 >>> - ASSERT (0); >>> -#else >>> - select (0, NULL, NULL, NULL, NULL); >>> -#endif >>> -} >>> - >>> /* return true if filename can be opened for read */ >>> bool >>> test_file (const char *filename) >>> @@ -1198,7 +941,7 @@ test_file (const char *filename) >>> bool ret = false; >>> if (filename) >>> { >>> - FILE *fp = openvpn_fopen (filename, "r"); >>> + FILE *fp = platform_fopen (filename, "r"); >>> if (fp) >>> { >>> fclose (fp); >>> @@ -1246,7 +989,7 @@ create_temp_file (const char *directory, const char >>> *prefix, struct gc_arena *gc >>> >>> /* Atomically create the file. Errors out if the file already >>> exists. */ >>> - fd = openvpn_open (retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | >>> S_IWUSR); >>> + fd = platform_open (retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | >>> S_IWUSR); >>> if (fd != -1) >>> { >>> close (fd); >>> @@ -1342,22 +1085,6 @@ gen_path (const char *directory, const char >>> *filename, struct gc_arena *gc) >>> return NULL; >>> } >>> >>> -/* delete a file, return true if succeeded */ >>> -bool >>> -delete_file (const char *filename) >>> -{ >>> -#if defined(WIN32) >>> - struct gc_arena gc = gc_new (); >>> - BOOL ret = DeleteFileW (wide_string (filename, &gc)); >>> - gc_free (&gc); >>> - return (ret != 0); >>> -#elif defined(HAVE_UNLINK) >>> - return (unlink (filename) == 0); >>> -#else >>> - return false; >>> -#endif >>> -} >>> - >>> bool >>> absolute_pathname (const char *pathname) >>> { >>> @@ -1524,7 +1251,7 @@ get_user_pass_cr (struct user_pass *up, >>> >>> warn_if_group_others_accessible (auth_file); >>> >>> - fp = openvpn_fopen (auth_file, "r"); >>> + fp = platform_fopen (auth_file, "r"); >>> if (!fp) >>> msg (M_ERR, "Error opening '%s' auth file: %s", prefix, >>> auth_file); >>> >>> diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h >>> index 12a8f71..d4c8e33 100644 >>> --- a/src/openvpn/misc.h >>> +++ b/src/openvpn/misc.h >>> @@ -29,6 +29,7 @@ >>> #include "common.h" >>> #include "integer.h" >>> #include "buffer.h" >>> +#include "platform.h" >>> >>> /* socket descriptor passed by inetd/xinetd server to us */ >>> #define INETD_SOCKET_DESCRIPTOR 0 >>> @@ -58,37 +59,6 @@ struct env_set { >>> struct env_item *list; >>> }; >>> >>> -/* Get/Set UID of process */ >>> - >>> -struct user_state { >>> -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> - const char *username; >>> - struct passwd *pw; >>> -#else >>> - int dummy; >>> -#endif >>> -}; >>> - >>> -bool get_user (const char *username, struct user_state *state); >>> -void set_user (const struct user_state *state); >>> - >>> -/* Get/Set GID of process */ >>> - >>> -struct group_state { >>> -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> - const char *groupname; >>> - struct group *gr; >>> -#else >>> - int dummy; >>> -#endif >>> -}; >>> - >>> -bool get_group (const char *groupname, struct group_state *state); >>> -void set_group (const struct group_state *state); >>> - >>> -void set_nice (int niceval); >>> -void do_chroot (const char *path); >>> - >>> void run_up_down (const char *command, >>> const struct plugin_list *plugins, >>> int plugin_type, >>> @@ -111,9 +81,6 @@ struct pid_state { >>> >>> void get_pid_file (const char* filename, struct pid_state *state); >>> void write_pid (const struct pid_state *state); >>> -unsigned int openvpn_getpid (void); >>> - >>> -void do_mlockall (bool print_msg); /* Disable paging */ >>> >>> /* check file protections */ >>> void warn_if_group_others_accessible(const char* filename); >>> @@ -122,9 +89,6 @@ void warn_if_group_others_accessible(const char* >>> filename); >>> #define S_SCRIPT (1<<0) >>> #define S_FATAL (1<<1) >>> >>> -/* interpret the status code returned by system()/execve() */ >>> -bool system_ok(int); >>> -bool system_executed (int stat); >>> const char *system_error_message (int, struct gc_arena *gc); >>> >>> /* wrapper around the execve() call */ >>> @@ -133,7 +97,6 @@ int openvpn_execve (const struct argv *a, const struct >>> env_set *es, const unsign >>> bool openvpn_execve_check (const struct argv *a, const struct env_set *es, >>> const unsigned int flags, const char *error_message); >>> bool openvpn_execve_allowed (const unsigned int flags); >>> int openvpn_system (const char *command, const struct env_set *es, >>> unsigned int flags); >>> -int openvpn_access (const char *path, int mode); >>> >>> static inline bool >>> openvpn_run_script (const struct argv *a, const struct env_set *es, const >>> unsigned int flags, const char *hook) >>> @@ -144,37 +107,6 @@ openvpn_run_script (const struct argv *a, const struct >>> env_set *es, const unsign >>> return openvpn_execve_check(a, es, flags | S_SCRIPT, msg); >>> } >>> >>> -#ifdef WIN32 >>> -FILE * openvpn_fopen (const char *path, const char *mode); >>> -#else >>> -static inline FILE * >>> -openvpn_fopen (const char *path, const char *mode) >>> -{ >>> - return fopen (path, mode); >>> -} >>> -#endif >>> - >>> -#ifdef WIN32 >>> -int openvpn_open (const char *path, int flags, int mode); >>> -#else >>> -static inline int >>> -openvpn_open (const char *path, int flags, mode_t mode) >>> -{ >>> - return open (path, flags, mode); >>> -} >>> -#endif >>> - >>> -#ifdef WIN32 >>> -typedef struct _stat openvpn_stat_t; >>> -int openvpn_stat (const char *path, openvpn_stat_t *buf); >>> -#else >>> -typedef struct stat openvpn_stat_t; >>> -static inline int >>> -openvpn_stat (const char *path, openvpn_stat_t *buf) >>> -{ >>> - return stat (path, buf); >>> -} >>> -#endif >>> >>> #ifdef HAVE_STRERROR >>> /* a thread-safe version of strerror */ >>> @@ -184,9 +116,6 @@ const char* strerror_ts (int errnum, struct gc_arena >>> *gc); >>> /* Set standard file descriptors to /dev/null */ >>> void set_std_files_to_null (bool stdin_only); >>> >>> -/* Wrapper for chdir library function */ >>> -int openvpn_chdir (const char* dir); >>> - >>> /* dup inetd/xinetd socket descriptor and save */ >>> extern int inetd_socket_descriptor; >>> void save_inetd_socket_descriptor (void); >>> @@ -242,12 +171,6 @@ const char **make_extended_arg_array (char **p, struct >>> gc_arena *gc); >>> int count_netmask_bits(const char *); >>> unsigned int count_bits(unsigned int ); >>> >>> -/* go to sleep for n milliseconds */ >>> -void sleep_milliseconds (unsigned int n); >>> - >>> -/* go to sleep indefinitely */ >>> -void sleep_until_signal (void); >>> - >>> /* an analogue to the random() function, but use OpenSSL functions if >>> available */ >>> #ifdef ENABLE_CRYPTO >>> long int get_random(void); >>> @@ -264,9 +187,6 @@ const char *create_temp_file (const char *directory, >>> const char *prefix, struct >>> /* put a directory and filename together */ >>> const char *gen_path (const char *directory, const char *filename, struct >>> gc_arena *gc); >>> >>> -/* delete a file, return true if succeeded */ >>> -bool delete_file (const char *filename); >>> - >>> /* return true if pathname is absolute */ >>> bool absolute_pathname (const char *pathname); >>> >>> @@ -448,28 +368,4 @@ void argv_printf_cat (struct argv *a, const char >>> *format, ...) >>> #endif >>> ; >>> >>> -/* >>> - * Extract UID or GID >>> - */ >>> - >>> -static inline int >>> -user_state_uid (const struct user_state *s) >>> -{ >>> -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> - if (s->pw) >>> - return s->pw->pw_uid; >>> -#endif >>> - return -1; >>> -} >>> - >>> -static inline int >>> -group_state_gid (const struct group_state *s) >>> -{ >>> -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> - if (s->gr) >>> - return s->gr->gr_gid; >>> -#endif >>> - return -1; >>> -} >>> - >>> #endif >>> diff --git a/src/openvpn/mstats.c b/src/openvpn/mstats.c >>> index b4b864b..3be493c 100644 >>> --- a/src/openvpn/mstats.c >>> +++ b/src/openvpn/mstats.c >>> @@ -114,7 +114,7 @@ mstats_close(void) >>> mmap_stats->state = MSTATS_EXPIRED; >>> if (munmap((void *)mmap_stats, sizeof(struct mmap_stats))) >>> msg (M_WARN | M_ERRNO, "mstats_close: munmap error"); >>> - delete_file(mmap_fn); >>> + platform_unlink(mmap_fn); >>> mmap_stats = NULL; >>> } >>> } >>> diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c >>> index e79c6f1..9876b80 100644 >>> --- a/src/openvpn/multi.c >>> +++ b/src/openvpn/multi.c >>> @@ -1452,7 +1452,7 @@ multi_client_connect_post (struct multi_context *m, >>> option_types_found, >>> mi->context.c2.es); >>> >>> - if (!delete_file (dc_file)) >>> + if (!platform_unlink (dc_file)) >>> msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s", >>> dc_file); >>> >>> diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h >>> index b314885..0732d0f 100644 >>> --- a/src/openvpn/openvpn.h >>> +++ b/src/openvpn/openvpn.h >>> @@ -143,8 +143,8 @@ struct context_0 >>> /* workspace for --user/--group */ >>> bool uid_gid_specified; >>> bool uid_gid_set; >>> - struct user_state user_state; >>> - struct group_state group_state; >>> + struct platform_state_user platform_state_user; >>> + struct platform_state_group platform_state_group; >>> }; >>> >>> >>> diff --git a/src/openvpn/openvpn.vcproj b/src/openvpn/openvpn.vcproj >>> index 6c19621..4680e52 100644 >>> --- a/src/openvpn/openvpn.vcproj >>> +++ b/src/openvpn/openvpn.vcproj >>> @@ -347,6 +347,10 @@ >>> > >>> </File> >>> <File >>> + RelativePath=".\platform.c" >>> + > >>> + </File> >>> + <File >>> RelativePath=".\plugin.c" >>> > >>> </File> >>> @@ -649,6 +653,10 @@ >>> > >>> </File> >>> <File >>> + RelativePath=".\platform.h" >>> + > >>> + </File> >>> + <File >>> RelativePath=".\plugin.h" >>> > >>> </File> >>> diff --git a/src/openvpn/options.c b/src/openvpn/options.c >>> index 258b060..bd83843 100644 >>> --- a/src/openvpn/options.c >>> +++ b/src/openvpn/options.c >>> @@ -920,7 +920,7 @@ setenv_settings (struct env_set *es, const struct >>> options *o) >>> setenv_int (es, "daemon", o->daemon); >>> setenv_int (es, "daemon_log_redirect", o->log); >>> setenv_unsigned (es, "daemon_start_time", time(NULL)); >>> - setenv_int (es, "daemon_pid", openvpn_getpid()); >>> + setenv_int (es, "daemon_pid", platform_getpid()); >>> >>> #ifdef ENABLE_CONNECTION >>> if (o->connection_list) >>> @@ -2640,18 +2640,18 @@ check_file_access(const int type, const char *file, >>> const int mode, const char * >>> char *fullpath = strdup(file); /* POSIX dirname() implementaion may >>> modify its arguments */ >>> char *dirpath = dirname(fullpath); >>> >>> - if (openvpn_access (dirpath, mode|X_OK) != 0) >>> + if (platform_access (dirpath, mode|X_OK) != 0) >>> errcode = errno; >>> free(fullpath); >>> } >>> >>> /* Is the file itself accessible? */ >>> - if (!errcode && (type & CHKACC_FILE) && (openvpn_access (file, mode) != >>> 0) ) >>> + if (!errcode && (type & CHKACC_FILE) && (platform_access (file, mode) != >>> 0) ) >>> errcode = errno; >>> >>> /* If the file exists and is accessible, is it writable? */ >>> - if (!errcode && (type & CHKACC_FILEXSTWR) && (openvpn_access (file, >>> F_OK) == 0) ) >>> - if (openvpn_access (file, W_OK) != 0) >>> + if (!errcode && (type & CHKACC_FILEXSTWR) && (platform_access (file, >>> F_OK) == 0) ) >>> + if (platform_access (file, W_OK) != 0) >>> errcode = errno; >>> >>> /* Scream if an error is found */ >>> @@ -3755,7 +3755,7 @@ read_config_file (struct options *options, >>> if (streq (file, "stdin")) >>> fp = stdin; >>> else >>> - fp = openvpn_fopen (file, "r"); >>> + fp = platform_fopen (file, "r"); >>> if (fp) >>> { >>> line_num = 0; >>> @@ -4528,7 +4528,7 @@ add_option (struct options *options, >>> else if (streq (p[0], "cd") && p[1]) >>> { >>> VERIFY_PERMISSION (OPT_P_GENERAL); >>> - if (openvpn_chdir (p[1])) >>> + if (platform_chdir (p[1])) >>> { >>> msg (M_ERR, "cd to '%s' failed", p[1]); >>> goto err; >>> diff --git a/src/openvpn/packet_id.c b/src/openvpn/packet_id.c >>> index 186f074..0102129 100644 >>> --- a/src/openvpn/packet_id.c >>> +++ b/src/openvpn/packet_id.c >>> @@ -368,7 +368,7 @@ packet_id_persist_load (struct packet_id_persist *p, >>> const char *filename) >>> if (!packet_id_persist_enabled (p)) >>> { >>> /* open packet-id persist file for both read and write */ >>> - p->fd = openvpn_open (filename, >>> + p->fd = platform_open (filename, >>> O_CREAT | O_RDWR | O_BINARY, >>> S_IRUSR | S_IWUSR); >>> if (p->fd == -1) >>> diff --git a/src/openvpn/pf.c b/src/openvpn/pf.c >>> index 729792e..7ed1e70 100644 >>> --- a/src/openvpn/pf.c >>> +++ b/src/openvpn/pf.c >>> @@ -504,8 +504,8 @@ pf_check_reload (struct context *c) >>> && c->c2.pf.filename >>> && event_timeout_trigger (&c->c2.pf.reload, &c->c2.timeval, >>> ETT_DEFAULT)) >>> { >>> - openvpn_stat_t s; >>> - if (!openvpn_stat (c->c2.pf.filename, &s)) >>> + platform_stat_t s; >>> + if (!platform_stat (c->c2.pf.filename, &s)) >>> { >>> if (s.st_mtime > c->c2.pf.file_last_mod) >>> { >>> @@ -605,7 +605,7 @@ pf_destroy_context (struct pf_context *pfc) >>> #ifdef PLUGIN_PF >>> if (pfc->filename) >>> { >>> - delete_file (pfc->filename); >>> + platform_unlink (pfc->filename); >>> free (pfc->filename); >>> } >>> #endif >>> diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c >>> new file mode 100644 >>> index 0000000..c79f680 >>> --- /dev/null >>> +++ b/src/openvpn/platform.c >>> @@ -0,0 +1,369 @@ >>> +/* >>> + * OpenVPN -- An application to securely tunnel IP networks >>> + * over a single TCP/UDP port, with support for SSL/TLS-based >>> + * session authentication and key exchange, >>> + * packet encryption, packet authentication, and >>> + * packet compression. >>> + * >>> + * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sa...@openvpn.net> >>> + * >>> + * This program is free software; you can redistribute it and/or modify >>> + * it under the terms of the GNU General Public License version 2 >>> + * as published by the Free Software Foundation. >>> + * >>> + * This program is distributed in the hope that it will be useful, >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >>> + * GNU General Public License for more details. >>> + * >>> + * You should have received a copy of the GNU General Public License >>> + * along with this program (see the file COPYING included with this >>> + * distribution); if not, write to the Free Software Foundation, Inc., >>> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >>> + */ >>> + >>> +#ifdef HAVE_CONFIG_H >>> +#include "config.h" >>> +#elif defined(_MSC_VER) >>> +#include "config-msvc.h" >>> +#endif >>> + >>> +#include "syshead.h" >>> + >>> +#include "buffer.h" >>> +#include "error.h" >>> +#include "win32.h" >>> + >>> +#include "memdbg.h" >>> + >>> +#include "platform.h" >>> + >>> +/* Redefine the top level directory of the filesystem >>> + to restrict access to files for security */ >>> +void >>> +platform_chroot (const char *path) >>> +{ >>> + if (path) >>> + { >>> +#ifdef HAVE_CHROOT >>> + const char *top = "/"; >>> + if (chroot (path)) >>> + msg (M_ERR, "chroot to '%s' failed", path); >>> + if (platform_chdir (top)) >>> + msg (M_ERR, "cd to '%s' failed", top); >>> + msg (M_INFO, "chroot to '%s' and cd to '%s' succeeded", path, top); >>> +#else >>> + msg (M_FATAL, "Sorry but I can't chroot to '%s' because this >>> operating system doesn't appear to support the chroot() system call", path); >>> +#endif >>> + } >>> +} >>> + >>> +/* Get/Set UID of process */ >>> + >>> +bool >>> +platform_user_get (const char *username, struct platform_state_user *state) >>> +{ >>> + bool ret = false; >>> + CLEAR (*state); >>> + if (username) >>> + { >>> +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> + state->pw = getpwnam (username); >>> + if (!state->pw) >>> + msg (M_ERR, "failed to find UID for user %s", username); >>> + state->username = username; >>> + ret = true; >>> +#else >>> + msg (M_FATAL, "cannot get UID for user %s -- platform lacks >>> getpwname() or setuid() system calls", username); >>> +#endif >>> + } >>> + return ret; >>> +} >>> + >>> +void >>> +platform_user_set (const struct platform_state_user *state) >>> +{ >>> +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> + if (state->username && state->pw) >>> + { >>> + if (setuid (state->pw->pw_uid)) >>> + msg (M_ERR, "setuid('%s') failed", state->username); >>> + msg (M_INFO, "UID set to %s", state->username); >>> + } >>> +#endif >>> +} >>> + >>> +/* Get/Set GID of process */ >>> + >>> +bool >>> +platform_group_get (const char *groupname, struct platform_state_group >>> *state) >>> +{ >>> + bool ret = false; >>> + CLEAR (*state); >>> + if (groupname) >>> + { >>> +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> + state->gr = getgrnam (groupname); >>> + if (!state->gr) >>> + msg (M_ERR, "failed to find GID for group %s", groupname); >>> + state->groupname = groupname; >>> + ret = true; >>> +#else >>> + msg (M_FATAL, "cannot get GID for group %s -- platform lacks >>> getgrnam() or setgid() system calls", groupname); >>> +#endif >>> + } >>> + return ret; >>> +} >>> + >>> +void >>> +platform_group_set (const struct platform_state_group *state) >>> +{ >>> +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> + if (state->groupname && state->gr) >>> + { >>> + if (setgid (state->gr->gr_gid)) >>> + msg (M_ERR, "setgid('%s') failed", state->groupname); >>> + msg (M_INFO, "GID set to %s", state->groupname); >>> +#ifdef HAVE_SETGROUPS >>> + { >>> + gid_t gr_list[1]; >>> + gr_list[0] = state->gr->gr_gid; >>> + if (setgroups (1, gr_list)) >>> + msg (M_ERR, "setgroups('%s') failed", state->groupname); >>> + } >>> +#endif >>> + } >>> +#endif >>> +} >>> + >>> +/* Change process priority */ >>> +void >>> +platform_nice (int niceval) >>> +{ >>> + if (niceval) >>> + { >>> +#ifdef HAVE_NICE >>> + errno = 0; >>> + if (nice (niceval) < 0 && errno != 0) >>> + msg (M_WARN | M_ERRNO, "WARNING: nice %d failed: %s", niceval, >>> strerror(errno)); >>> + else >>> + msg (M_INFO, "nice %d succeeded", niceval); >>> +#else >>> + msg (M_WARN, "WARNING: nice %d failed (function not implemented)", >>> niceval); >>> +#endif >>> + } >>> +} >>> + >>> +/* Get current PID */ >>> +unsigned int >>> +platform_getpid () >>> +{ >>> +#ifdef WIN32 >>> + return (unsigned int) GetCurrentProcessId (); >>> +#else >>> +#ifdef HAVE_GETPID >>> + return (unsigned int) getpid (); >>> +#else >>> + return 0; >>> +#endif >>> +#endif >>> +} >>> + >>> +/* Disable paging */ >>> +void >>> +platform_mlockall(bool print_msg) >>> +{ >>> +#ifdef HAVE_MLOCKALL >>> + if (mlockall (MCL_CURRENT | MCL_FUTURE)) >>> + msg (M_WARN | M_ERRNO, "WARNING: mlockall call failed"); >>> + else if (print_msg) >>> + msg (M_INFO, "mlockall call succeeded"); >>> +#else >>> + msg (M_WARN, "WARNING: mlockall call failed (function not implemented)"); >>> +#endif >>> +} >>> + >>> +/* >>> + * Wrapper for chdir library function >>> + */ >>> +int >>> +platform_chdir (const char* dir) >>> +{ >>> +#ifdef HAVE_CHDIR >>> +#ifdef WIN32 >>> + int res; >>> + struct gc_arena gc = gc_new (); >>> + res = _wchdir (wide_string (dir, &gc)); >>> + gc_free (&gc); >>> + return res; >>> +#else >>> + return chdir (dir); >>> +#endif >>> +#else >>> + return -1; >>> +#endif >>> +} >>> + >>> +/* >>> + * convert system() return into a success/failure value >>> + */ >>> +bool >>> +platform_system_ok (int stat) >>> +{ >>> +#ifdef WIN32 >>> + return stat == 0; >>> +#else >>> + return stat != -1 && WIFEXITED (stat) && WEXITSTATUS (stat) == 0; >>> +#endif >>> +} >>> + >>> +/* >>> + * did system() call execute the given command? >>> + */ >>> +bool >>> +platform_system_executed (int stat) >>> +{ >>> +#ifdef WIN32 >>> + return stat != -1; >>> +#else >>> + return stat != -1 && WEXITSTATUS (stat) != 127; >>> +#endif >>> +} >>> + >>> +int >>> +platform_access (const char *path, int mode) >>> +{ >>> +#ifdef WIN32 >>> + struct gc_arena gc = gc_new (); >>> + int ret = _waccess (wide_string (path, &gc), mode & ~X_OK); >>> + gc_free (&gc); >>> + return ret; >>> +#else >>> + return access (path, mode); >>> +#endif >>> +} >>> + >>> +/* >>> + * Go to sleep for n milliseconds. >>> + */ >>> +void >>> +platform_sleep_milliseconds (unsigned int n) >>> +{ >>> +#ifdef WIN32 >>> + Sleep (n); >>> +#else >>> + struct timeval tv; >>> + tv.tv_sec = n / 1000; >>> + tv.tv_usec = (n % 1000) * 1000; >>> + select (0, NULL, NULL, NULL, &tv); >>> +#endif >>> +} >>> + >>> +/* >>> + * Go to sleep indefinitely. >>> + */ >>> +void >>> +platform_sleep_until_signal (void) >>> +{ >>> +#ifdef WIN32 >>> + ASSERT (0); >>> +#else >>> + select (0, NULL, NULL, NULL, NULL); >>> +#endif >>> +} >>> + >>> +/* delete a file, return true if succeeded */ >>> +bool >>> +platform_unlink (const char *filename) >>> +{ >>> +#if defined(WIN32) >>> + struct gc_arena gc = gc_new (); >>> + BOOL ret = DeleteFileW (wide_string (filename, &gc)); >>> + gc_free (&gc); >>> + return (ret != 0); >>> +#elif defined(HAVE_UNLINK) >>> + return (unlink (filename) == 0); >>> +#else >>> + return false; >>> +#endif >>> +} >>> + >>> +int platform_system(const char *command) { >>> + int ret; >>> +#ifdef WIN32 >>> + struct gc_arena gc = gc_new (); >>> + ret = _wsystem (wide_string (command, &gc)); >>> + gc_free (&gc); >>> +#else >>> + ret = system (command); >>> +#endif >>> + return ret; >>> +} >>> + >>> +int platform_putenv(char *string) >>> +{ >>> + int status; >>> +#if defined(WIN32) >>> + struct gc_arena gc = gc_new (); >>> + char *s = string_alloc(string, &gc); >>> + char *value = strchr(s, '='); >>> + if (value!=NULL) >>> + { >>> + *value = '\0'; >>> + value++; >>> + if (*value == '\0') >>> + value = NULL; >>> + } >>> + >>> + status = SetEnvironmentVariableW (wide_string (s, &gc), >>> + wide_string (value, &gc)) ? 1: 0; >>> + gc_free (&gc); >>> +#elif defined(HAVE_PUTENV) >>> + void manage_env (char *str); /* TODO: Resolve properly */ >>> + status = putenv (string); >>> + if (!status) >>> + manage_env (string); >>> +#endif >>> + >>> + return status; >>> +} >>> + >>> +FILE * >>> +platform_fopen (const char *path, const char *mode) >>> +{ >>> +#ifdef WIN32 >>> + struct gc_arena gc = gc_new (); >>> + FILE *f = _wfopen (wide_string (path, &gc), wide_string (mode, &gc)); >>> + gc_free (&gc); >>> + return f; >>> +#else >>> + return fopen(path, mode); >>> +#endif >>> +} >>> + >>> +int >>> +platform_open (const char *path, int flags, int mode) >>> +{ >>> +#ifdef WIN32 >>> + struct gc_arena gc = gc_new (); >>> + int fd = _wopen (wide_string (path, &gc), flags, mode); >>> + gc_free (&gc); >>> + return fd; >>> +#else >>> + return open(path, flags, mode); >>> +#endif >>> +} >>> + >>> +int >>> +platform_stat (const char *path, platform_stat_t *buf) >>> +{ >>> +#ifdef WIN32 >>> + struct gc_arena gc = gc_new (); >>> + int res = _wstat (wide_string (path, &gc), buf); >>> + gc_free (&gc); >>> + return res; >>> +#else >>> + return stat(path, buf); >>> +#endif >>> +} >>> + >>> diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h >>> new file mode 100644 >>> index 0000000..7bd2067 >>> --- /dev/null >>> +++ b/src/openvpn/platform.h >>> @@ -0,0 +1,142 @@ >>> +/* >>> + * OpenVPN -- An application to securely tunnel IP networks >>> + * over a single TCP/UDP port, with support for SSL/TLS-based >>> + * session authentication and key exchange, >>> + * packet encryption, packet authentication, and >>> + * packet compression. >>> + * >>> + * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sa...@openvpn.net> >>> + * >>> + * This program is free software; you can redistribute it and/or modify >>> + * it under the terms of the GNU General Public License version 2 >>> + * as published by the Free Software Foundation. >>> + * >>> + * This program is distributed in the hope that it will be useful, >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >>> + * GNU General Public License for more details. >>> + * >>> + * You should have received a copy of the GNU General Public License >>> + * along with this program (see the file COPYING included with this >>> + * distribution); if not, write to the Free Software Foundation, Inc., >>> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >>> + */ >>> + >>> +#ifndef PLATFORM_H >>> +#define PLATFORM_H >>> + >>> +#ifdef HAVE_SYS_TYPES_H >>> +#include <sys/types.h> >>> +#endif >>> + >>> +#ifdef HAVE_SYS_STAT_H >>> +#include <sys/stat.h> >>> +#endif >>> + >>> +#ifdef HAVE_UNISTD_H >>> +#include <unistd.h> >>> +#endif >>> + >>> +#ifdef HAVE_PWD_H >>> +#include <pwd.h> >>> +#endif >>> + >>> +#ifdef HAVE_GRP_H >>> +#include <grp.h> >>> +#endif >>> + >>> +#ifdef HAVE_STDIO_H >>> +#include <stdio.h> >>> +#endif >>> + >>> +#include "basic.h" >>> + >>> +/* Get/Set UID of process */ >>> + >>> +struct platform_state_user { >>> +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> + const char *username; >>> + struct passwd *pw; >>> +#else >>> + int dummy; >>> +#endif >>> +}; >>> + >>> +/* Get/Set GID of process */ >>> + >>> +struct platform_state_group { >>> +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> + const char *groupname; >>> + struct group *gr; >>> +#else >>> + int dummy; >>> +#endif >>> +}; >>> + >>> +bool platform_user_get (const char *username, struct platform_state_user >>> *state); >>> +void platform_user_set (const struct platform_state_user *state); >>> + >>> +bool platform_group_get (const char *groupname, struct >>> platform_state_group *state); >>> +void platform_group_set (const struct platform_state_group *state); >>> + >>> +/* >>> + * Extract UID or GID >>> + */ >>> + >>> +static inline int >>> +platform_state_user_uid (const struct platform_state_user *s) >>> +{ >>> +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) >>> + if (s->pw) >>> + return s->pw->pw_uid; >>> +#endif >>> + return -1; >>> +} >>> + >>> +static inline int >>> +platform_state_group_gid (const struct platform_state_group *s) >>> +{ >>> +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) >>> + if (s->gr) >>> + return s->gr->gr_gid; >>> +#endif >>> + return -1; >>> +} >>> + >>> +void platform_chroot (const char *path); >>> + >>> +void platform_nice (int niceval); >>> + >>> +unsigned int platform_getpid (void); >>> + >>> +void platform_mlockall (bool print_msg); /* Disable paging */ >>> + >>> +int platform_chdir (const char* dir); >>> + >>> +/* interpret the status code returned by system()/execve() */ >>> +bool platform_system_ok (int stat); >>> +bool platform_system_executed (int stat); >>> +int platform_system(const char *command); >>> + >>> +int platform_access (const char *path, int mode); >>> + >>> +void platform_sleep_milliseconds (unsigned int n); >>> + >>> +void platform_sleep_until_signal (void); >>> + >>> +/* delete a file, return true if succeeded */ >>> +bool platform_unlink (const char *filename); >>> + >>> +int platform_putenv (char *string); >>> + >>> +FILE *platform_fopen (const char *path, const char *mode); >>> +int platform_open (const char *path, int flags, int mode); >>> + >>> +#ifdef WIN32 >>> +typedef struct _stat platform_stat_t; >>> +#else >>> +typedef struct stat platform_stat_t; >>> +#endif >>> +int platform_stat (const char *path, platform_stat_t *buf); >>> + >>> +#endif >>> diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c >>> index a4e50e8..5d056ee 100644 >>> --- a/src/openvpn/ps.c >>> +++ b/src/openvpn/ps.c >>> @@ -337,7 +337,7 @@ journal_add (const char *journal_dir, struct >>> proxy_connection *pc, struct proxy_ >>> check_malloc_return (jfn); >>> openvpn_snprintf (jfn, fnlen, "%s/%s", journal_dir, t); >>> dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: client origin %s -> %s", >>> jfn, f); >>> - fd = openvpn_open (jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | >>> S_IWUSR | S_IRGRP); >>> + fd = platform_open (jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | >>> S_IWUSR | S_IRGRP); >>> if (fd != -1) >>> { >>> write(fd, f, strlen(f)); >>> diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c >>> index 6a60cb5..d712c66 100644 >>> --- a/src/openvpn/ssl_openssl.c >>> +++ b/src/openvpn/ssl_openssl.c >>> @@ -280,7 +280,7 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const >>> char *pkcs12_file, >>> #endif >>> { >>> /* Load the PKCS #12 file */ >>> - if (!(fp = openvpn_fopen(pkcs12_file, "rb"))) >>> + if (!(fp = platform_fopen(pkcs12_file, "rb"))) >>> msg(M_SSLERR, "Error opening file %s", pkcs12_file); >>> p12 = d2i_PKCS12_fp(fp, NULL); >>> fclose(fp); >>> diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c >>> index 51457f8..e837e39 100644 >>> --- a/src/openvpn/ssl_verify.c >>> +++ b/src/openvpn/ssl_verify.c >>> @@ -517,7 +517,7 @@ verify_cert_call_command(const char *verify_command, >>> struct env_set *es, >>> if (verify_export_cert) >>> { >>> if (tmp_file) >>> - delete_file(tmp_file); >>> + platform_unlink(tmp_file); >>> } >>> >>> gc_free(&gc); >>> @@ -551,7 +551,7 @@ verify_check_crl_dir(const char *crl_dir, >>> openvpn_x509_cert_t *cert) >>> x509_free_serial(serial); >>> return FAILURE; >>> } >>> - fd = openvpn_open (fn, O_RDONLY, 0); >>> + fd = platform_open (fn, O_RDONLY, 0); >>> if (fd >= 0) >>> { >>> msg (D_HANDSHAKE, "VERIFY CRL: certificate serial number %s is >>> revoked", serial); >>> @@ -735,7 +735,7 @@ key_state_rm_auth_control_file (struct key_state *ks) >>> { >>> if (ks && ks->auth_control_file) >>> { >>> - delete_file (ks->auth_control_file); >>> + platform_unlink (ks->auth_control_file); >>> free (ks->auth_control_file); >>> ks->auth_control_file = NULL; >>> } >>> @@ -987,7 +987,7 @@ verify_user_pass_script (struct tls_session *session, >>> const struct user_pass *up >>> >>> done: >>> if (tmp_file && strlen (tmp_file) > 0) >>> - delete_file (tmp_file); >>> + platform_unlink (tmp_file); >>> >>> argv_reset (&argv); >>> gc_free (&gc); >>> diff --git a/src/openvpn/status.c b/src/openvpn/status.c >>> index 0be5e4c..5f9ab9e 100644 >>> --- a/src/openvpn/status.c >>> +++ b/src/openvpn/status.c >>> @@ -78,17 +78,17 @@ status_open (const char *filename, >>> switch (so->flags) >>> { >>> case STATUS_OUTPUT_WRITE: >>> - so->fd = openvpn_open (filename, >>> + so->fd = platform_open (filename, >>> O_CREAT | O_TRUNC | O_WRONLY, >>> S_IRUSR | S_IWUSR); >>> break; >>> case STATUS_OUTPUT_READ: >>> - so->fd = openvpn_open (filename, >>> + so->fd = platform_open (filename, >>> O_RDONLY, >>> S_IRUSR | S_IWUSR); >>> break; >>> case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE: >>> - so->fd = openvpn_open (filename, >>> + so->fd = platform_open (filename, >>> O_CREAT | O_RDWR, >>> S_IRUSR | S_IWUSR); >>> break; >>> diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c >>> index abc6a99..e6a7bc8 100644 >>> --- a/src/openvpn/tun.c >>> +++ b/src/openvpn/tun.c >>> @@ -1545,22 +1545,22 @@ tuncfg (const char *dev, const char *dev_type, >>> const char *dev_node, int persist >>> msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev); >>> if (username != NULL) >>> { >>> - struct user_state user_state; >>> + struct platform_state_user platform_state_user; >>> >>> - if (!get_user (username, &user_state)) >>> + if (!platform_user_get (username, &platform_state_user)) >>> msg (M_ERR, "Cannot get user entry for %s", username); >>> else >>> - if (ioctl (tt->fd, TUNSETOWNER, user_state.pw->pw_uid) < 0) >>> + if (ioctl (tt->fd, TUNSETOWNER, platform_state_user.pw->pw_uid) < >>> 0) >>> msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev); >>> } >>> if (groupname != NULL) >>> { >>> - struct group_state group_state; >>> + struct platform_state_group platform_state_group; >>> >>> - if (!get_group (groupname, &group_state)) >>> + if (!platform_group_get (groupname, &platform_state_group)) >>> msg (M_ERR, "Cannot get group entry for %s", groupname); >>> else >>> - if (ioctl (tt->fd, TUNSETGROUP, group_state.gr->gr_gid) < 0) >>> + if (ioctl (tt->fd, TUNSETGROUP, platform_state_group.gr->gr_gid) < >>> 0) >>> msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev); >>> } >>> close_tun (tt); >>> diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c >>> index e94343b..e8e69dc 100644 >>> --- a/src/openvpn/win32.c >>> +++ b/src/openvpn/win32.c >>> @@ -976,33 +976,6 @@ wide_string (const char* utf8, struct gc_arena *gc) >>> return ucs16; >>> } >>> >>> -FILE * >>> -openvpn_fopen (const char *path, const char *mode) >>> -{ >>> - struct gc_arena gc = gc_new (); >>> - FILE *f = _wfopen (wide_string (path, &gc), wide_string (mode, &gc)); >>> - gc_free (&gc); >>> - return f; >>> -} >>> - >>> -int >>> -openvpn_open (const char *path, int flags, int mode) >>> -{ >>> - struct gc_arena gc = gc_new (); >>> - int fd = _wopen (wide_string (path, &gc), flags, mode); >>> - gc_free (&gc); >>> - return fd; >>> -} >>> - >>> -int >>> -openvpn_stat (const char *path, openvpn_stat_t *buf) >>> -{ >>> - struct gc_arena gc = gc_new (); >>> - int res = _wstat (wide_string (path, &gc), buf); >>> - gc_free (&gc); >>> - return res; >>> -} >>> - >>> /* >>> * call ourself in another process >>> */ >>> -- >>> 1.7.3.4 >>> >>> >>> ------------------------------------------------------------------------------ >>> Virtualization & Cloud Management Using Capacity Planning >>> Cloud computing makes use of virtualization - but cloud computing >>> also focuses on allowing computing to be delivered as a service. >>> http://www.accelacomm.com/jaw/sfnl/114/51521223/ >>> _______________________________________________ >>> Openvpn-devel mailing list >>> Openvpn-devel@lists.sourceforge.net >>> https://lists.sourceforge.net/lists/listinfo/openvpn-devel >>