summaryrefslogtreecommitdiff
path: root/src/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn')
-rw-r--r--src/openvpn/buffer.h5
-rw-r--r--src/openvpn/crypto.c19
-rw-r--r--src/openvpn/crypto_backend.h2
-rw-r--r--src/openvpn/init.c12
-rw-r--r--src/openvpn/init.h5
-rw-r--r--src/openvpn/misc.c33
-rw-r--r--src/openvpn/misc.h9
-rw-r--r--src/openvpn/openvpn.c17
-rw-r--r--src/openvpn/openvpn.h3
-rw-r--r--src/openvpn/options.c15
-rw-r--r--src/openvpn/syshead.h4
-rw-r--r--src/openvpn/tun.c26
12 files changed, 93 insertions, 57 deletions
diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h
index 93efb09..d306a04 100644
--- a/src/openvpn/buffer.h
+++ b/src/openvpn/buffer.h
@@ -308,7 +308,10 @@ has_digit (const unsigned char* src)
}
/*
- * printf append to a buffer with overflow check
+ * printf append to a buffer with overflow check,
+ * due to usage of vsnprintf, it will leave space for
+ * a final null character and thus use only
+ * capacity - 1
*/
bool buf_printf (struct buffer *buf, const char *format, ...)
#ifdef __GNUC__
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index aa93a7b..c2d5c27 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -166,11 +166,11 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
/* Encrypt packet ID, payload */
ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)));
- work.len += outlen;
+ ASSERT (buf_inc_len(&work, outlen));
/* Flush the encryption buffer */
- ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
- work.len += outlen;
+ ASSERT (cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
+ ASSERT (buf_inc_len(&work, outlen));
/* For all CBC mode ciphers, check the last block is complete */
ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC ||
@@ -305,18 +305,18 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
CRYPT_ERROR ("cipher init failed");
/* Buffer overflow check (should never happen) */
- if (!buf_safe (&work, buf->len))
- CRYPT_ERROR ("buffer overflow");
+ if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
+ CRYPT_ERROR ("potential buffer overflow");
/* Decrypt packet ID, payload */
if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)))
CRYPT_ERROR ("cipher update failed");
- work.len += outlen;
+ ASSERT (buf_inc_len(&work, outlen));
/* Flush the decryption buffer */
if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen))
CRYPT_ERROR ("cipher final failed");
- work.len += outlen;
+ ASSERT (buf_inc_len(&work, outlen));
dmsg (D_PACKET_CONTENT, "DECRYPT TO: %s",
format_hex (BPTR (&work), BLEN (&work), 80, &gc));
@@ -413,9 +413,8 @@ crypto_adjust_frame_parameters(struct frame *frame,
if (use_iv)
crypto_overhead += cipher_kt_iv_size (kt->cipher);
- if (cipher_kt_mode_cbc (kt->cipher))
- /* worst case padding expansion */
- crypto_overhead += cipher_kt_block_size (kt->cipher);
+ /* extra block required by cipher_ctx_update() */
+ crypto_overhead += cipher_kt_block_size (kt->cipher);
}
crypto_overhead += kt->hmac_length;
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 4e45df0..4c1ce9f 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -333,7 +333,7 @@ int cipher_ctx_reset (cipher_ctx_t *ctx, uint8_t *iv_buf);
* Note that if a complete block cannot be written, data is cached in the
* context, and emitted at a later call to \c cipher_ctx_update, or by a call
* to \c cipher_ctx_final(). This implies that dst should have enough room for
- * src_len + \c cipher_ctx_block_size() - 1.
+ * src_len + \c cipher_ctx_block_size().
*
* @param ctx Cipher's context. May not be NULL.
* @param dst Destination buffer
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index c99e775..71c91a2 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -389,8 +389,8 @@ next_connection_entry (struct context *c)
/*
* Query for private key and auth-user-pass username/passwords
*/
-static void
-init_query_passwords (struct context *c)
+void
+init_query_passwords (const struct context *c)
{
#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
/* Certificate password input */
@@ -520,8 +520,6 @@ context_init_1 (struct context *c)
init_connection_list (c);
- init_query_passwords (c);
-
#if defined(ENABLE_PKCS11)
if (c->first_time) {
int i;
@@ -2775,16 +2773,10 @@ do_init_first_time (struct context *c)
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);
-
/* perform postponed chdir if --daemon */
if (c->did_we_daemonize && c->options.cd_dir == NULL)
platform_chdir("/");
- /* save process ID in a file */
- write_pid (&c0->pid_state);
-
/* should we change scheduling priority? */
platform_nice (c->options.nice);
}
diff --git a/src/openvpn/init.h b/src/openvpn/init.h
index d1908ed..a819bd2 100644
--- a/src/openvpn/init.h
+++ b/src/openvpn/init.h
@@ -63,6 +63,11 @@ void init_instance_handle_signals (struct context *c, const struct env_set *env,
void init_instance (struct context *c, const struct env_set *env, const unsigned int flags);
+/**
+ * Query for private key and auth-user-pass username/passwords.
+ */
+void init_query_passwords (const struct context *c);
+
void do_route (const struct options *options,
struct route_list *route_list,
struct route_ipv6_list *route_ipv6_list,
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index 8408438..f20d059 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -127,30 +127,21 @@ run_up_down (const char *command,
gc_free (&gc);
}
-/* Get the file we will later write our process ID to */
+/* Write our PID to a file */
void
-get_pid_file (const char* filename, struct pid_state *state)
+write_pid (const char *filename)
{
- CLEAR (*state);
if (filename)
{
- state->fp = platform_fopen (filename, "w");
- if (!state->fp)
+ unsigned int pid = 0;
+ FILE *fp = platform_fopen (filename, "w");
+ if (!fp)
msg (M_ERR, "Open error on pid file %s", filename);
- state->filename = filename;
- }
-}
-/* Write our PID to a file */
-void
-write_pid (const struct pid_state *state)
-{
- if (state->filename && state->fp)
- {
- 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);
+ pid = platform_getpid ();
+ fprintf(fp, "%u\n", pid);
+ if (fclose (fp))
+ msg (M_ERR, "Close error on pid file %s", filename);
}
}
@@ -1097,6 +1088,12 @@ get_user_pass_cr (struct user_pass *up,
*/
else if (from_stdin)
{
+#ifndef WIN32
+ /* did we --daemon'ize before asking for passwords? */
+ if ( !isatty(0) && !isatty(2) )
+ { msg(M_FATAL, "neither stdin nor stderr are a tty device, can't ask for %s password. If you used --daemon, you need to use --askpass to make passphrase-protected keys work, and you can not use --auth-nocache.", prefix ); }
+#endif
+
#ifdef ENABLE_CLIENT_CR
if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
{
diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h
index 183898e..e67b5e4 100644
--- a/src/openvpn/misc.h
+++ b/src/openvpn/misc.h
@@ -73,14 +73,7 @@ void run_up_down (const char *command,
const char *script_type,
struct env_set *es);
-/* workspace for get_pid_file/write_pid */
-struct pid_state {
- FILE *fp;
- const char *filename;
-};
-
-void get_pid_file (const char* filename, struct pid_state *state);
-void write_pid (const struct pid_state *state);
+void write_pid (const char *filename);
/* check file protections */
void warn_if_group_others_accessible(const char* filename);
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index 2f327f3..32e326e 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -228,15 +228,28 @@ openvpn_main (int argc, char *argv[])
/* test crypto? */
if (do_test_crypto (&c.options))
break;
-
+
+ /* Query passwords before becoming a daemon if we don't use the
+ * management interface to get them. */
+#ifdef ENABLE_MANAGEMENT
+ if (!(c.options.management_flags & MF_QUERY_PASSWORDS))
+#endif
+ init_query_passwords (&c);
+
/* become a daemon if --daemon */
if (c.first_time)
- c.did_we_daemonize = possibly_become_daemon (&c.options);
+ {
+ c.did_we_daemonize = possibly_become_daemon (&c.options);
+ write_pid (c.options.writepid);
+ }
#ifdef ENABLE_MANAGEMENT
/* open management subsystem */
if (!open_management (&c))
break;
+ /* query for passwords through management interface, if needed */
+ if (c.options.management_flags & MF_QUERY_PASSWORDS)
+ init_query_passwords (&c);
#endif
/* set certain options as environmental variables */
diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h
index bdfa685..10ec859 100644
--- a/src/openvpn/openvpn.h
+++ b/src/openvpn/openvpn.h
@@ -137,9 +137,6 @@ struct context_persist
*/
struct context_0
{
- /* workspace for get_pid_file/write_pid */
- struct pid_state pid_state;
-
/* workspace for --user/--group */
bool uid_gid_specified;
bool uid_gid_set;
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index ff4b07b..007bd8c 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -2774,8 +2774,8 @@ options_postprocess_filechecks (struct options *options)
/* ** Password files ** */
#ifdef ENABLE_SSL
- errs |= check_file_access (CHKACC_FILE, options->key_pass_file, R_OK,
- "--askpass");
+ errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN,
+ options->key_pass_file, R_OK, "--askpass");
#endif /* ENABLE_SSL */
#ifdef ENABLE_MANAGEMENT
errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN,
@@ -3757,11 +3757,16 @@ read_inline_file (struct in_src *is, const char *close_tag, struct gc_arena *gc)
char line[OPTION_LINE_SIZE];
struct buffer buf = alloc_buf (8*OPTION_LINE_SIZE);
char *ret;
+ bool endtagfound = false;
+
while (in_src_get (is, line, sizeof (line)))
{
if (!strncmp (line, close_tag, strlen (close_tag)))
- break;
- if (!buf_safe (&buf, strlen(line)))
+ {
+ endtagfound = true;
+ break;
+ }
+ if (!buf_safe (&buf, strlen(line)+1))
{
/* Increase buffer size */
struct buffer buf2 = alloc_buf (buf.capacity * 2);
@@ -3772,6 +3777,8 @@ read_inline_file (struct in_src *is, const char *close_tag, struct gc_arena *gc)
}
buf_printf (&buf, "%s", line);
}
+ if (!endtagfound)
+ msg (M_WARN, "WARNING: Endtag %s missing", close_tag);
ret = string_alloc (BSTR (&buf), gc);
buf_clear (&buf);
free_buf (&buf);
diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h
index 7075b96..ffba4e8 100644
--- a/src/openvpn/syshead.h
+++ b/src/openvpn/syshead.h
@@ -45,6 +45,10 @@
#define srandom srand
#endif
+#ifdef _MSC_VER // Visual Studio
+#define __func__ __FUNCTION__
+#endif
+
#if defined(__APPLE__)
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070
#define __APPLE_USE_RFC_3542 1
diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 285e774..3e20215 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -1714,6 +1714,32 @@ close_tun (struct tuntap *tt)
argv_msg (M_INFO, &argv);
openvpn_execve_check (&argv, NULL, 0, "Linux ip addr del failed");
+ if (tt->ipv6 && tt->did_ifconfig_ipv6_setup)
+ {
+ const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
+
+#ifdef ENABLE_IPROUTE
+ argv_printf (&argv, "%s -6 addr del %s/%d dev %s",
+ iproute_path,
+ ifconfig_ipv6_local,
+ tt->netbits_ipv6,
+ tt->actual_name
+ );
+ argv_msg (M_INFO, &argv);
+ openvpn_execve_check (&argv, NULL, 0, "Linux ip -6 addr del failed");
+#else
+ argv_printf (&argv,
+ "%s %s del %s/%d",
+ IFCONFIG_PATH,
+ tt->actual_name,
+ ifconfig_ipv6_local,
+ tt->netbits_ipv6
+ );
+ argv_msg (M_INFO, &argv);
+ openvpn_execve_check (&argv, NULL, 0, "Linux ifconfig inet6 del failed");
+#endif
+ }
+
argv_reset (&argv);
gc_free (&gc);
}