diff options
Diffstat (limited to 'src/openvpn')
60 files changed, 632 insertions, 633 deletions
diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in index ca4635b..a55ea37 100644 --- a/src/openvpn/Makefile.in +++ b/src/openvpn/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -37,17 +37,7 @@ # Required to build Windows resource file VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -110,6 +100,8 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +DIST_COMMON = $(top_srcdir)/build/ltrc.inc $(srcdir)/Makefile.in \ + $(srcdir)/Makefile.am $(top_srcdir)/depcomp # we want unicode entry point but not the macro @WIN32_TRUE@am__append_1 = -municode -UUNICODE @@ -127,7 +119,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/include/openvpn-plugin.h @@ -263,8 +254,6 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/ltrc.inc \ - $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -313,7 +302,6 @@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LZ4_CFLAGS = @LZ4_CFLAGS@ LZ4_LIBS = @LZ4_LIBS@ LZO_CFLAGS = @LZO_CFLAGS@ @@ -514,6 +502,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/ltrc.inc $(am_ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/openvpn/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/openvpn/Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -522,7 +511,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; -$(top_srcdir)/build/ltrc.inc $(am__empty): +$(top_srcdir)/build/ltrc.inc: $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh @@ -903,8 +892,6 @@ uninstall-am: uninstall-sbinPROGRAMS mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS -.PRECIOUS: Makefile - .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" diff --git a/src/openvpn/argv.c b/src/openvpn/argv.c index a71d261..95bdfea 100644 --- a/src/openvpn/argv.c +++ b/src/openvpn/argv.c @@ -36,6 +36,7 @@ #include "syshead.h" #include "argv.h" +#include "integer.h" #include "options.h" static void diff --git a/src/openvpn/block_dns.h b/src/openvpn/block_dns.h index c4b6693..c9a9d70 100644 --- a/src/openvpn/block_dns.h +++ b/src/openvpn/block_dns.h @@ -26,7 +26,7 @@ #ifndef OPENVPN_BLOCK_DNS_H #define OPENVPN_BLOCK_DNS_H -/* Any value less than 5 should work fine. 3 is choosen without any real reason. */ +/* Any value less than 5 should work fine. 3 is chosen without any real reason. */ #define BLOCK_DNS_IFACE_METRIC 3 typedef void (*block_dns_msg_handler_t) (DWORD err, const char *msg); diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c index 87e27ec..a63ce14 100644 --- a/src/openvpn/buffer.c +++ b/src/openvpn/buffer.c @@ -180,7 +180,7 @@ buf_assign(struct buffer *dest, const struct buffer *src) } struct buffer -clear_buf() +clear_buf(void) { struct buffer buf; CLEAR(buf); diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h index 8bc4428..1ed5631 100644 --- a/src/openvpn/buffer.h +++ b/src/openvpn/buffer.h @@ -91,7 +91,7 @@ struct gc_entry }; /** - * Gargabe collection entry for a specially allocated structure that needs + * Garbage collection entry for a specially allocated structure that needs * a custom free function to be freed like struct addrinfo * */ diff --git a/src/openvpn/comp-lz4.c b/src/openvpn/comp-lz4.c index 6e40c32..9598853 100644 --- a/src/openvpn/comp-lz4.c +++ b/src/openvpn/comp-lz4.c @@ -43,6 +43,7 @@ #include "memdbg.h" + static void lz4_compress_init(struct compress_context *compctx) { @@ -86,7 +87,7 @@ do_lz4_compress(struct buffer *buf, return false; } - zlen = LZ4_compress_limitedOutput((const char *)BPTR(buf), (char *)BPTR(work), BLEN(buf), zlen_max ); + zlen = LZ4_compress_default((const char *)BPTR(buf), (char *)BPTR(work), BLEN(buf), zlen_max); if (zlen <= 0) { @@ -185,7 +186,7 @@ lz4v2_compress(struct buffer *buf, struct buffer work, } } -void +static void do_lz4_decompress(size_t zlen_max, struct buffer *work, struct buffer *buf, diff --git a/src/openvpn/console.c b/src/openvpn/console.c index eb6944d..7e17024 100644 --- a/src/openvpn/console.c +++ b/src/openvpn/console.c @@ -44,7 +44,7 @@ struct _query_user query_user[QUERY_USER_NUMSLOTS]; /* GLOBAL */ void -query_user_clear() +query_user_clear(void) { int i; diff --git a/src/openvpn/console.h b/src/openvpn/console.h index aa51e6f..3f74e77 100644 --- a/src/openvpn/console.h +++ b/src/openvpn/console.h @@ -46,7 +46,7 @@ extern struct _query_user query_user[]; /**< Global variable, declared in conso * Wipes all data put into all of the query_user structs * */ -void query_user_clear(); +void query_user_clear(void); /** @@ -72,7 +72,7 @@ void query_user_add(char *prompt, size_t prompt_len, * * @return True if executing all the defined steps completed successfully */ -bool query_user_exec_builtin(); +bool query_user_exec_builtin(void); #if defined(ENABLE_SYSTEMD) @@ -83,7 +83,7 @@ bool query_user_exec_builtin(); * * @return True if executing all the defined steps completed successfully */ -bool query_user_exec(); +bool query_user_exec(void); #else /* ENABLE_SYSTEMD not defined*/ /** @@ -92,7 +92,7 @@ bool query_user_exec(); * */ static bool -query_user_exec() +query_user_exec(void) { return query_user_exec_builtin(); } diff --git a/src/openvpn/console_builtin.c b/src/openvpn/console_builtin.c index 7b95da9..f005ed7 100644 --- a/src/openvpn/console_builtin.c +++ b/src/openvpn/console_builtin.c @@ -267,7 +267,7 @@ get_console_input(const char *prompt, const bool echo, char *input, const int ca * */ bool -query_user_exec_builtin() +query_user_exec_builtin(void) { bool ret = true; /* Presume everything goes okay */ int i; diff --git a/src/openvpn/console_systemd.c b/src/openvpn/console_systemd.c index 8cee8c8..e7a72ae 100644 --- a/src/openvpn/console_systemd.c +++ b/src/openvpn/console_systemd.c @@ -41,7 +41,7 @@ */ static bool -check_systemd_running() +check_systemd_running(void) { struct stat c; @@ -95,7 +95,7 @@ get_console_input_systemd(const char *prompt, const bool echo, char *input, cons * */ bool -query_user_exec() +query_user_exec(void) { bool ret = true; /* Presume everything goes okay */ int i; diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 5f482d0..03e880e 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -895,6 +895,26 @@ init_key_ctx(struct key_ctx *ctx, struct key *key, } void +init_key_ctx_bi(struct key_ctx_bi *ctx, const struct key2 *key2, + int key_direction, const struct key_type *kt, const char *name) +{ + char log_prefix[128] = { 0 }; + struct key_direction_state kds; + + key_direction_state_init(&kds, key_direction); + + openvpn_snprintf(log_prefix, sizeof(log_prefix), "Outgoing %s", name); + init_key_ctx(&ctx->encrypt, &key2->keys[kds.out_key], kt, + OPENVPN_OP_ENCRYPT, log_prefix); + + openvpn_snprintf(log_prefix, sizeof(log_prefix), "Incoming %s", name); + init_key_ctx(&ctx->decrypt, &key2->keys[kds.in_key], kt, + OPENVPN_OP_DECRYPT, log_prefix); + + ctx->initialized = true; +} + +void free_key_ctx(struct key_ctx *ctx) { if (ctx->cipher) @@ -1184,7 +1204,6 @@ crypto_read_openvpn_key(const struct key_type *key_type, { struct key2 key2; struct key_direction_state kds; - char log_prefix[128] = { 0 }; if (key_inline) { @@ -1209,13 +1228,7 @@ crypto_read_openvpn_key(const struct key_type *key_type, must_have_n_keys(key_file, opt_name, &key2, kds.need_keys); /* initialize key in both directions */ - openvpn_snprintf(log_prefix, sizeof(log_prefix), "Outgoing %s", key_name); - init_key_ctx(&ctx->encrypt, &key2.keys[kds.out_key], key_type, - OPENVPN_OP_ENCRYPT, log_prefix); - openvpn_snprintf(log_prefix, sizeof(log_prefix), "Incoming %s", key_name); - init_key_ctx(&ctx->decrypt, &key2.keys[kds.in_key], key_type, - OPENVPN_OP_DECRYPT, log_prefix); - + init_key_ctx_bi(ctx, &key2, key_direction, key_type, key_name); secure_memzero(&key2, sizeof(key2)); } @@ -1284,7 +1297,7 @@ read_key_file(struct key2 *key2, const char *file, const unsigned int flags) fd = platform_open(file, O_RDONLY, 0); if (fd == -1) { - msg(M_ERR, "Cannot open file key file '%s'", file); + msg(M_ERR, "Cannot open key file '%s'", file); } size = read(fd, in.data, in.capacity); if (size < 0) @@ -1676,6 +1689,11 @@ read_key(struct key *key, const struct key_type *kt, struct buffer *buf) goto read_err; } + if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length) + { + goto key_len_err; + } + if (!buf_read(buf, key->cipher, cipher_length)) { goto read_err; @@ -1685,11 +1703,6 @@ read_key(struct key *key, const struct key_type *kt, struct buffer *buf) goto read_err; } - if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length) - { - goto key_len_err; - } - return 1; read_err: @@ -1716,7 +1729,7 @@ static int nonce_secret_len = 0; /* GLOBAL */ /* Reset the nonce value, also done periodically to refresh entropy */ static void -prng_reset_nonce() +prng_reset_nonce(void) { const int size = md_kt_size(nonce_md) + nonce_secret_len; #if 1 /* Must be 1 for real usage */ @@ -1795,7 +1808,7 @@ prng_bytes(uint8_t *output, int len) /* an analogue to the random() function, but use prng_bytes */ long int -get_random() +get_random(void) { long int l; prng_bytes((unsigned char *)&l, sizeof(l)); diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h index 8818c01..0cdd30f 100644 --- a/src/openvpn/crypto.h +++ b/src/openvpn/crypto.h @@ -323,6 +323,10 @@ void init_key_ctx(struct key_ctx *ctx, struct key *key, void free_key_ctx(struct key_ctx *ctx); +void init_key_ctx_bi(struct key_ctx_bi *ctx, const struct key2 *key2, + int key_direction, const struct key_type *kt, + const char *name); + void free_key_ctx_bi(struct key_ctx_bi *ctx); @@ -459,7 +463,7 @@ void prng_init(const char *md_name, const int nonce_secret_len_parm); */ void prng_bytes(uint8_t *output, int len); -void prng_uninit(); +void prng_uninit(void); void test_crypto(struct crypto_options *co, struct frame *f); diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index 24bc315..0cb7f81 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -159,7 +159,7 @@ print_cipher(const cipher_kt_t *info) } void -show_available_ciphers() +show_available_ciphers(void) { const int *ciphers = mbedtls_cipher_list(); @@ -196,7 +196,7 @@ show_available_ciphers() } void -show_available_digests() +show_available_digests(void) { const int *digests = mbedtls_md_list(); @@ -223,7 +223,7 @@ show_available_digests() } void -show_available_engines() +show_available_engines(void) { printf("Sorry, mbed TLS hardware crypto engine functionality is not " "available\n"); @@ -243,7 +243,7 @@ show_available_engines() * entropy gathering function. */ mbedtls_ctr_drbg_context * -rand_ctx_get() +rand_ctx_get(void) { static mbedtls_entropy_context ec = {0}; static mbedtls_ctr_drbg_context cd_ctx = {0}; @@ -280,7 +280,7 @@ rand_ctx_get() #ifdef ENABLE_PREDICTION_RESISTANCE void -rand_ctx_enable_prediction_resistance() +rand_ctx_enable_prediction_resistance(void) { mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get(); diff --git a/src/openvpn/crypto_mbedtls.h b/src/openvpn/crypto_mbedtls.h index a434ce3..4417b92 100644 --- a/src/openvpn/crypto_mbedtls.h +++ b/src/openvpn/crypto_mbedtls.h @@ -85,13 +85,13 @@ typedef mbedtls_md_context_t hmac_ctx_t; * added. During initialisation, a personalisation string will be added based * on the time, the PID, and a pointer to the random context. */ -mbedtls_ctr_drbg_context *rand_ctx_get(); +mbedtls_ctr_drbg_context *rand_ctx_get(void); #ifdef ENABLE_PREDICTION_RESISTANCE /** * Enable prediction resistance on the random number generator. */ -void rand_ctx_enable_prediction_resistance(); +void rand_ctx_enable_prediction_resistance(void); #endif diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index a55e65c..9e8d3f3 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -280,7 +280,7 @@ print_cipher(const EVP_CIPHER *cipher) } void -show_available_ciphers() +show_available_ciphers(void) { int nid; size_t i; @@ -339,7 +339,7 @@ show_available_ciphers() } void -show_available_digests() +show_available_digests(void) { int nid; @@ -364,7 +364,7 @@ show_available_digests() } void -show_available_engines() +show_available_engines(void) { #if HAVE_OPENSSL_ENGINE /* Only defined for OpenSSL */ ENGINE *e; @@ -930,7 +930,7 @@ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len, { ASSERT(NULL != kt && NULL != ctx); - HMAC_CTX_init(ctx); + HMAC_CTX_reset(ctx); HMAC_Init_ex(ctx, key, key_len, kt, NULL); /* make sure we used a big enough key */ diff --git a/src/openvpn/error.c b/src/openvpn/error.c index ce50ff9..04bf0da 100644 --- a/src/openvpn/error.c +++ b/src/openvpn/error.c @@ -159,7 +159,7 @@ set_machine_readable_output(bool parsable) } void -error_reset() +error_reset(void) { use_syslog = std_redir = false; suppress_timestamps = false; @@ -267,7 +267,7 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist) if ((flags & M_ERRNO) && e) { openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)", - m1, strerror_ts(e, &gc), e); + m1, strerror(e), e); SWAP; } @@ -480,7 +480,7 @@ open_syslog(const char *pgmname, bool stdio_to_null) } void -close_syslog() +close_syslog(void) { #if SYSLOG_CAPABILITY if (use_syslog) @@ -635,7 +635,7 @@ unsigned int x_cs_verbose_level; /* GLOBAL */ unsigned int x_cs_err_delay_ms; /* GLOBAL */ void -reset_check_status() +reset_check_status(void) { x_cs_info_level = 0; x_cs_verbose_level = 0; @@ -693,20 +693,15 @@ x_check_status(int status, { if (extended_msg) { - msg(x_cs_info_level, "%s %s [%s]: %s (code=%d)", - description, + msg(x_cs_info_level, "%s %s [%s]: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - extended_msg, - strerror_ts(my_errno, &gc), - my_errno); + extended_msg, strerror(my_errno), my_errno); } else { - msg(x_cs_info_level, "%s %s: %s (code=%d)", - description, + msg(x_cs_info_level, "%s %s: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - strerror_ts(my_errno, &gc), - my_errno); + strerror(my_errno), my_errno); } if (x_cs_err_delay_ms) diff --git a/src/openvpn/error.h b/src/openvpn/error.h index 14ef7e6..023cec4 100644 --- a/src/openvpn/error.h +++ b/src/openvpn/error.h @@ -261,7 +261,7 @@ void msg_forked(void); void open_syslog(const char *pgmname, bool stdio_to_null); -void close_syslog(); +void close_syslog(void); /* log file output */ void redirect_stdout_stderr(const char *file, bool append); diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 371ddca..6cc5938 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -756,7 +756,7 @@ read_incoming_link(struct context *c) if (event_timeout_defined(&c->c2.explicit_exit_notification_interval)) { msg(D_STREAM_ERRORS, "Connection reset during exit notification period, ignoring [%d]", status); - openvpn_sleep(1); + management_sleep(1); } else #endif @@ -1007,7 +1007,7 @@ process_incoming_link_part2(struct context *c, struct link_socket_info *lsi, con } } -void +static void process_incoming_link(struct context *c) { perf_push(PERF_PROC_IN_LINK); diff --git a/src/openvpn/fragment.c b/src/openvpn/fragment.c index 38de62f..84f0121 100644 --- a/src/openvpn/fragment.c +++ b/src/openvpn/fragment.c @@ -208,7 +208,7 @@ fragment_incoming(struct fragment_master *f, struct buffer *buf, } /* is this the first fragment for our sequence number? */ - if (!frag->defined || (frag->defined && frag->max_frag_size != size)) + if (!frag->defined || frag->max_frag_size != size) { frag->defined = true; frag->max_frag_size = size; diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 0652ef4..133a9f5 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -94,6 +94,94 @@ context_clear_all_except_first_time(struct context *c) } /* + * Pass tunnel endpoint and MTU parms to a user-supplied script. + * Used to execute the up/down script/plugins. + */ +static void +run_up_down(const char *command, + const struct plugin_list *plugins, + int plugin_type, + const char *arg, +#ifdef _WIN32 + DWORD adapter_index, +#endif + const char *dev_type, + int tun_mtu, + int link_mtu, + const char *ifconfig_local, + const char *ifconfig_remote, + const char *context, + const char *signal_text, + const char *script_type, + struct env_set *es) +{ + struct gc_arena gc = gc_new(); + + if (signal_text) + { + setenv_str(es, "signal", signal_text); + } + setenv_str(es, "script_context", context); + setenv_int(es, "tun_mtu", tun_mtu); + setenv_int(es, "link_mtu", link_mtu); + setenv_str(es, "dev", arg); + if (dev_type) + { + setenv_str(es, "dev_type", dev_type); + } +#ifdef _WIN32 + setenv_int(es, "dev_idx", adapter_index); +#endif + + if (!ifconfig_local) + { + ifconfig_local = ""; + } + if (!ifconfig_remote) + { + ifconfig_remote = ""; + } + if (!context) + { + context = ""; + } + + if (plugin_defined(plugins, plugin_type)) + { + struct argv argv = argv_new(); + ASSERT(arg); + argv_printf(&argv, + "%s %d %d %s %s %s", + arg, + tun_mtu, link_mtu, + ifconfig_local, ifconfig_remote, + context); + + if (plugin_call(plugins, plugin_type, &argv, NULL, es) != OPENVPN_PLUGIN_FUNC_SUCCESS) + { + msg(M_FATAL, "ERROR: up/down plugin call failed"); + } + + argv_reset(&argv); + } + + if (command) + { + struct argv argv = argv_new(); + ASSERT(arg); + setenv_str(es, "script_type", script_type); + argv_parse_cmd(&argv, command); + argv_printf_cat(&argv, "%s %d %d %s %s %s", arg, tun_mtu, link_mtu, + ifconfig_local, ifconfig_remote, context); + argv_msg(M_INFO, &argv); + openvpn_run_script(&argv, es, S_FATAL, "--up/--down"); + argv_reset(&argv); + } + + gc_free(&gc); +} + +/* * Should be called after options->ce is modified at the top * of a SIGUSR1 restart. */ @@ -150,7 +238,7 @@ management_callback_proxy_cmd(void *arg, const char **p) else if (streq(p[1], "SOCKS")) { ce->socks_proxy_server = string_alloc(p[2], gc); - ce->socks_proxy_port = p[3]; + ce->socks_proxy_port = string_alloc(p[3], gc); ret = true; } } @@ -610,6 +698,7 @@ init_port_share(struct context *c) #endif /* if PORT_SHARE */ + bool init_static(void) { @@ -619,8 +708,20 @@ init_static(void) crypto_init_dmalloc(); #endif - init_random_seed(); /* init random() function, only used as - * source for weak random numbers */ + + /* + * Initialize random number seed. random() is only used + * when "weak" random numbers are acceptable. + * SSL library routines are always used when cryptographically + * strong random numbers are required. + */ + struct timeval tv; + if (!gettimeofday(&tv, NULL)) + { + const unsigned int seed = (unsigned int) tv.tv_sec ^ tv.tv_usec; + srandom(seed); + } + error_reset(); /* initialize error.c */ reset_check_status(); /* initialize status check code in socket.c */ @@ -1904,7 +2005,7 @@ do_close_tun(struct context *c, bool force) } void -tun_abort() +tun_abort(void) { struct context *c = static_context; if (c) @@ -1969,7 +2070,7 @@ do_up(struct context *c, bool pulled_options, unsigned int option_types_found) /* if so, close tun, delete routes, then reinitialize tun and add routes */ msg(M_INFO, "NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device."); do_close_tun(c, true); - openvpn_sleep(1); + management_sleep(1); c->c2.did_open_tun = do_open_tun(c); update_time(); } @@ -2263,7 +2364,7 @@ socket_restart_pause(struct context *c) if (sec) { msg(D_RESTART, "Restart pause, %d second(s)", sec); - openvpn_sleep(sec); + management_sleep(sec); } } diff --git a/src/openvpn/integer.h b/src/openvpn/integer.h index 240781b..9bb00a3 100644 --- a/src/openvpn/integer.h +++ b/src/openvpn/integer.h @@ -118,6 +118,24 @@ modulo_add(int x, int y, int mod) return sum; } +/* + * Return the next largest power of 2 + * or u if u is a power of 2. + */ +static inline size_t +adjust_power_of_2(size_t u) +{ + size_t ret = 1; + + while (ret < u) + { + ret <<= 1; + ASSERT(ret > 0); + } + + return ret; +} + static inline int index_verify(int index, int size, const char *file, int line) { diff --git a/src/openvpn/interval.h b/src/openvpn/interval.h index 8095c0b..dd5dfbc 100644 --- a/src/openvpn/interval.h +++ b/src/openvpn/interval.h @@ -155,7 +155,7 @@ event_timeout_clear(struct event_timeout *et) } static inline struct event_timeout -event_timeout_clear_ret() +event_timeout_clear_ret(void) { struct event_timeout ret; event_timeout_clear(&ret); diff --git a/src/openvpn/list.c b/src/openvpn/list.c index edca6f7..91765d2 100644 --- a/src/openvpn/list.c +++ b/src/openvpn/list.c @@ -31,6 +31,7 @@ #if P2MP_SERVER +#include "integer.h" #include "list.h" #include "misc.h" diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index c2e8dc7..88121a3 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -68,7 +68,7 @@ static void man_output_standalone(struct management *man, volatile int *signal_r static void man_reset_client_socket(struct management *man, const bool exiting); static void -man_help() +man_help(void) { msg(M_CLIENT, "Management Interface for %s", title_string); msg(M_CLIENT, "Commands:"); @@ -1878,17 +1878,15 @@ man_connect(struct management *man) #if UNIX_SOCK_SUPPORT if (man->settings.flags & MF_UNIX_SOCK) { - msg(D_LINK_ERRORS, - "MANAGEMENT: connect to unix socket %s failed: %s", - sockaddr_unix_name(&man->settings.local_unix, "NULL"), - strerror_ts(status, &gc)); + msg(D_LINK_ERRORS | M_ERRNO, + "MANAGEMENT: connect to unix socket %s failed", + sockaddr_unix_name(&man->settings.local_unix, "NULL")); } else #endif - msg(D_LINK_ERRORS, - "MANAGEMENT: connect to %s failed: %s", - print_sockaddr(man->settings.local->ai_addr, &gc), - strerror_ts(status, &gc)); + msg(D_LINK_ERRORS | M_ERRNO, + "MANAGEMENT: connect to %s failed", + print_sockaddr(man->settings.local->ai_addr, &gc)); throw_signal_soft(SIGTERM, "management-connect-failed"); goto done; } @@ -2008,9 +2006,8 @@ man_io_error(struct management *man, const char *prefix) if (!ignore_sys_error(err)) { struct gc_arena gc = gc_new(); - msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", - prefix, - strerror_ts(err, &gc)); + msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", prefix, + strerror(err)); gc_free(&gc); return true; } @@ -3504,7 +3501,9 @@ management_query_user_pass(struct management *man, */ if (ret) { - man->connection.up_query.nocache = up->nocache; /* preserve caller's nocache setting */ + /* preserve caller's settings */ + man->connection.up_query.nocache = up->nocache; + man->connection.up_query.wait_for_push = up->wait_for_push; *up = man->connection.up_query; } secure_memzero(&man->connection.up_query, sizeof(man->connection.up_query)); @@ -3516,7 +3515,7 @@ management_query_user_pass(struct management *man, #ifdef MANAGMENT_EXTERNAL_KEY -int +static int management_query_multiline(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input) { @@ -3592,7 +3591,7 @@ done: return ret; } -char * +static char * /* returns allocated base64 signature */ management_query_multiline_flatten_newline(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input) @@ -3621,7 +3620,7 @@ management_query_multiline_flatten_newline(struct management *man, return result; } -char * +static char * /* returns allocated base64 signature */ management_query_multiline_flatten(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input) @@ -4000,9 +3999,25 @@ log_history_ref(const struct log_history *h, const int index) } } +void +management_sleep(const int n) +{ + if (management) + { + management_event_loop_n_seconds(management, n); + } + else + { + sleep(n); + } +} + #else /* ifdef ENABLE_MANAGEMENT */ -static void -dummy(void) + +void +management_sleep(const int n) { + sleep(n); } + #endif /* ENABLE_MANAGEMENT */ diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h index 542cc07..676be64 100644 --- a/src/openvpn/manage.h +++ b/src/openvpn/manage.h @@ -605,4 +605,11 @@ management_bytes_server(struct management *man, #endif /* MANAGEMENT_DEF_AUTH */ #endif /* ifdef ENABLE_MANAGEMENT */ + +/** + * A sleep function that services the management layer for n seconds rather + * than doing nothing. + */ +void management_sleep(const int n); + #endif /* ifndef MANAGE_H */ diff --git a/src/openvpn/mbuf.c b/src/openvpn/mbuf.c index fafbce0..f969a2b 100644 --- a/src/openvpn/mbuf.c +++ b/src/openvpn/mbuf.c @@ -33,6 +33,7 @@ #include "buffer.h" #include "error.h" +#include "integer.h" #include "misc.h" #include "mbuf.h" diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index fbd9938..8c7f611 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -55,116 +55,6 @@ const char *iproute_path = IPROUTE_PATH; /* GLOBAL */ int script_security = SSEC_BUILT_IN; /* GLOBAL */ /* - * Pass tunnel endpoint and MTU parms to a user-supplied script. - * Used to execute the up/down script/plugins. - */ -void -run_up_down(const char *command, - const struct plugin_list *plugins, - int plugin_type, - const char *arg, -#ifdef _WIN32 - DWORD adapter_index, -#endif - const char *dev_type, - int tun_mtu, - int link_mtu, - const char *ifconfig_local, - const char *ifconfig_remote, - const char *context, - const char *signal_text, - const char *script_type, - struct env_set *es) -{ - struct gc_arena gc = gc_new(); - - if (signal_text) - { - setenv_str(es, "signal", signal_text); - } - setenv_str(es, "script_context", context); - setenv_int(es, "tun_mtu", tun_mtu); - setenv_int(es, "link_mtu", link_mtu); - setenv_str(es, "dev", arg); - if (dev_type) - { - setenv_str(es, "dev_type", dev_type); - } -#ifdef _WIN32 - setenv_int(es, "dev_idx", adapter_index); -#endif - - if (!ifconfig_local) - { - ifconfig_local = ""; - } - if (!ifconfig_remote) - { - ifconfig_remote = ""; - } - if (!context) - { - context = ""; - } - - if (plugin_defined(plugins, plugin_type)) - { - struct argv argv = argv_new(); - ASSERT(arg); - argv_printf(&argv, - "%s %d %d %s %s %s", - arg, - tun_mtu, link_mtu, - ifconfig_local, ifconfig_remote, - context); - - if (plugin_call(plugins, plugin_type, &argv, NULL, es) != OPENVPN_PLUGIN_FUNC_SUCCESS) - { - msg(M_FATAL, "ERROR: up/down plugin call failed"); - } - - argv_reset(&argv); - } - - if (command) - { - struct argv argv = argv_new(); - ASSERT(arg); - setenv_str(es, "script_type", script_type); - argv_parse_cmd(&argv, command); - argv_printf_cat(&argv, "%s %d %d %s %s %s", arg, tun_mtu, link_mtu, - ifconfig_local, ifconfig_remote, context); - argv_msg(M_INFO, &argv); - openvpn_run_script(&argv, es, S_FATAL, "--up/--down"); - argv_reset(&argv); - } - - gc_free(&gc); -} - -/* Write our PID to a file */ -void -write_pid(const char *filename) -{ - if (filename) - { - unsigned int pid = 0; - FILE *fp = platform_fopen(filename, "w"); - if (!fp) - { - msg(M_ERR, "Open error on pid file %s", filename); - } - - pid = platform_getpid(); - fprintf(fp, "%u\n", pid); - if (fclose(fp)) - { - msg(M_ERR, "Close error on pid file %s", filename); - } - } -} - -/* * Set standard file descriptors to /dev/null */ void @@ -426,40 +316,6 @@ openvpn_popen(const struct argv *a, const struct env_set *es) /* - * Initialize random number seed. random() is only used - * when "weak" random numbers are acceptable. - * OpenSSL routines are always used when cryptographically - * strong random numbers are required. - */ - -void -init_random_seed(void) -{ - struct timeval tv; - - if (!gettimeofday(&tv, NULL)) - { - const unsigned int seed = (unsigned int) tv.tv_sec ^ tv.tv_usec; - srandom(seed); - } -} - -/* thread-safe strerror */ - -const char * -strerror_ts(int errnum, struct gc_arena *gc) -{ -#ifdef HAVE_STRERROR - struct buffer out = alloc_buf_gc(256, gc); - - buf_printf(&out, "%s", openvpn_strerror(errnum, gc)); - return BSTR(&out); -#else - return "[error string unavailable]"; -#endif -} - -/* * Set environmental variable (int or string). * * On Posix, we use putenv for portability, @@ -484,29 +340,6 @@ construct_name_value(const char *name, const char *value, struct gc_arena *gc) return BSTR(&out); } -bool -deconstruct_name_value(const char *str, const char **name, const char **value, struct gc_arena *gc) -{ - char *cp; - - ASSERT(str); - ASSERT(name && value); - - *name = cp = string_alloc(str, gc); - *value = NULL; - - while ((*cp)) - { - if (*cp == '=' && !*value) - { - *cp = 0; - *value = cp + 1; - } - ++cp; - } - return *name && *value; -} - static bool env_string_equal(const char *s1, const char *s2) { @@ -886,8 +719,6 @@ test_file(const char *filename) return ret; } -#ifdef ENABLE_CRYPTO - /* create a temporary filename in directory */ const char * create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc) @@ -900,15 +731,11 @@ create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc) do { - uint8_t rndbytes[16]; - const char *rndstr; - ++attempts; ++counter; - prng_bytes(rndbytes, sizeof rndbytes); - rndstr = format_hex_ex(rndbytes, sizeof rndbytes, 40, 0, NULL, gc); - buf_printf(&fname, PACKAGE "_%s_%s.tmp", prefix, rndstr); + buf_printf(&fname, PACKAGE "_%s_%08lx%08lx.tmp", prefix, + (unsigned long) get_random(), (unsigned long) get_random()); retfname = gen_path(directory, BSTR(&fname), gc); if (!retfname) @@ -928,10 +755,8 @@ create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc) else if (fd == -1 && errno != EEXIST) { /* Something else went wrong, no need to retry. */ - struct gc_arena gcerr = gc_new(); - msg(M_FATAL, "Could not create temporary file '%s': %s", - retfname, strerror_ts(errno, &gcerr)); - gc_free(&gcerr); + msg(M_FATAL | M_ERRNO, "Could not create temporary file '%s'", + retfname); return NULL; } } @@ -941,6 +766,8 @@ create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc) return NULL; } +#ifdef ENABLE_CRYPTO + /* * Prepend a random string to hostname to prevent DNS caching. * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov. @@ -1632,37 +1459,6 @@ make_extended_arg_array(char **p, struct gc_arena *gc) } } -void -openvpn_sleep(const int n) -{ -#ifdef ENABLE_MANAGEMENT - if (management) - { - management_event_loop_n_seconds(management, n); - return; - } -#endif - sleep(n); -} - -/* - * Return the next largest power of 2 - * or u if u is a power of 2. - */ -size_t -adjust_power_of_2(size_t u) -{ - size_t ret = 1; - - while (ret < u) - { - ret <<= 1; - ASSERT(ret > 0); - } - - return ret; -} - /* * Remove security-sensitive strings from control message * so that they will not be output to log file. diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index ce96549..eb39ce3 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -51,25 +51,6 @@ struct env_set { struct env_item *list; }; -void run_up_down(const char *command, - const struct plugin_list *plugins, - int plugin_type, - const char *arg, -#ifdef _WIN32 - DWORD adapter_index, -#endif - const char *dev_type, - int tun_mtu, - int link_mtu, - const char *ifconfig_local, - const char *ifconfig_remote, - const char *context, - const char *signal_text, - const char *script_type, - struct env_set *es); - -void write_pid(const char *filename); - /* system flags */ #define S_SCRIPT (1<<0) #define S_FATAL (1<<1) @@ -95,12 +76,6 @@ openvpn_run_script(const struct argv *a, const struct env_set *es, const unsigne } -#ifdef HAVE_STRERROR -/* a thread-safe version of strerror */ -const char *strerror_ts(int errnum, struct gc_arena *gc); - -#endif - /* Set standard file descriptors to /dev/null */ void set_std_files_to_null(bool stdin_only); @@ -108,9 +83,6 @@ void set_std_files_to_null(bool stdin_only); extern int inetd_socket_descriptor; void save_inetd_socket_descriptor(void); -/* init random() function, only used as source for weak random numbers, when !ENABLE_CRYPTO */ -void init_random_seed(void); - /* set/delete environmental variable */ void setenv_str_ex(struct env_set *es, const char *name, @@ -298,12 +270,6 @@ bool env_safe_to_print(const char *str); /* returns true if environmental variable may be passed to an external program */ bool env_allowed(const char *str); -/* - * A sleep function that services the management layer for n - * seconds rather than doing nothing. - */ -void openvpn_sleep(const int n); - void configure_path(void); const char *sanitize_control_message(const char *str, struct gc_arena *gc); @@ -327,8 +293,6 @@ extern const char *iproute_path; #define SSEC_PW_ENV 3 /* allow calling of built-in programs and user-defined scripts that may receive a password as an environmental variable */ extern int script_security; /* GLOBAL */ -/* return the next largest power of 2 */ -size_t adjust_power_of_2(size_t u); #define COMPAT_FLAG_QUERY 0 /** compat_flags operator: Query for a flag */ #define COMPAT_FLAG_SET (1<<0) /** compat_flags operator: Set a compat flag */ diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index 7b46a6a..74ee360 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -159,9 +159,8 @@ mroute_extract_addr_arp(struct mroute_addr *src, #endif /* ifdef ENABLE_PF */ unsigned int -mroute_extract_addr_ipv4(struct mroute_addr *src, - struct mroute_addr *dest, - const struct buffer *buf) +mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest, + const struct buffer *buf) { unsigned int ret = 0; if (BLEN(buf) >= 1) @@ -267,7 +266,7 @@ mroute_extract_addr_ether(struct mroute_addr *src, switch (ntohs(eth->proto)) { case OPENVPN_ETH_P_IPV4: - ret |= (mroute_extract_addr_ipv4(esrc, edest, &b) << MROUTE_SEC_SHIFT); + ret |= (mroute_extract_addr_ip(esrc, edest, &b) << MROUTE_SEC_SHIFT); break; case OPENVPN_ETH_P_ARP: diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h index e57a950..35361fb 100644 --- a/src/openvpn/mroute.h +++ b/src/openvpn/mroute.h @@ -181,9 +181,9 @@ mroute_extract_addr_from_packet(struct mroute_addr *src, const struct buffer *buf, int tunnel_type) { - unsigned int mroute_extract_addr_ipv4(struct mroute_addr *src, - struct mroute_addr *dest, - const struct buffer *buf); + unsigned int mroute_extract_addr_ip(struct mroute_addr *src, + struct mroute_addr *dest, + const struct buffer *buf); unsigned int mroute_extract_addr_ether(struct mroute_addr *src, struct mroute_addr *dest, @@ -195,7 +195,7 @@ mroute_extract_addr_from_packet(struct mroute_addr *src, verify_align_4(buf); if (tunnel_type == DEV_TYPE_TUN) { - ret = mroute_extract_addr_ipv4(src, dest, buf); + ret = mroute_extract_addr_ip(src, dest, buf); } else if (tunnel_type == DEV_TYPE_TAP) { diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c index cb940d8..3cb5211 100644 --- a/src/openvpn/mtcp.c +++ b/src/openvpn/mtcp.c @@ -521,7 +521,7 @@ multi_tcp_dispatch(struct multi_context *m, struct multi_instance *mi, const int return touched; } -int +static int multi_tcp_post(struct multi_context *m, struct multi_instance *mi, const int action) { struct context *c = multi_tcp_context(m, mi); @@ -797,7 +797,7 @@ tunnel_server_tcp(struct context *top) multi.top.c2.inotify_fd = inotify_init(); if (multi.top.c2.inotify_fd < 0) { - msg(D_MULTI_ERRORS, "MULTI: inotify_init error: %s", strerror(errno)); + msg(D_MULTI_ERRORS | M_ERRNO, "MULTI: inotify_init error"); } #endif diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 793678d..eb28ca2 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -325,7 +325,7 @@ tunnel_server_udp_single_threaded(struct context *top) multi.top.c2.inotify_fd = inotify_init(); if (multi.top.c2.inotify_fd < 0) { - msg(D_MULTI_ERRORS, "MULTI: inotify_init error: %s", strerror(errno)); + msg(D_MULTI_ERRORS | M_ERRNO, "MULTI: inotify_init error"); } #endif diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 8d3d67f..c798c43 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -485,7 +485,7 @@ multi_instance_string(const struct multi_instance *mi, bool null, struct gc_aren } } -void +static void generate_prefix(struct multi_instance *mi) { struct gc_arena gc = gc_new(); @@ -2355,7 +2355,7 @@ multi_process_post(struct multi_context *m, struct multi_instance *mi, const uns } else { - msg(M_NONFATAL, "MULTI: inotify_add_watch error: %s", strerror(errno)); + msg(M_NONFATAL | M_ERRNO, "MULTI: inotify_add_watch error"); } } #endif @@ -2967,7 +2967,7 @@ gremlin_flood_clients(struct multi_context *m) } #endif /* ifdef ENABLE_DEBUG */ -bool +static bool stale_route_check_trigger(struct multi_context *m) { struct timeval null; diff --git a/src/openvpn/ntlm.c b/src/openvpn/ntlm.c index 0b1163e..077fa3e 100644 --- a/src/openvpn/ntlm.c +++ b/src/openvpn/ntlm.c @@ -60,45 +60,47 @@ static void create_des_keys(const unsigned char *hash, unsigned char *key) { key[0] = hash[0]; - key[1] = ((hash[0]&1)<<7)|(hash[1]>>1); - key[2] = ((hash[1]&3)<<6)|(hash[2]>>2); - key[3] = ((hash[2]&7)<<5)|(hash[3]>>3); - key[4] = ((hash[3]&15)<<4)|(hash[4]>>4); - key[5] = ((hash[4]&31)<<3)|(hash[5]>>5); - key[6] = ((hash[5]&63)<<2)|(hash[6]>>6); - key[7] = ((hash[6]&127)<<1); + key[1] = ((hash[0] & 1) << 7) | (hash[1] >> 1); + key[2] = ((hash[1] & 3) << 6) | (hash[2] >> 2); + key[3] = ((hash[2] & 7) << 5) | (hash[3] >> 3); + key[4] = ((hash[3] & 15) << 4) | (hash[4] >> 4); + key[5] = ((hash[4] & 31) << 3) | (hash[5] >> 5); + key[6] = ((hash[5] & 63) << 2) | (hash[6] >> 6); + key[7] = ((hash[6] & 127) << 1); key_des_fixup(key, 8, 1); } static void -gen_md4_hash(const char *data, int data_len, char *result) +gen_md4_hash(const uint8_t *data, int data_len, uint8_t *result) { /* result is 16 byte md4 hash */ const md_kt_t *md4_kt = md_kt_get("MD4"); - char md[MD4_DIGEST_LENGTH]; + uint8_t md[MD4_DIGEST_LENGTH]; md_full(md4_kt, data, data_len, md); memcpy(result, md, MD4_DIGEST_LENGTH); } static void -gen_hmac_md5(const char *data, int data_len, const char *key, int key_len,char *result) +gen_hmac_md5(const uint8_t *data, int data_len, const uint8_t *key, int key_len, + uint8_t *result) { const md_kt_t *md5_kt = md_kt_get("MD5"); hmac_ctx_t *hmac_ctx = hmac_ctx_new(); hmac_ctx_init(hmac_ctx, key, key_len, md5_kt); - hmac_ctx_update(hmac_ctx, (const unsigned char *)data, data_len); - hmac_ctx_final(hmac_ctx, (unsigned char *)result); + hmac_ctx_update(hmac_ctx, data, data_len); + hmac_ctx_final(hmac_ctx, result); hmac_ctx_cleanup(hmac_ctx); hmac_ctx_free(hmac_ctx); } static void -gen_timestamp(unsigned char *timestamp) +gen_timestamp(uint8_t *timestamp) { /* Copies 8 bytes long timestamp into "timestamp" buffer. - * Timestamp is Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601. + * Timestamp is Little-endian, 64-bit signed value representing the + * number of tenths of a microsecond since January 1, 1601. */ UINTEGER64 timestamp_ull; @@ -129,8 +131,8 @@ gen_nonce(unsigned char *nonce) } } -void -my_strupr(unsigned char *str) +static void +my_strupr(char *str) { /* converts string to uppercase in place */ @@ -150,16 +152,17 @@ unicodize(char *dst, const char *src) { dst[i++] = *src; dst[i++] = 0; - } - while (*src++); + } while (*src++); return i; } static void -add_security_buffer(int sb_offset, void *data, int length, unsigned char *msg_buf, int *msg_bufpos) +add_security_buffer(int sb_offset, void *data, int length, + unsigned char *msg_buf, int *msg_bufpos) { - /* Adds security buffer data to a message and sets security buffer's offset and length */ + /* Adds security buffer data to a message and sets security buffer's + * offset and length */ msg_buf[sb_offset] = (unsigned char)length; msg_buf[sb_offset + 2] = msg_buf[sb_offset]; msg_buf[sb_offset + 4] = (unsigned char)(*msg_bufpos & 0xff); @@ -186,7 +189,8 @@ ntlm_phase_1(const struct http_proxy_info *p, struct gc_arena *gc) } const char * -ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_arena *gc) +ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, + struct gc_arena *gc) { /* NTLM handshake * @@ -195,19 +199,19 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are */ char pwbuf[sizeof(p->up.password) * 2]; /* for unicode password */ - unsigned char buf2[128]; /* decoded reply from proxy */ - unsigned char phase3[464]; + uint8_t buf2[128]; /* decoded reply from proxy */ + uint8_t phase3[464]; - char md4_hash[MD4_DIGEST_LENGTH+5]; - char challenge[8], ntlm_response[24]; + uint8_t md4_hash[MD4_DIGEST_LENGTH + 5]; + uint8_t challenge[8], ntlm_response[24]; int i, ret_val; - char ntlmv2_response[144]; + uint8_t ntlmv2_response[144]; char userdomain_u[256]; /* for uppercase unicode username and domain */ char userdomain[128]; /* the same as previous but ascii */ - char ntlmv2_hash[MD5_DIGEST_LENGTH]; - char ntlmv2_hmacmd5[16]; - char *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */ + uint8_t ntlmv2_hash[MD5_DIGEST_LENGTH]; + uint8_t ntlmv2_hmacmd5[16]; + uint8_t *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */ int ntlmv2_blob_size = 0; int phase3_bufpos = 0x40; /* offset to next security buffer data to be added */ size_t len; @@ -246,12 +250,13 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are /* fill 1st 16 bytes with md4 hash, disregard terminating null */ - gen_md4_hash(pwbuf, unicodize(pwbuf, p->up.password) - 2, md4_hash); + int unicode_len = unicodize(pwbuf, p->up.password) - 2; + gen_md4_hash((uint8_t *)pwbuf, unicode_len, md4_hash); /* pad to 21 bytes */ memset(md4_hash + MD4_DIGEST_LENGTH, 0, 5); - ret_val = openvpn_base64_decode( phase_2, (void *)buf2, -1); + ret_val = openvpn_base64_decode(phase_2, buf2, -1); if (ret_val < 0) { return NULL; @@ -271,7 +276,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are int tib_len; /* NTLMv2 hash */ - my_strupr((unsigned char *)strcpy(userdomain, username)); + strcpy(userdomain, username); + my_strupr(userdomain); if (strlen(username) + strlen(domain) < sizeof(userdomain)) { strcat(userdomain, domain); @@ -281,34 +287,54 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are msg(M_INFO, "Warning: Username or domain too long"); } unicodize(userdomain_u, userdomain); - gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, MD5_DIGEST_LENGTH, ntlmv2_hash); + gen_hmac_md5((uint8_t *)userdomain_u, 2 * strlen(userdomain), md4_hash, + MD5_DIGEST_LENGTH, ntlmv2_hash); /* NTLMv2 Blob */ memset(ntlmv2_blob, 0, 128); /* Clear blob buffer */ ntlmv2_blob[0x00] = 1; /* Signature */ ntlmv2_blob[0x01] = 1; /* Signature */ ntlmv2_blob[0x04] = 0; /* Reserved */ - gen_timestamp((unsigned char *)&ntlmv2_blob[0x08]); /* 64-bit Timestamp */ - gen_nonce((unsigned char *)&ntlmv2_blob[0x10]); /* 64-bit Client Nonce */ + gen_timestamp(&ntlmv2_blob[0x08]); /* 64-bit Timestamp */ + gen_nonce(&ntlmv2_blob[0x10]); /* 64-bit Client Nonce */ ntlmv2_blob[0x18] = 0; /* Unknown, zero should work */ /* Add target information block to the blob */ - if (( *((long *)&buf2[0x14]) & 0x00800000) == 0x00800000) /* Check for Target Information block */ + + /* Check for Target Information block */ + /* The NTLM spec instructs to interpret these 4 consecutive bytes as a + * 32bit long integer. However, no endianness is specified. + * The code here and that found in other NTLM implementations point + * towards the assumption that the byte order on the wire has to + * match the order on the sending and receiving hosts. Probably NTLM has + * been thought to be always running on x86_64/i386 machine thus + * implying Little-Endian everywhere. + * + * This said, in case of future changes, we should keep in mind that the + * byte order on the wire for the NTLM header is LE. + */ + const size_t hoff = 0x14; + unsigned long flags = buf2[hoff] | (buf2[hoff + 1] << 8) | + (buf2[hoff + 2] << 16) | (buf2[hoff + 3] << 24); + if ((flags & 0x00800000) == 0x00800000) { tib_len = buf2[0x28]; /* Get Target Information block size */ if (tib_len > 96) { tib_len = 96; } + { - char *tib_ptr; - int tib_pos = buf2[0x2c]; + uint8_t *tib_ptr; + uint8_t tib_pos = buf2[0x2c]; if (tib_pos + tib_len > sizeof(buf2)) { return NULL; } - tib_ptr = buf2 + tib_pos; /* Get Target Information block pointer */ - memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy Target Information block into the blob */ + /* Get Target Information block pointer */ + tib_ptr = buf2 + tib_pos; + /* Copy Target Information block into the blob */ + memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); } } else @@ -316,7 +342,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are tib_len = 0; } - ntlmv2_blob[0x1c + tib_len] = 0; /* Unknown, zero works */ + /* Unknown, zero works */ + ntlmv2_blob[0x1c + tib_len] = 0; /* Get blob length */ ntlmv2_blob_size = 0x20 + tib_len; @@ -325,24 +352,28 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are memcpy(&ntlmv2_response[8], challenge, 8); /* hmac-md5 */ - gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, MD5_DIGEST_LENGTH, ntlmv2_hmacmd5); - - /* Add hmac-md5 result to the blob */ - memcpy(ntlmv2_response, ntlmv2_hmacmd5, MD5_DIGEST_LENGTH); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */ + gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, + MD5_DIGEST_LENGTH, ntlmv2_hmacmd5); + /* Add hmac-md5 result to the blob. + * Note: This overwrites challenge previously written at + * ntlmv2_response[8..15] */ + memcpy(ntlmv2_response, ntlmv2_hmacmd5, MD5_DIGEST_LENGTH); } - else /* Generate NTLM response */ + else /* Generate NTLM response */ { - unsigned char key1[DES_KEY_LENGTH], key2[DES_KEY_LENGTH], key3[DES_KEY_LENGTH]; + unsigned char key1[DES_KEY_LENGTH], key2[DES_KEY_LENGTH]; + unsigned char key3[DES_KEY_LENGTH]; - create_des_keys((unsigned char *)md4_hash, key1); + create_des_keys(md4_hash, key1); cipher_des_encrypt_ecb(key1, challenge, ntlm_response); - create_des_keys((unsigned char *)&(md4_hash[DES_KEY_LENGTH-1]), key2); + create_des_keys(&md4_hash[DES_KEY_LENGTH - 1], key2); cipher_des_encrypt_ecb(key2, challenge, &ntlm_response[DES_KEY_LENGTH]); - create_des_keys((unsigned char *)&(md4_hash[2*(DES_KEY_LENGTH-1)]), key3); - cipher_des_encrypt_ecb(key3, challenge, &ntlm_response[DES_KEY_LENGTH*2]); + create_des_keys(&md4_hash[2 * (DES_KEY_LENGTH - 1)], key3); + cipher_des_encrypt_ecb(key3, challenge, + &ntlm_response[DES_KEY_LENGTH * 2]); } @@ -353,7 +384,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are if (ntlmv2_enabled) /* NTLMv2 response */ { - add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, phase3, &phase3_bufpos); + add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, + phase3, &phase3_bufpos); } else /* NTLM response */ { @@ -361,12 +393,13 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are } /* username in ascii */ - add_security_buffer(0x24, username, strlen(username), phase3, &phase3_bufpos); + add_security_buffer(0x24, username, strlen(username), phase3, + &phase3_bufpos); - /* Set domain. If <domain> is empty, default domain will be used (i.e. proxy's domain) */ + /* Set domain. If <domain> is empty, default domain will be used + * (i.e. proxy's domain) */ add_security_buffer(0x1c, domain, strlen(domain), phase3, &phase3_bufpos); - /* other security buffers will be empty */ phase3[0x10] = phase3_bufpos; /* lm not used */ phase3[0x30] = phase3_bufpos; /* no workstation name supplied */ @@ -376,7 +409,8 @@ ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2, struct gc_are phase3[0x3c] = 0x02; /* negotiate oem */ phase3[0x3d] = 0x02; /* negotiate ntlm */ - return ((const char *)make_base64_string2((unsigned char *)phase3, phase3_bufpos, gc)); + return ((const char *)make_base64_string2((unsigned char *)phase3, + phase3_bufpos, gc)); } #else /* if NTLM */ diff --git a/src/openvpn/occ-inline.h b/src/openvpn/occ-inline.h index 68e9098..0fa8e5b 100644 --- a/src/openvpn/occ-inline.h +++ b/src/openvpn/occ-inline.h @@ -31,7 +31,7 @@ */ static inline int -occ_reset_op() +occ_reset_op(void) { return -1; } diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index c765f0b..70b19ae 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -88,38 +88,19 @@ EVP_MD_CTX_new(void) } #endif -#if !defined(HAVE_EVP_CIPHER_CTX_FREE) -/** - * Free an existing cipher context - * - * @param ctx The cipher context - */ -static inline void -EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c) -{ - free(c); -} -#endif - -#if !defined(HAVE_EVP_CIPHER_CTX_NEW) -/** - * Allocate a new cipher context object - * - * @return A zero'ed cipher context object - */ -static inline EVP_CIPHER_CTX * -EVP_CIPHER_CTX_new(void) -{ - EVP_CIPHER_CTX *ctx = NULL; - ALLOC_OBJ_CLEAR(ctx, EVP_CIPHER_CTX); - return ctx; -} -#endif - #if !defined(HAVE_HMAC_CTX_RESET) /** * Reset a HMAC context * + * OpenSSL 1.1+ removes APIs HMAC_CTX_init() and HMAC_CTX_cleanup() + * and replace them with a single call that does a cleanup followed + * by an init. A proper _reset() for OpenSSL < 1.1 should perform + * a similar set of operations. + * + * It means that before we kill a HMAC context, we'll have to cleanup + * again, as we probably have allocated a few resources when we forced + * an init. + * * @param ctx The HMAC context * @return 1 on success, 0 on error */ @@ -127,42 +108,22 @@ static inline int HMAC_CTX_reset(HMAC_CTX *ctx) { HMAC_CTX_cleanup(ctx); + HMAC_CTX_init(ctx); return 1; } #endif -#if !defined(HAVE_HMAC_CTX_INIT) -/** - * Init a HMAC context - * - * @param ctx The HMAC context - * - * Contrary to many functions in this file, HMAC_CTX_init() is not - * an OpenSSL 1.1 function: it comes from previous versions and was - * removed in v1.1. As a consequence, there is no distincting in - * v1.1 between a cleanup, and init and a reset. Yet, previous OpenSSL - * version need this distinction. - * - * In order to respect previous OpenSSL versions, we implement init - * as reset for OpenSSL 1.1+. - */ -static inline void -HMAC_CTX_init(HMAC_CTX *ctx) -{ - HMAC_CTX_reset(ctx); -} -#endif - #if !defined(HAVE_HMAC_CTX_FREE) /** - * Free an existing HMAC context + * Cleanup and free an existing HMAC context * * @param ctx The HMAC context */ static inline void -HMAC_CTX_free(HMAC_CTX *c) +HMAC_CTX_free(HMAC_CTX *ctx) { - free(c); + HMAC_CTX_cleanup(ctx); + free(ctx); } #endif @@ -283,6 +244,20 @@ EVP_PKEY_get0_RSA(EVP_PKEY *pkey) } #endif +#if !defined(HAVE_EVP_PKEY_GET0_EC_KEY) && !defined(OPENSSL_NO_EC) +/** + * Get the EC_KEY object of a public key + * + * @param pkey Public key object + * @return The underlying EC_KEY object + */ +static inline EC_KEY * +EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) +{ + return pkey ? pkey->pkey.ec : NULL; +} +#endif + #if !defined(HAVE_EVP_PKEY_ID) /** * Get the PKEY type @@ -649,6 +624,24 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) } #endif +#if !defined(HAVE_EC_GROUP_ORDER_BITS) && !defined(OPENSSL_NO_EC) +/** + * Gets the number of bits of the order of an EC_GROUP + * + * @param group EC_GROUP object + * @return number of bits of group order. + */ +static inline int +EC_GROUP_order_bits(const EC_GROUP *group) +{ + BIGNUM* order = BN_new(); + EC_GROUP_get_order(group, order, NULL); + int bits = BN_num_bits(order); + BN_free(order); + return bits; +} +#endif + /* SSLeay symbols have been renamed in OpenSSL 1.1 */ #if !defined(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT) #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c index 08c09e6..e237ee5 100644 --- a/src/openvpn/openvpn.c +++ b/src/openvpn/openvpn.c @@ -33,6 +33,7 @@ #include "forward.h" #include "multi.h" #include "win32.h" +#include "platform.h" #include "memdbg.h" @@ -47,6 +48,27 @@ process_signal_p2p(struct context *c) return process_signal(c); } +/* Write our PID to a file */ +static void +write_pid(const char *filename) +{ + if (filename) + { + unsigned int pid = 0; + FILE *fp = platform_fopen(filename, "w"); + if (!fp) + { + msg(M_ERR, "Open error on pid file %s", filename); + } + + pid = platform_getpid(); + fprintf(fp, "%u\n", pid); + if (fclose(fp)) + { + msg(M_ERR, "Close error on pid file %s", filename); + } + } +} /**************************************************************************/ diff --git a/src/openvpn/options.c b/src/openvpn/options.c index fef5e90..8dee5d1 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -415,8 +415,9 @@ static const char usage_message[] = " client instance.\n" "--ifconfig-pool start-IP end-IP [netmask] : Set aside a pool of subnets\n" " to be dynamically allocated to connecting clients.\n" - "--ifconfig-pool-linear : Use individual addresses rather than /30 subnets\n" - " in tun mode. Not compatible with Windows clients.\n" + "--ifconfig-pool-linear : (DEPRECATED) Use individual addresses rather \n" + " than /30 subnets\n in tun mode. Not compatible with\n" + " Windows clients.\n" "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n" " data to file, at seconds intervals (default=600).\n" " If seconds=0, file will be treated as read-only.\n" @@ -434,7 +435,7 @@ static const char usage_message[] = " Only valid in a client-specific config file.\n" "--disable : Client is disabled.\n" " Only valid in a client-specific config file.\n" - "--client-cert-not-required : Don't require client certificate, client\n" + "--client-cert-not-required : (DEPRECATED) Don't require client certificate, client\n" " will authenticate using username/password.\n" "--verify-client-cert [none|optional|require] : perform no, optional or\n" " mandatory client certificate verification.\n" @@ -455,7 +456,7 @@ static const char usage_message[] = " with those of the server will be disconnected.\n" "--auth-user-pass-optional : Allow connections by clients that don't\n" " specify a username/password.\n" - "--no-name-remapping : Allow Common Name and X509 Subject to include\n" + "--no-name-remapping : (DEPRECATED) Allow Common Name and X509 Subject to include\n" " any printable character.\n" "--client-to-client : Internally route client-to-client traffic.\n" "--duplicate-cn : Allow multiple clients with the same common name to\n" @@ -539,13 +540,13 @@ static const char usage_message[] = "--prng alg [nsl] : For PRNG, use digest algorithm alg, and\n" " nonce_secret_len=nsl. Set alg=none to disable PRNG.\n" #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH - "--keysize n : Size of cipher key in bits (optional).\n" + "--keysize n : (DEPRECATED) Size of cipher key in bits (optional).\n" " If unspecified, defaults to cipher-specific default.\n" #endif #ifndef ENABLE_CRYPTO_MBEDTLS "--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n" #endif - "--no-replay : Disable replay protection.\n" + "--no-replay : (DEPRECATED) Disable replay protection.\n" "--mute-replay-warnings : Silence the output of replay warnings to log file.\n" "--replay-window n [t] : Use a replay protection sliding window of size n\n" " and a time window of t seconds.\n" @@ -564,7 +565,7 @@ static const char usage_message[] = "(These options are meaningful only for TLS-mode)\n" "--tls-server : Enable TLS and assume server role during TLS handshake.\n" "--tls-client : Enable TLS and assume client role during TLS handshake.\n" - "--key-method m : Data channel key exchange method. m should be a method\n" + "--key-method m : (DEPRECATED) Data channel key exchange method. m should be a method\n" " number, such as 1 (default), 2, etc.\n" "--ca file : Certificate authority file in .pem format containing\n" " root certificate.\n" @@ -961,7 +962,7 @@ pull_filter_type_name(int type) #endif -void +static void setenv_connection_entry(struct env_set *es, const struct connection_entry *e, const int i) @@ -1441,7 +1442,7 @@ rol_check_alloc(struct options *options) } } -void +static void rol6_check_alloc(struct options *options) { if (!options->routes_ipv6) @@ -1872,7 +1873,7 @@ parse_http_proxy_override(const char *server, } } -void +static void options_postprocess_http_proxy_override(struct options *o) { const struct connection_list *l = o->connection_list; @@ -1989,7 +1990,7 @@ alloc_pull_filter(struct options *o, const int msglevel) return f; } -void +static void connection_entry_load_re(struct connection_entry *ce, const struct remote_entry *re) { if (re->remote) @@ -2495,6 +2496,16 @@ options_postprocess_verify_ce(const struct options *options, const struct connec msg(M_WARN, "WARNING: --no-iv is deprecated and will be removed in 2.5"); } + if (options->keysize) + { + msg(M_WARN, "WARNING: --keysize is DEPRECATED and will be removed in OpenVPN 2.6"); + } + + if (!options->replay) + { + msg(M_WARN, "WARNING: --no-replay is DEPRECATED and will be removed in OpenVPN 2.5"); + } + /* * Check consistency of replay options */ @@ -3016,6 +3027,13 @@ options_postprocess_mutate(struct options *o) o->dh_file = NULL; } } + else if (o->dh_file) + { + /* DH file is only meaningful in a tls-server context. */ + msg(M_WARN, "WARNING: Ignoring option 'dh' in tls-client mode, please only " + "include this in your server configuration"); + o->dh_file = NULL; + } /* cipher negotiation (NCP) currently assumes --pull or --mode server */ if (o->ncp_enabled @@ -3148,8 +3166,7 @@ check_file_access(const int type, const char *file, const int mode, const char * /* Scream if an error is found */ if (errcode > 0) { - msg(M_NOPREFIX|M_OPTERR, "%s fails with '%s': %s", - opt, file, strerror(errno)); + msg(M_NOPREFIX | M_OPTERR | M_ERRNO, "%s fails with '%s'", opt, file); } /* Return true if an error occured */ @@ -6198,7 +6215,7 @@ add_option(struct options *options, else if (streq(p[0], "max-routes") && !p[2]) { msg(M_WARN, "DEPRECATED OPTION: --max-routes option ignored." - "The number of routes is unlimited as of version 2.4. " + "The number of routes is unlimited as of OpenVPN 2.4. " "This option will be removed in a future version, " "please remove it from your configuration."); } @@ -6582,6 +6599,7 @@ add_option(struct options *options, { VERIFY_PERMISSION(OPT_P_GENERAL); options->topology = TOP_P2P; + msg(M_WARN, "DEPRECATED OPTION: --ifconfig-pool-linear, use --topology p2p instead"); } else if (streq(p[0], "ifconfig-ipv6-pool") && p[1] && !p[2]) { @@ -7028,7 +7046,7 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); if (streq(p[1], "env")) { - msg(M_INFO, "NOTE: --win-sys env is default from OpenVPN v2.3. " + msg(M_INFO, "NOTE: --win-sys env is default from OpenVPN 2.3. " "This entry will now be ignored. " "Please remove this entry from your configuration file."); } @@ -7874,7 +7892,7 @@ add_option(struct options *options, msg(msglevel, "you cannot use --compat-names with --verify-x509-name"); goto err; } - msg(M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration. This will be removed in OpenVPN v2.5."); + msg(M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration. This will be removed in OpenVPN 2.5."); compat_flag(COMPAT_FLAG_SET | COMPAT_NAMES); #if P2MP_SERVER if (p[1] && streq(p[1], "no-remapping")) @@ -7890,7 +7908,7 @@ add_option(struct options *options, msg(msglevel, "you cannot use --no-name-remapping with --verify-x509-name"); goto err; } - msg(M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration. This will be removed in OpenVPN v2.5."); + msg(M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration. This will be removed in OpenVPN 2.5."); compat_flag(COMPAT_FLAG_SET | COMPAT_NAMES); compat_flag(COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING); #endif diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 67b9b94..01a7b26 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -181,7 +181,7 @@ struct options /* enable forward compatibility for post-2.1 features */ bool forward_compatible; - /* list of options that should be ignored even if unkown */ + /* list of options that should be ignored even if unknown */ const char **ignore_unknown_option; /* persist parms */ diff --git a/src/openvpn/packet_id.c b/src/openvpn/packet_id.c index 30ae8fb..a3ff572 100644 --- a/src/openvpn/packet_id.c +++ b/src/openvpn/packet_id.c @@ -643,7 +643,7 @@ packet_id_debug_print(int msglevel, #ifdef PID_TEST void -packet_id_interactive_test() +packet_id_interactive_test(void) { struct packet_id pid; struct packet_id_net pin; diff --git a/src/openvpn/packet_id.h b/src/openvpn/packet_id.h index a370936..8509e59 100644 --- a/src/openvpn/packet_id.h +++ b/src/openvpn/packet_id.h @@ -299,7 +299,7 @@ packet_id_persist_save_obj(struct packet_id_persist *p, const struct packet_id * const char *packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc); #ifdef PID_TEST -void packet_id_interactive_test(); +void packet_id_interactive_test(void); #endif diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c index 6041828..a0d0906 100644 --- a/src/openvpn/pkcs11.c +++ b/src/openvpn/pkcs11.c @@ -356,7 +356,7 @@ cleanup: } void -pkcs11_terminate() +pkcs11_terminate(void) { dmsg( D_PKCS11_DEBUG, @@ -422,13 +422,13 @@ pkcs11_addProvider( } int -pkcs11_logout() +pkcs11_logout(void) { return pkcs11h_logout() == CKR_OK; } int -pkcs11_management_id_count() +pkcs11_management_id_count(void) { pkcs11h_certificate_id_list_t id_list = NULL; pkcs11h_certificate_id_list_t t = NULL; diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c index 2495523..e942ba9 100644 --- a/src/openvpn/platform.c +++ b/src/openvpn/platform.c @@ -159,7 +159,7 @@ platform_nice(int niceval) errno = 0; if (nice(niceval) < 0 && errno != 0) { - msg(M_WARN | M_ERRNO, "WARNING: nice %d failed: %s", niceval, strerror(errno)); + msg(M_WARN | M_ERRNO, "WARNING: nice %d failed", niceval); } else { @@ -173,7 +173,7 @@ platform_nice(int niceval) /* Get current PID */ unsigned int -platform_getpid() +platform_getpid(void) { #ifdef _WIN32 return (unsigned int) GetCurrentProcessId(); diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index 7a737ea..2e81503 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -550,7 +550,7 @@ http_proxy_close(struct http_proxy_info *hp) free(hp); } -bool +static bool add_proxy_headers(struct http_proxy_info *p, socket_descriptor_t sd, /* already open to proxy */ const char *host, /* openvpn server remote */ diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c index c2b05cd..5136a20 100644 --- a/src/openvpn/ps.c +++ b/src/openvpn/ps.c @@ -172,7 +172,7 @@ send_control(const socket_descriptor_t fd, int code) } static int -cmsg_size() +cmsg_size(void) { return CMSG_SPACE(sizeof(socket_descriptor_t)); } @@ -922,7 +922,7 @@ port_share_open(const char *host, openvpn_close_socket(fd[1]); exit(0); - return 0; /* NOTREACHED */ + return NULL; /* NOTREACHED */ } error: diff --git a/src/openvpn/route.c b/src/openvpn/route.c index a1811f4..8c71e6e 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -518,14 +518,14 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, l->routes_ipv6 = ro; } -void +static void clear_route_list(struct route_list *rl) { gc_free(&rl->gc); CLEAR(*rl); } -void +static void clear_route_ipv6_list(struct route_ipv6_list *rl6) { gc_free(&rl6->gc); @@ -1530,7 +1530,9 @@ add_route(struct route_ipv4 *r, struct gc_arena gc; struct argv argv = argv_new(); const char *network; +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) const char *netmask; +#endif const char *gateway; bool status = false; int is_local_route; @@ -1543,7 +1545,9 @@ add_route(struct route_ipv4 *r, gc_init(&gc); network = print_in_addr_t(r->network, 0, &gc); +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) netmask = print_in_addr_t(r->netmask, 0, &gc); +#endif gateway = print_in_addr_t(r->gateway, 0, &gc); is_local_route = local_route(r->network, r->netmask, r->gateway, rgi); @@ -2132,8 +2136,12 @@ delete_route(struct route_ipv4 *r, struct gc_arena gc; struct argv argv = argv_new(); const char *network; +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) const char *netmask; +#endif +#if !defined(TARGET_LINUX) && !defined(TARGET_ANDROID) const char *gateway; +#endif int is_local_route; if ((r->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED)) @@ -2144,8 +2152,12 @@ delete_route(struct route_ipv4 *r, gc_init(&gc); network = print_in_addr_t(r->network, 0, &gc); +#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX) netmask = print_in_addr_t(r->netmask, 0, &gc); +#endif +#if !defined(TARGET_LINUX) && !defined(TARGET_ANDROID) gateway = print_in_addr_t(r->gateway, 0, &gc); +#endif is_local_route = local_route(r->network, r->netmask, r->gateway, rgi); if (is_local_route == LR_ERROR) @@ -3441,7 +3453,14 @@ get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, if (nh->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *ne = (struct nlmsgerr *)NLMSG_DATA(nh); - msg(M_WARN, "GDG6: NLSMG_ERROR: error %d\n", ne->error); + + /* since linux-4.11 -ENETUNREACH is returned when no route can be + * found. Don't print any error message in this case */ + if (ne->error != -ENETUNREACH) + { + msg(M_WARN, "GDG6: NLMSG_ERROR: error %s\n", + strerror(-ne->error)); + } break; } diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 4e7e3f9..0fc91f2 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -496,7 +496,7 @@ openvpn_getaddrinfo(unsigned int flags, goto done; } - openvpn_sleep(fail_wait_interval); + management_sleep(fail_wait_interval); } ASSERT(res); @@ -1193,7 +1193,7 @@ socket_listen_accept(socket_descriptor_t sd, if (status <= 0) { - openvpn_sleep(1); + management_sleep(1); continue; } @@ -1228,7 +1228,7 @@ socket_listen_accept(socket_descriptor_t sd, break; } } - openvpn_sleep(1); + management_sleep(1); } if (!nowait && openvpn_close_socket(sd)) @@ -1297,11 +1297,9 @@ socket_bind(socket_descriptor_t sd, } if (bind(sd, cur->ai_addr, cur->ai_addrlen)) { - const int errnum = openvpn_errno(); - msg(M_FATAL, "%s: Socket bind failed on local address %s: %s", + msg(M_FATAL | M_ERRNO, "%s: Socket bind failed on local address %s", prefix, - print_sockaddr_ex(local->ai_addr, ":", PS_SHOW_PORT, &gc), - strerror_ts(errnum, &gc)); + print_sockaddr_ex(local->ai_addr, ":", PS_SHOW_PORT, &gc)); } gc_free(&gc); } @@ -1376,7 +1374,7 @@ openvpn_connect(socket_descriptor_t sd, #endif break; } - openvpn_sleep(1); + management_sleep(1); continue; } @@ -1433,7 +1431,7 @@ set_actual_address(struct link_socket_actual *actual, struct addrinfo *ai) } -void +static void socket_connect(socket_descriptor_t *sd, const struct sockaddr *dest, const int connect_timeout, @@ -1475,10 +1473,8 @@ socket_connect(socket_descriptor_t *sd, if (status) { - msg(D_LINK_ERRORS, - "TCP: connect to %s failed: %s", - print_sockaddr(dest, &gc), - strerror_ts(status, &gc)); + msg(D_LINK_ERRORS, "TCP: connect to %s failed: %s", + print_sockaddr(dest, &gc), strerror(status)); openvpn_close_socket(*sd); *sd = SOCKET_UNDEFINED; @@ -1790,6 +1786,8 @@ link_socket_init_phase1(struct link_socket *sock, ASSERT(sock->info.proto == PROTO_TCP_SERVER); ASSERT(!sock->inetd); sock->sd = accept_from->sd; + /* inherit (possibly guessed) info AF from parent context */ + sock->info.af = accept_from->info.af; } /* are we running in HTTP proxy mode? */ @@ -3888,12 +3886,11 @@ socket_bind_unix(socket_descriptor_t sd, if (bind(sd, (struct sockaddr *) local, sizeof(struct sockaddr_un))) { - const int errnum = openvpn_errno(); - msg(M_FATAL, "%s: Socket bind[%d] failed on unix domain socket %s: %s", + msg(M_FATAL | M_ERRNO, + "%s: Socket bind[%d] failed on unix domain socket %s", prefix, (int)sd, - sockaddr_unix_name(local, "NULL"), - strerror_ts(errnum, &gc)); + sockaddr_unix_name(local, "NULL")); } #ifdef HAVE_UMASK diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 15cd94a..0739cf7 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -347,7 +347,7 @@ tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame } void -init_ssl_lib() +init_ssl_lib(void) { tls_init_lib(); @@ -355,7 +355,7 @@ init_ssl_lib() } void -free_ssl_lib() +free_ssl_lib(void) { crypto_uninit_lib(); prng_uninit(); @@ -616,6 +616,11 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_client_new(new_ctx); } + /* Allowable ciphers */ + /* Since @SECLEVEL also influces loading of certificates, set the + * cipher restrictions before loading certificates */ + tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); + tls_ctx_set_options(new_ctx, options->ssl_flags); if (options->pkcs12_file) @@ -708,9 +713,6 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_load_ecdh_params(new_ctx, options->ecdh_curve); } - /* Allowable ciphers */ - tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); - #ifdef ENABLE_CRYPTO_MBEDTLS /* Personalise the random by mixing in the certificate */ tls_ctx_personalise_random(new_ctx); @@ -1532,7 +1534,7 @@ read_control_auth(struct buffer *buf, } else if (ctx->mode == TLS_WRAP_CRYPT) { - struct buffer tmp = alloc_buf(buf_forward_capacity_total(buf)); + struct buffer tmp = alloc_buf_gc(buf_forward_capacity_total(buf), &gc); if (!tls_crypt_unwrap(buf, &tmp, &ctx->opt)) { msg(D_TLS_ERRORS, "TLS Error: tls-crypt unwrapping failed from %s", @@ -1541,7 +1543,7 @@ read_control_auth(struct buffer *buf, } ASSERT(buf_init(buf, buf->offset)); ASSERT(buf_copy(buf, &tmp)); - free_buf(&tmp); + buf_clear(&tmp); } if (ctx->mode == TLS_WRAP_NONE || ctx->mode == TLS_WRAP_AUTH) @@ -1605,7 +1607,7 @@ key_source2_print(const struct key_source2 *k) * @param out Output buffer * @param olen Length of the output buffer */ -void +static void tls1_P_hash(const md_kt_t *md_kt, const uint8_t *sec, int sec_len, @@ -1838,20 +1840,8 @@ generate_key_expansion(struct key_ctx_bi *key, } /* Initialize OpenSSL key contexts */ - - ASSERT(server == true || server == false); - - init_key_ctx(&key->encrypt, - &key2.keys[(int)server], - key_type, - OPENVPN_OP_ENCRYPT, - "Data Channel Encrypt"); - - init_key_ctx(&key->decrypt, - &key2.keys[1-(int)server], - key_type, - OPENVPN_OP_DECRYPT, - "Data Channel Decrypt"); + int key_direction = server ? KEY_DIRECTION_INVERSE : KEY_DIRECTION_NORMAL; + init_key_ctx_bi(key, &key2, key_direction, key_type, "Data Channel"); /* Initialize implicit IVs */ key_ctx_update_implicit_iv(&key->encrypt, key2.keys[(int)server].hmac, @@ -1859,7 +1849,6 @@ generate_key_expansion(struct key_ctx_bi *key, key_ctx_update_implicit_iv(&key->decrypt, key2.keys[1-(int)server].hmac, MAX_HMAC_KEY_LENGTH); - key->initialized = true; ret = true; exit: @@ -1958,7 +1947,7 @@ cleanup: bool tls_session_update_crypto_params(struct tls_session *session, - const struct options *options, struct frame *frame) + struct options *options, struct frame *frame) { if (!session->opt->server && 0 != strcmp(options->ciphername, session->opt->config_ciphername) @@ -1967,6 +1956,8 @@ tls_session_update_crypto_params(struct tls_session *session, msg(D_TLS_ERRORS, "Error: pushed cipher not allowed - %s not in %s or %s", options->ciphername, session->opt->config_ciphername, options->ncp_ciphers); + /* undo cipher push, abort connection setup */ + options->ciphername = session->opt->config_ciphername; return false; } @@ -1974,6 +1965,11 @@ tls_session_update_crypto_params(struct tls_session *session, { msg(D_HANDSHAKE, "Data Channel: using negotiated cipher '%s'", options->ciphername); + if (options->keysize) + { + msg(D_HANDSHAKE, "NCP: overriding user-set keysize with default"); + options->keysize = 0; + } } init_key_type(&session->opt->key_type, options->ciphername, @@ -2186,16 +2182,6 @@ read_string_alloc(struct buffer *buf) return str; } -void -read_string_discard(struct buffer *buf) -{ - char *data = read_string_alloc(buf); - if (data) - { - free(data); - } -} - /* * Handle the reading and writing of key data to and from * the TLS control channel (cleartext). diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 56ea601..0e0f68f 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -481,7 +481,7 @@ void tls_update_remote_addr(struct tls_multi *multi, * @return true if updating succeeded, false otherwise. */ bool tls_session_update_crypto_params(struct tls_session *session, - const struct options *options, struct frame *frame); + struct options *options, struct frame *frame); /** * "Poor man's NCP": Use peer cipher if it is an allowed (NCP) cipher. diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index a738f0f..aba5a4d 100644 --- a/src/openvpn/ssl_backend.h +++ b/src/openvpn/ssl_backend.h @@ -88,17 +88,17 @@ int pem_password_callback(char *buf, int size, int rwflag, void *u); * Perform any static initialisation necessary by the library. * Called on OpenVPN initialisation */ -void tls_init_lib(); +void tls_init_lib(void); /** * Free any global SSL library-specific data structures. */ -void tls_free_lib(); +void tls_free_lib(void); /** * Clear the underlying SSL library's error state. */ -void tls_clear_error(); +void tls_clear_error(void); /** * Parse a TLS version specifier diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index ef583e6..861d936 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -63,17 +63,17 @@ #include <mbedtls/sha256.h> void -tls_init_lib() +tls_init_lib(void) { } void -tls_free_lib() +tls_free_lib(void) { } void -tls_clear_error() +tls_clear_error(void) { } diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index e589dcd..b266309 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -69,7 +69,7 @@ int mydata_index; /* GLOBAL */ void -tls_init_lib() +tls_init_lib(void) { SSL_library_init(); #ifndef ENABLE_SMALL @@ -82,7 +82,7 @@ tls_init_lib() } void -tls_free_lib() +tls_free_lib(void) { EVP_cleanup(); #ifndef ENABLE_SMALL @@ -91,7 +91,7 @@ tls_free_lib() } void -tls_clear_error() +tls_clear_error(void) { ERR_clear_error(); } @@ -253,6 +253,9 @@ tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) sslopt |= SSL_OP_NO_TLSv1_2; } #endif +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + sslopt |= SSL_OP_CIPHER_SERVER_PREFERENCE; +#endif #ifdef SSL_OP_NO_COMPRESSION /* Disable compression - flag not available in OpenSSL 0.9.8 */ sslopt |= SSL_OP_NO_COMPRESSION; @@ -487,15 +490,7 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name /* Generate a new ECDH key for each SSL session (for non-ephemeral ECDH) */ SSL_CTX_set_options(ctx->ctx, SSL_OP_SINGLE_ECDH_USE); -#if OPENSSL_VERSION_NUMBER >= 0x10002000L - /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter loading */ - if (NULL == curve_name) - { - SSL_CTX_set_ecdh_auto(ctx->ctx, 1); - return; - } -#endif - /* For older OpenSSL, we'll have to do the parameter loading on our own */ + if (curve_name != NULL) { /* Use user supplied curve if given */ @@ -504,14 +499,17 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name } else { - /* Extract curve from key */ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter + * loading */ + SSL_CTX_set_ecdh_auto(ctx->ctx, 1); + return; +#else + /* For older OpenSSL we have to extract the curve from key on our own */ EC_KEY *eckey = NULL; const EC_GROUP *ecgrp = NULL; EVP_PKEY *pkey = NULL; -#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) - pkey = SSL_CTX_get0_privatekey(ctx->ctx); -#else /* Little hack to get private key ref from SSL_CTX, yay OpenSSL... */ SSL *ssl = SSL_new(ctx->ctx); if (!ssl) @@ -520,7 +518,6 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name } pkey = SSL_get_privatekey(ssl); SSL_free(ssl); -#endif msg(D_TLS_DEBUG, "Extracting ECDH curve from private key"); @@ -529,6 +526,7 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name { nid = EC_GROUP_get_curve_name(ecgrp); } +#endif } /* Translate NID back to name , just for kicks */ @@ -713,7 +711,7 @@ tls_ctx_add_extra_certs(struct tls_root_ctx *ctx, BIO *bio) for (;; ) { cert = NULL; - if (!PEM_read_bio_X509(bio, &cert, 0, NULL)) /* takes ownership of cert */ + if (!PEM_read_bio_X509(bio, &cert, NULL, NULL)) /* takes ownership of cert */ { break; } @@ -811,12 +809,6 @@ tls_ctx_load_cert_file(struct tls_root_ctx *ctx, const char *cert_file, tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, NULL); } -void -tls_ctx_free_cert_file(X509 *x509) -{ - X509_free(x509); -} - int tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, const char *priv_key_file_inline @@ -1080,6 +1072,13 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ pub_rsa = EVP_PKEY_get0_RSA(pkey); + /* Certificate might not be RSA but DSA or EC */ + if (!pub_rsa) + { + crypto_msg(M_WARN, "management-external-key requires a RSA certificate"); + goto err; + } + /* initialize RSA object */ const BIGNUM *n = NULL; const BIGNUM *e = NULL; @@ -1330,7 +1329,7 @@ static time_t biofp_last_open; /* GLOBAL */ static const int biofp_reopen_interval = 600; /* GLOBAL */ static void -close_biofp() +close_biofp(void) { if (biofp) { @@ -1340,7 +1339,7 @@ close_biofp() } static void -open_biofp() +open_biofp(void) { const time_t current = time(NULL); const pid_t pid = getpid(); @@ -1686,18 +1685,36 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) EVP_PKEY *pkey = X509_get_pubkey(cert); if (pkey != NULL) { - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL) + if ((EVP_PKEY_id(pkey) == EVP_PKEY_RSA) && (EVP_PKEY_get0_RSA(pkey) != NULL)) { RSA *rsa = EVP_PKEY_get0_RSA(pkey); openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", RSA_bits(rsa)); } - else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL) + else if ((EVP_PKEY_id(pkey) == EVP_PKEY_DSA) && (EVP_PKEY_get0_DSA(pkey) != NULL)) { DSA *dsa = EVP_PKEY_get0_DSA(pkey); openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", DSA_bits(dsa)); } +#ifndef OPENSSL_NO_EC + else if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC) && (EVP_PKEY_get0_EC_KEY(pkey) != NULL)) + { + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + const EC_GROUP *group = EC_KEY_get0_group(ec); + const char* curve; + + int nid = EC_GROUP_get_curve_name(group); + if (nid == 0 || (curve = OBJ_nid2sn(nid)) == NULL) + { + curve = "Error getting curve name"; + } + + openvpn_snprintf(s2, sizeof(s2), ", %d bit EC, curve: %s", + EC_GROUP_order_bits(group), curve); + + } +#endif EVP_PKEY_free(pkey); } X509_free(cert); @@ -1758,7 +1775,7 @@ show_available_tls_ciphers(const char *cipher_list) * in the OpenSSL library. */ void -show_available_curves() +show_available_curves(void) { #ifndef OPENSSL_NO_EC EC_builtin_curve *curves = NULL; diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index 468b495..95b08e0 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -129,8 +129,7 @@ extract_x509_extension(X509 *cert, char *fieldname, char *out, int size) if (!x509_username_field_ext_supported(fieldname)) { msg(D_TLS_ERRORS, - "ERROR: --x509-alt-username field 'ext:%s' not supported", - fieldname); + "ERROR: --x509-username-field 'ext:%s' not supported", fieldname); return false; } @@ -203,8 +202,8 @@ extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out, { int lastpos = -1; int tmp = -1; - X509_NAME_ENTRY *x509ne = 0; - ASN1_STRING *asn1 = 0; + X509_NAME_ENTRY *x509ne = NULL; + ASN1_STRING *asn1 = NULL; unsigned char *buf = NULL; ASN1_OBJECT *field_name_obj = OBJ_txt2obj(field_name, 0); diff --git a/src/openvpn/status.c b/src/openvpn/status.c index a163408..d2f0b13 100644 --- a/src/openvpn/status.c +++ b/src/openvpn/status.c @@ -178,7 +178,7 @@ status_flush(struct status_output *so) const off_t off = lseek(so->fd, (off_t)0, SEEK_CUR); if (ftruncate(so->fd, off) != 0) { - msg(M_WARN, "Failed to truncate status file: %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "Failed to truncate status file"); } } #elif defined(HAVE_CHSIZE) diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h index 2973b5a..d9f5a34 100644 --- a/src/openvpn/syshead.h +++ b/src/openvpn/syshead.h @@ -513,7 +513,7 @@ socket_defined(const socket_descriptor_t sd) * Do we have point-to-multipoint capability? */ -#if defined(ENABLE_CLIENT_SERVER) && defined(ENABLE_CRYPTO) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS) +#if defined(ENABLE_CRYPTO) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS) #define P2MP 1 #else #define P2MP 0 diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c index e13bb4e..403060d 100644 --- a/src/openvpn/tls_crypt.c +++ b/src/openvpn/tls_crypt.c @@ -35,35 +35,47 @@ #include "tls_crypt.h" -int -tls_crypt_buf_overhead(void) -{ - return packet_id_size(true) + TLS_CRYPT_TAG_SIZE + TLS_CRYPT_BLOCK_SIZE; -} - -void -tls_crypt_init_key(struct key_ctx_bi *key, const char *key_file, - const char *key_inline, bool tls_server) +static struct key_type +tls_crypt_kt(void) { - const int key_direction = tls_server ? - KEY_DIRECTION_NORMAL : KEY_DIRECTION_INVERSE; - struct key_type kt; kt.cipher = cipher_kt_get("AES-256-CTR"); kt.digest = md_kt_get("SHA256"); if (!kt.cipher) { - msg(M_FATAL, "ERROR: --tls-crypt requires AES-256-CTR support."); + msg(M_WARN, "ERROR: --tls-crypt requires AES-256-CTR support."); + return (struct key_type) { 0 }; } if (!kt.digest) { - msg(M_FATAL, "ERROR: --tls-crypt requires HMAC-SHA-256 support."); + msg(M_WARN, "ERROR: --tls-crypt requires HMAC-SHA-256 support."); + return (struct key_type) { 0 }; } kt.cipher_length = cipher_kt_key_size(kt.cipher); kt.hmac_length = md_kt_size(kt.digest); + return kt; +} + +int +tls_crypt_buf_overhead(void) +{ + return packet_id_size(true) + TLS_CRYPT_TAG_SIZE + TLS_CRYPT_BLOCK_SIZE; +} + +void +tls_crypt_init_key(struct key_ctx_bi *key, const char *key_file, + const char *key_inline, bool tls_server) +{ + const int key_direction = tls_server ? + KEY_DIRECTION_NORMAL : KEY_DIRECTION_INVERSE; + struct key_type kt = tls_crypt_kt(); + if (!kt.cipher || !kt.digest) + { + msg (M_FATAL, "ERROR: --tls-crypt not supported"); + } crypto_read_openvpn_key(&kt, key, key_file, key_inline, key_direction, "Control Channel Encryption", "tls-crypt"); } diff --git a/src/openvpn/tls_crypt.h b/src/openvpn/tls_crypt.h index e8080df..4071ac9 100644 --- a/src/openvpn/tls_crypt.h +++ b/src/openvpn/tls_crypt.h @@ -74,6 +74,8 @@ #ifndef TLSCRYPT_H #define TLSCRYPT_H +#ifdef ENABLE_CRYPTO + #include "buffer.h" #include "crypto.h" #include "session_id.h" @@ -140,4 +142,6 @@ bool tls_crypt_unwrap(const struct buffer *src, struct buffer *dst, /** @} */ +#endif /* ENABLE_CRYPTO */ + #endif /* TLSCRYPT_H */ diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 75a156c..3639718 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -1862,7 +1862,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (oldtunfd >=0 && android_method == ANDROID_OPEN_AFTER_CLOSE) { close(oldtunfd); - openvpn_sleep(2); + management_sleep(2); } if (oldtunfd >=0 && android_method == ANDROID_KEEP_OLD_TUN) @@ -2563,8 +2563,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (ioctl(tt->fd, TUNGIFINFO, &info) < 0) { - msg(M_WARN | M_ERRNO, "Can't get interface info: %s", - strerror(errno)); + msg(M_WARN | M_ERRNO, "Can't get interface info"); } #ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */ @@ -2573,8 +2572,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (ioctl(tt->fd, TUNSIFINFO, &info) < 0) { - msg(M_WARN | M_ERRNO, "Can't set interface info: %s", - strerror(errno)); + msg(M_WARN | M_ERRNO, "Can't set interface info"); } } } @@ -2663,7 +2661,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun i = 1; if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */ { - msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)"); } } } @@ -2796,12 +2794,12 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (ioctl(tt->fd, TUNSIFMODE, &i) < 0) { - msg(M_WARN | M_ERRNO, "ioctl(TUNSIFMODE): %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "ioctl(TUNSIFMODE)"); } i = 1; if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0) { - msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); + msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)"); } } } @@ -3022,16 +3020,14 @@ utun_open_helper(struct ctl_info ctlInfo, int utunnum) if (fd < 0) { - msg(M_INFO, "Opening utun (%s): %s", "socket(SYSPROTO_CONTROL)", - strerror(errno)); + msg(M_INFO | M_ERRNO, "Opening utun (socket(SYSPROTO_CONTROL))"); return -2; } if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1) { close(fd); - msg(M_INFO, "Opening utun (%s): %s", "ioctl(CTLIOCGINFO)", - strerror(errno)); + msg(M_INFO | M_ERRNO, "Opening utun (ioctl(CTLIOCGINFO))"); return -2; } @@ -3049,8 +3045,7 @@ utun_open_helper(struct ctl_info ctlInfo, int utunnum) if (connect(fd, (struct sockaddr *)&sc, sizeof(sc)) < 0) { - msg(M_INFO, "Opening utun (%s): %s", "connect(AF_SYS_CONTROL)", - strerror(errno)); + msg(M_INFO | M_ERRNO, "Opening utun (connect(AF_SYS_CONTROL))"); close(fd); return -1; } @@ -5004,7 +4999,7 @@ netsh_command(const struct argv *a, int n, int msglevel) for (i = 0; i < n; ++i) { bool status; - openvpn_sleep(1); + management_sleep(1); netcmd_semaphore_lock(); argv_msg_prefix(M_INFO, a, "NETSH"); status = openvpn_execve_check(a, NULL, 0, "ERROR: netsh command failed"); @@ -5013,7 +5008,7 @@ netsh_command(const struct argv *a, int n, int msglevel) { return; } - openvpn_sleep(4); + management_sleep(4); } msg(msglevel, "NETSH: command failed"); } @@ -5996,7 +5991,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun if (s > 0) { msg(M_INFO, "Sleeping for %d seconds...", s); - openvpn_sleep(s); + management_sleep(s); } } diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index d0b10ba..95fea5d 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -1235,7 +1235,7 @@ set_win_sys_path_via_env(struct env_set *es) const char * -win_get_tempdir() +win_get_tempdir(void) { static char tmpdir[MAX_PATH]; WCHAR wtmpdir[MAX_PATH]; @@ -1398,7 +1398,7 @@ win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel) } int -win32_version_info() +win32_version_info(void) { if (!IsWindowsXPOrGreater()) { @@ -1426,7 +1426,7 @@ win32_version_info() } bool -win32_is_64bit() +win32_is_64bit(void) { #if defined(_WIN64) return true; /* 64-bit programs run only on Win64 */ diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h index 21a1021..7fc57cc 100644 --- a/src/openvpn/win32.h +++ b/src/openvpn/win32.h @@ -285,7 +285,7 @@ char *get_win_sys_path(void); void fork_to_self(const char *cmdline); /* Find temporary directory */ -const char *win_get_tempdir(); +const char *win_get_tempdir(void); /* Convert a string from UTF-8 to UCS-2 */ WCHAR *wide_string(const char *utf8, struct gc_arena *gc); @@ -299,7 +299,7 @@ bool win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel); #define WIN_7 2 #define WIN_8 3 -int win32_version_info(); +int win32_version_info(void); /* * String representation of Windows version number and name, see |