In commit 4e1cc5f6dda22e9 the create_temp_filename() function was
reviewed and hardened, which in the end renamed this function to
create_temp_file() in commit 495e3cec5d156.
With these changes it became more evident that OpenVPN needs a directory
where it can create temporary files. The create_temp_file() will create
such files f.ex. if --client-connect or --plugin which makes use of
the OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY hook, such as openvpn-auth-pam.so.
When this happens, OpenVPN will normally create these files in the directory
OpenVPN was started. In many cases, this will fail due to restricted access.
By using --tmp-dir and pointing it to a directory writeable to the user
running OpenVPN, it works again.
This patch makes OpenVPN use a more suitable temproary directory by default,
instead of the current working directory. On non-Windows platforms this
default value is set to '/tmp', but can be modified at compile-time by
running ./configure --with-tmp-dir-path=<TEMP DIR PATH>. On Windows, it
will look up %TEMP% and %TMP% first, and if that doesn't give any clues, it
will fallback to C:\WINDOWS\Temp in the end.
In any cases, this default value can be overridden in the configuration
file by using the --tmp-dir option, as before.
To check what the default is at runime, you can see this easily by doing
this:
$ ./openvpn --verb 4 --dev tun | grep tmp_dir
Signed-off-by: David Sommerseth <[email protected]>
Tested-by: Jan Just Keijser <[email protected]>
---
configure.ac | 11 +++++++++++
options.c | 15 +++++++++++----
win/config.h.in | 3 +++
win32.c | 19 +++++++++++++++++++
win32.h | 3 +++
5 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index e0847bc..a9f022e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -279,6 +279,11 @@ AC_ARG_WITH(netstat-path,
)
AC_DEFINE_UNQUOTED(NETSTAT_PATH, "$NETSTAT", [Path to netstat tool])
+AC_ARG_WITH(tmp-dir-path,
+ [ --with-tmp-dir-path=PATH Default tmp-dir to use when not configured
(unset defaults to /tmp)],
+ [TMPDIRPATH="$withval"]
+)
+
AC_ARG_WITH(mem-check,
[ --with-mem-check=TYPE Build with debug memory checking, TYPE = dmalloc
or valgrind],
[MEMCHECK="$withval"]
@@ -566,6 +571,12 @@ LDFLAGS="$LDFLAGS -Wl,--fatal-warnings"
AC_CHECK_FUNC(epoll_create, AC_DEFINE(HAVE_EPOLL_CREATE, 1, [epoll_create
function is defined]))
LDFLAGS="$OLDLDFLAGS"
+dnl set the default temporary directory
+if test -z "$TMPDIRPATH"; then
+ TMPDIRPATH="/tmp"
+fi
+AC_DEFINE_UNQUOTED(DEFAULT_TMPDIR, "$TMPDIRPATH", [Default --tmp-dir])
+
dnl
dnl check for valgrind tool
dnl
diff --git a/options.c b/options.c
index 36e8393..0b91657 100644
--- a/options.c
+++ b/options.c
@@ -766,11 +766,20 @@ init_options (struct options *o, const bool init_gc)
#ifdef ENABLE_X509ALTUSERNAME
o->x509_username_field = X509_USERNAME_FIELD_DEFAULT;
#endif
-#endif
-#endif
+#endif /* USE_SSL */
+#endif /* USE_CRYPTO */
#ifdef ENABLE_PKCS11
o->pkcs11_pin_cache_period = -1;
#endif /* ENABLE_PKCS11 */
+
+ /* Set default --tmp-dir */
+#ifdef WIN32
+ /* On Windows, find temp dir via enviroment variables */
+ o->tmp_dir = win_get_tempdir();
+#else
+ /* Non-windows platforms have this value defined via ./configure */
+ o->tmp_dir = DEFAULT_TMPDIR;
+#endif /* WIN32 */
}
void
@@ -1916,8 +1925,6 @@ options_postprocess_verify_ce (const struct options
*options, const struct conne
msg (M_USAGE, "--client-connect requires --mode server");
if (options->client_disconnect_script)
msg (M_USAGE, "--client-disconnect requires --mode server");
- if (options->tmp_dir)
- msg (M_USAGE, "--tmp-dir requires --mode server");
if (options->client_config_dir || options->ccd_exclusive)
msg (M_USAGE, "--client-config-dir/--ccd-exclusive requires --mode
server");
if (options->enable_c2c)
diff --git a/win/config.h.in b/win/config.h.in
index fb349d0..abf71d2 100644
--- a/win/config.h.in
+++ b/win/config.h.in
@@ -286,6 +286,9 @@ typedef unsigned long in_addr_t;
/* Route command */
#define ROUTE_PATH "route"
+/* Default temporary directory, if not found via getenv() */
+#define DEFAULT_TMPDIR "C:\\WINDOWS\\Temp" /* FIXME: Should be configurable
*/
+
#ifdef _MSC_VER
/* MSVC++ hacks */
#pragma warning(disable:4244) // conversion from 'foo' to 'bar', possible loss
of data
diff --git a/win32.c b/win32.c
index 7c9901e..c9eb184 100644
--- a/win32.c
+++ b/win32.c
@@ -1093,4 +1093,23 @@ env_set_add_win32 (struct env_set *es)
set_win_sys_path (DEFAULT_WIN_SYS_PATH, es);
}
+
+const char *
+win_get_tempdir()
+{
+ static char *tmpdir = NULL;
+
+ /* Try to use %TEMP% or %TMP% */
+ tmpdir = getenv("TEMP");
+ if( !tmpdir ) {
+ tmpdir = getenv("TMP");
+ }
+ if( !tmpdir ) {
+ /* Warn if we're using a hard coded path */
+ msg (M_WARN, "Could not find %TEMP% or %TMP% environment variables. "
+ "Falling back to %s. Consider to use --tmp-dir", DEFAULT_TMPDIR);
+ tmpdir = DEFAULT_TMPDIR;
+ }
+ return tmpdir;
+}
#endif
diff --git a/win32.h b/win32.h
index fcc3062..b6a162e 100644
--- a/win32.h
+++ b/win32.h
@@ -270,5 +270,8 @@ char *get_win_sys_path (void);
/* call self in a subprocess */
void fork_to_self (const char *cmdline);
+/* Find temporary directory */
+const char *win_get_tempdir();
+
#endif
#endif
--
1.7.4