From 41ffafc126abd9af67061f4931b7614f3cb898b0 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Iniesta Date: Mon, 10 Aug 2015 16:45:51 +0200 Subject: Imported Upstream version 2.3.8 --- src/openvpn/buffer.h | 5 ++++- src/openvpn/crypto.c | 19 +++++++++---------- src/openvpn/crypto_backend.h | 2 +- src/openvpn/init.c | 12 ++---------- src/openvpn/init.h | 5 +++++ src/openvpn/misc.c | 33 +++++++++++++++------------------ src/openvpn/misc.h | 9 +-------- src/openvpn/openvpn.c | 17 +++++++++++++++-- src/openvpn/openvpn.h | 3 --- src/openvpn/options.c | 15 +++++++++++---- src/openvpn/syshead.h | 4 ++++ src/openvpn/tun.c | 26 ++++++++++++++++++++++++++ 12 files changed, 93 insertions(+), 57 deletions(-) (limited to 'src') 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); } -- cgit v1.2.3