Message ID | 20210802114628.698697-1-arne@rfc2549.org |
---|---|
State | Superseded |
Headers | show |
Series | [Openvpn-devel] Modernise OpenVPN defaults and introduce '--compat-mode' | expand |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Hi, 12 minor corrections Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Monday, August 2nd, 2021 at 12:46, Arne Schwabe <arne@rfc2549.org> wrote: > TLS 1.0 should be allowed anymore in a sensible default configuration. Bump > the default to TLS 1.2 > TLS 1.0 should not be allowed -- Missing 'not' > > Also modify --cipher not to be automatically appended and default > allow-compression to no. This also allows a default configuration to be > compatible with DCO. > > Also introduce --compat-mode version to allow an easy way for UI/users > to maximise compatibility to earlier versions at the cost of DCO and > security. > > --compat-mode is only intended as an easier way to set options that > are still present. It will not implement options that are removed > (e.g. --keysize), so it is meant a best effort option and not as > a mean to provide 100% compatibility. mean -> means > > Signed-off-by: Arne Schwabe <arne@rfc2549.org> > --- > Changes.rst | 23 +++++++ > doc/man-sections/generic-options.rst | 21 ++++++ > src/openvpn/comp.h | 1 + > src/openvpn/options.c | 97 +++++++++++++++++++++++----- > src/openvpn/options.h | 17 +++++ > src/openvpn/ssl_ncp.c | 13 ++++ > src/openvpn/ssl_ncp.h | 8 +++ > 7 files changed, 163 insertions(+), 17 deletions(-) > > diff --git a/Changes.rst b/Changes.rst > index 0323a7f7a..cf3329486 100644 > --- a/Changes.rst > +++ b/Changes.rst > @@ -45,6 +45,12 @@ Pending auth support for plugins and scripts > > See ``sample/sample-scripts/totpauth.py`` for an example. > > +Compatibility mode (``--compat-mode``) > + The modernisation of defaults can impact the compatibility of OpenVPN 2.6.0 > + with older peers. The options ``--compat-mode`` allows UIs to provide users > + an easy way to still connect to older servers. with an easy way - missing 'with' -- not important > + > + > Deprecated features > ------------------- > ``inetd`` has been removed > @@ -65,6 +71,23 @@ Deprecated features > This option mainly served a role as debug option when NCP was first > introduced. It should now no longer be necessary. > > +TLS 1.0 and 1.1 are deprecated > + ``tls-version-min`` is set to 1.2 by default. OpenVPN 2.6.0 defaults > + to a minimum TLS version of 1.2 as TLS 1.0 and 1.1 should be generally > + avoided. Note that OpenVPN versions older than 2.3.7 use TLS 1.0 only. > + > +``--cipher`` options is no longer included in ``--data-ciphers`` by default > + Data cipher negotiation has been introduced in 2.4.0 and been significantly > + improved in 2.5.0. The implicit fallback to the cipher specified in > + ``--cipher`` has been removed. > + > +Compression no longer enabled by default > + Unless an explicit compression option is specified in the configuration, > + ``--allow-compression`` defaults to ``no`` in OpeNVPN 2.6.0. > + OpenVPN 2.5 still allowed by default a server to enable compression by Maybe improved with: By default, OpenVPN 2.5 still allowed a server to enable compression Just reads a little easier > + pushing compression related options. > + > + > Overview of changes in 2.5 > ========================== > > diff --git a/doc/man-sections/generic-options.rst b/doc/man-sections/generic-options.rst > index 203e35f57..739e845ac 100644 > --- a/doc/man-sections/generic-options.rst > +++ b/doc/man-sections/generic-options.rst > @@ -52,6 +52,27 @@ which mode OpenVPN is configured as. > BSDs implement a getrandom() or getentropy() syscall that removes the > need for /dev/urandom to be available. > > +--compat-mode version > + This option provides a way to alter the default of OpenVPN to be more > + compatible with the version ``version`` specified. All of the changes > + this option does can also be achieved using invdivdiual configuration > + option. All of the changes this option *makes* -- does -> makes invdivdiual -> individual > + > + Note: Using this options sets reverts defaults to no longer recommended > + values and should be avoided if possible. > + > + The following table details what defaults are changed depending on the > + version specified. > + > + - 2.5.x or lower: ``--allow-compression asym`` is automatically added > + to the configuration if no other compression options are present. > + - 2.4.x or lower: The cipher in ``--cipher`` is appended to > + ``--data-ciphers`` > + - 2.3.x or lower: ``--data-cipher-fallback`` is automatically added with > + the same cipher as ``--cipher`` > + - 2.3.6 or lower: ``--tls-version-min 1.0`` is added to the configuration > + when ``--tls-version-min`` is not explicitly set. > + > --config file > Load additional config options from ``file`` where each line corresponds > to one command line option, but with the leading '--' removed. > diff --git a/src/openvpn/comp.h b/src/openvpn/comp.h > index cd4f0e1a2..619a574e5 100644 > --- a/src/openvpn/comp.h > +++ b/src/openvpn/comp.h > @@ -59,6 +59,7 @@ > #define COMP_F_ALLOW_STUB_ONLY (1<<4) /* Only accept stub compression, even with COMP_F_ADVERTISE_STUBS_ONLY > * we still accept other compressions to be pushed */ > #define COMP_F_MIGRATE (1<<5) /* push stub-v2 or comp-lzo no when we see a client with comp-lzo in occ */ > +#define COMP_F_ALLOW_ASYM (1<<6) /* Compression was explicitly set to allow assymetric compression */ > > > /* > diff --git a/src/openvpn/options.c b/src/openvpn/options.c > index b57e8ecc6..649389360 100644 > --- a/src/openvpn/options.c > +++ b/src/openvpn/options.c > @@ -854,6 +854,7 @@ init_options(struct options *o, const bool init_gc) > o->use_prediction_resistance = false; > #endif > o->tls_timeout = 2; > + o->ssl_flags = (TLS_VER_1_2 << SSLF_TLS_VERSION_MIN_SHIFT); > o->renegotiate_bytes = -1; > o->renegotiate_seconds = 3600; > o->renegotiate_seconds_min = -1; > @@ -3079,11 +3080,11 @@ options_postprocess_verify(const struct options *o) > static void > options_postprocess_cipher(struct options *o) > { > - if (!o->pull && !(o->mode == MODE_SERVER)) > + if (!o->pull && !(o->tls_server || o->tls_client)) > { > /* we are in the classic P2P mode */ > - msg( M_WARN, "Cipher negotiation is disabled since neither " > - "P2MP client nor server mode is enabled"); > + msg( M_WARN, "Cipher negotiation is disabled since TLS " > + "mode is not enabled"); > > /* If the cipher is not set, use the old default of BF-CBC. We will > * warn that this is deprecated on cipher initialisation, no need > @@ -3101,26 +3102,68 @@ options_postprocess_cipher(struct options *o) > /* We still need to set the ciphername to BF-CBC since various other > * parts of OpenVPN assert that the ciphername is set */ > o->ciphername = "BF-CBC"; > + > + msg(M_WARN, "Note: --cipher is not set. Previous OpenVPN versions " > + "defaulted to BF-CBC as fallback when cipher negotiation " > + "failed in this case. If you need this fallback please add " > + "'--data-ciphers-fallback 'BF-CBC' to your configuration " > + "and/or add BF-CBC to --data-ciphers."); > } > else if (!o->enable_ncp_fallback > && !tls_item_in_cipher_list(o->ciphername, o->ncp_ciphers)) > { > - msg(M_WARN, "DEPRECATED OPTION: --cipher set to '%s' but missing in" > - " --data-ciphers (%s). Future OpenVPN version will " > - "ignore --cipher for cipher negotiations. " > - "Add '%s' to --data-ciphers or change --cipher '%s' to " > - "--data-ciphers-fallback '%s' to silence this warning.", > - o->ciphername, o->ncp_ciphers, o->ciphername, > - o->ciphername, o->ciphername); > - o->enable_ncp_fallback = true; > + msg(M_WARN, "DEPRECATED OPTION: --cipher set to '%s' but missing in " > + "--data-ciphers (%s). OpenVPN ignores --cipher for cipher " > + "negotiations. ", > + o->ciphername, o->ncp_ciphers); > + } > +} > > - /* Append the --cipher to ncp_ciphers to allow it in NCP */ > - size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(o->ciphername) + 1; > - char *ncp_ciphers = gc_malloc(newlen, false, &o->gc); > +static void > +options_set_backwards_compatible_options(struct options *o) > +{ > + /* TLS min version is not set */ > + if ((o->ssl_flags & SSLF_TLS_VERSION_MIN_MASK) == 0) > + { > + if (!need_compatibility(o, 203070)) > + { > + /* 2.3.6 and earlier have TLS 1.0 only, set minimum to TLS 1.0 */ > + o->ssl_flags = (TLS_VER_1_0 << SSLF_TLS_VERSION_MIN_SHIFT); > + } > + else > + { > + /* Use TLS 1.2 as proper default */ > + o->ssl_flags = (TLS_VER_1_2 << SSLF_TLS_VERSION_MIN_SHIFT); > + } > + } > > - ASSERT(openvpn_snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers, > - o->ciphername)); > - o->ncp_ciphers = ncp_ciphers; > + /* Versions < 2.5.0 do need --cipher in the list of accepted ciphers. > + * Version 2.4 might probably does not need it but NCP was not so 'might' is out of place and not necessary. > + * good with 2.4 and ncp-disable might be more common on 2.4 peers. > + * Only do this iif --cipher is not explicitly (BF-CBC). This is not iif -> if I'm not sure about the ' --cipher is not explicitly (BF-CBC)' part .. May be the () are not required ? > + * 100% correct backwards compatible behaviour but 2.5 already behaved like > + * this */ > + if (o->ciphername && need_compatibility(o, 205000) > + && !tls_item_in_cipher_list(o->ciphername, o->ncp_ciphers)) > + { > + append_cipher_to_ncp_list(o, o->ciphername); > + } > + > + /* Versions <= 2.3.0 additionally might be compiled with --enable-small and > + * not have OCC strings required for "poor man's NCP" */ > + if (o->ciphername && need_compatibility(o, 204000)) > + { > + o->enable_ncp_fallback = true; > + } > + > + /* Compression is deprecated and we do not want to announce support for it > + * by default anymore, additionally DCO breaks with with compression. > + * Disable compression by default starting with 2.6.0 if no other > + * compression related options have been explicitly set */ > + if (!comp_non_stub_enabled(&o->comp) && !need_compatibility(o, 206000) > + && (o->comp.flags == 0)) > + { > + o->comp.flags = COMP_F_ALLOW_STUB_ONLY|COMP_F_ADVERTISE_STUBS_ONLY; > } > } > > @@ -3136,6 +3179,8 @@ options_postprocess_mutate(struct options *o) > helper_keepalive(o); > helper_tcp_nodelay(o); > > + options_set_backwards_compatible_options(o); > + > options_postprocess_cipher(o); > options_postprocess_mutate_invariant(o); > > @@ -3213,6 +3258,12 @@ options_postprocess_mutate(struct options *o) > * when using --pull > */ > pre_connect_save(o); > + > + /* Give a general warning at the end of initialisation that defaults > + * have changed */ > + msg(M_WARN, "Note that modernistation of defaults in OpenVPN 2.6 limits " modernistation -> modernisation > + "compatibility with old versions. See Changes.rst and " > + "--compat-mode in the manual for details."); > } > > /* > @@ -6704,6 +6755,17 @@ add_option(struct options *options, > setenv_str(es, p[1], p[2] ? p[2] : ""); > } > } > + else if (streq(p[0], "compat-mode") && p[1] && !p[3]) > + { > + unsigned int major, minor, patch; > + if (!(sscanf(p[1], "%u.%u.%u", &major, &minor, &patch) == 3)) > + { > + msg(msglevel, "cannot parse version number for -compat-mode: %s", p[1]); > + goto err; > + } > + > + options->backwards_compatible = major * 10000 + minor * 100 + patch; > + } > else if (streq(p[0], "setenv-safe") && p[1] && !p[3]) > { > VERIFY_PERMISSION(OPT_P_SETENV); > @@ -7701,6 +7763,7 @@ add_option(struct options *options, > else if (streq(p[1], "asym")) > { > options->comp.flags &= ~COMP_F_ALLOW_COMPRESS; > + options->comp.flags |= COMP_F_ALLOW_ASYM; > } > else if (streq(p[1], "yes")) > { > diff --git a/src/openvpn/options.h b/src/openvpn/options.h > index b0e40cb7f..925083865 100644 > --- a/src/openvpn/options.h > +++ b/src/openvpn/options.h > @@ -225,6 +225,10 @@ struct options > > /* enable forward compatibility for post-2.1 features */ > bool forward_compatible; > + /** What version we should try to be compatible with as major * 10000 + > + * minor * 100 + patch, e.g. 2.4.7 => 204070 */ > + unsigned int backwards_compatible; > + > /* list of options that should be ignored even if unknown */ > const char **ignore_unknown_option; > > @@ -660,6 +664,19 @@ struct options > unsigned int data_channel_crypto_flags; > }; > > +/** > + * Returns if we want 'backwards-compatible' to a certain version > + * @param version the first version does that *NOT* need the compatibility > + * e.g. 204000 for all versions <= 2.4.0 > + * @return compatibility should be enabled. > + */ > +static inline bool > +need_compatibility(const struct options *o, int version) > +{ > + return o->backwards_compatible != 0 && o->backwards_compatible < version; > +} > + > + > #define streq(x, y) (!strcmp((x), (y))) > > /* > diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c > index 0258e6a72..5ea76640f 100644 > --- a/src/openvpn/ssl_ncp.c > +++ b/src/openvpn/ssl_ncp.c > @@ -172,6 +172,19 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) > return ret; > } > > + > +void > +append_cipher_to_ncp_list(struct options *o, const char *ciphername) > +{ > + /* Append the --cipher to ncp_ciphers to allow it in NCP */ > + size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(ciphername) + 1; > + char *ncp_ciphers = gc_malloc(newlen, false, &o->gc); > + > + ASSERT(openvpn_snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers, > + ciphername)); > + o->ncp_ciphers = ncp_ciphers; > +} > + > bool > tls_item_in_cipher_list(const char *item, const char *list) > { > diff --git a/src/openvpn/ssl_ncp.h b/src/openvpn/ssl_ncp.h > index 3fa68e262..2fc68fb53 100644 > --- a/src/openvpn/ssl_ncp.h > +++ b/src/openvpn/ssl_ncp.h > @@ -101,6 +101,14 @@ tls_peer_ncp_list(const char *peer_info, struct gc_arena *gc); > char * > mutate_ncp_cipher_list(const char *list, struct gc_arena *gc); > > +/** > + * Appends the cipher specified by the ciphernamer parameter to to ciphernamer -> ciphername - No 'r' on the end > + * the o->ncp_ciphers list. > + * @param o options struct to modify. Its gc is also used > + * @param ciphername the ciphername to add > + */ > +void append_cipher_to_ncp_list(struct options *o, const char *ciphername); > + > /** > * Return true iff item is present in the colon-separated zero-terminated iff -> if > * cipher list. > -- > 2.32.0 > > > > _______________________________________________ > Openvpn-devel mailing list > Openvpn-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/openvpn-devel -----BEGIN PGP SIGNATURE----- Version: ProtonMail wsBzBAEBCAAGBQJhCAh+ACEJEE+XnPZrkLidFiEECbw9RGejjXJ5xVVVT5ec 9muQuJ3gdQgAmq1LvRmTWrYIthfKt84Dc16hdhc4dCRrZijYQFcxM7CL+M1U dMMJibxQc4Bv5RgbXn6gcix1rFN3hlOouqkHaxMXgrPn4s4d0E1Vrv4xruth oX8vFzMZH6FcG4MIyWqNUZEXXOXsbV+FnF9CMbZeFHWdRSram6Mp26+QFATU ejHUs0OvAHpvlU8szQXb7QTM1bc/rZsF3ureMKp5R6RYVWcnD/BEGN9x6M/a gnyNlUlfdQ9xtaLX1kC8RZYPieSjrpK+aa/d8xqX36AyGwk0smfv3cSFGqa3 UZnCQ2WB/dZ7hhzpGGVXa4DLGjJBBDLLMrCaLcr4eI+YyQiUCYwPQQ== =+rmR -----END PGP SIGNATURE-----
diff --git a/Changes.rst b/Changes.rst index 0323a7f7a..cf3329486 100644 --- a/Changes.rst +++ b/Changes.rst @@ -45,6 +45,12 @@ Pending auth support for plugins and scripts See ``sample/sample-scripts/totpauth.py`` for an example. +Compatibility mode (``--compat-mode``) + The modernisation of defaults can impact the compatibility of OpenVPN 2.6.0 + with older peers. The options ``--compat-mode`` allows UIs to provide users + an easy way to still connect to older servers. + + Deprecated features ------------------- ``inetd`` has been removed @@ -65,6 +71,23 @@ Deprecated features This option mainly served a role as debug option when NCP was first introduced. It should now no longer be necessary. +TLS 1.0 and 1.1 are deprecated + ``tls-version-min`` is set to 1.2 by default. OpenVPN 2.6.0 defaults + to a minimum TLS version of 1.2 as TLS 1.0 and 1.1 should be generally + avoided. Note that OpenVPN versions older than 2.3.7 use TLS 1.0 only. + +``--cipher`` options is no longer included in ``--data-ciphers`` by default + Data cipher negotiation has been introduced in 2.4.0 and been significantly + improved in 2.5.0. The implicit fallback to the cipher specified in + ``--cipher`` has been removed. + +Compression no longer enabled by default + Unless an explicit compression option is specified in the configuration, + ``--allow-compression`` defaults to ``no`` in OpeNVPN 2.6.0. + OpenVPN 2.5 still allowed by default a server to enable compression by + pushing compression related options. + + Overview of changes in 2.5 ========================== diff --git a/doc/man-sections/generic-options.rst b/doc/man-sections/generic-options.rst index 203e35f57..739e845ac 100644 --- a/doc/man-sections/generic-options.rst +++ b/doc/man-sections/generic-options.rst @@ -52,6 +52,27 @@ which mode OpenVPN is configured as. BSDs implement a getrandom() or getentropy() syscall that removes the need for /dev/urandom to be available. +--compat-mode version + This option provides a way to alter the default of OpenVPN to be more + compatible with the version ``version`` specified. All of the changes + this option does can also be achieved using invdivdiual configuration + option. + + Note: Using this options sets reverts defaults to no longer recommended + values and should be avoided if possible. + + The following table details what defaults are changed depending on the + version specified. + + - 2.5.x or lower: ``--allow-compression asym`` is automatically added + to the configuration if no other compression options are present. + - 2.4.x or lower: The cipher in ``--cipher`` is appended to + ``--data-ciphers`` + - 2.3.x or lower: ``--data-cipher-fallback`` is automatically added with + the same cipher as ``--cipher`` + - 2.3.6 or lower: ``--tls-version-min 1.0`` is added to the configuration + when ``--tls-version-min`` is not explicitly set. + --config file Load additional config options from ``file`` where each line corresponds to one command line option, but with the leading '--' removed. diff --git a/src/openvpn/comp.h b/src/openvpn/comp.h index cd4f0e1a2..619a574e5 100644 --- a/src/openvpn/comp.h +++ b/src/openvpn/comp.h @@ -59,6 +59,7 @@ #define COMP_F_ALLOW_STUB_ONLY (1<<4) /* Only accept stub compression, even with COMP_F_ADVERTISE_STUBS_ONLY * we still accept other compressions to be pushed */ #define COMP_F_MIGRATE (1<<5) /* push stub-v2 or comp-lzo no when we see a client with comp-lzo in occ */ +#define COMP_F_ALLOW_ASYM (1<<6) /* Compression was explicitly set to allow assymetric compression */ /* diff --git a/src/openvpn/options.c b/src/openvpn/options.c index b57e8ecc6..649389360 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -854,6 +854,7 @@ init_options(struct options *o, const bool init_gc) o->use_prediction_resistance = false; #endif o->tls_timeout = 2; + o->ssl_flags = (TLS_VER_1_2 << SSLF_TLS_VERSION_MIN_SHIFT); o->renegotiate_bytes = -1; o->renegotiate_seconds = 3600; o->renegotiate_seconds_min = -1; @@ -3079,11 +3080,11 @@ options_postprocess_verify(const struct options *o) static void options_postprocess_cipher(struct options *o) { - if (!o->pull && !(o->mode == MODE_SERVER)) + if (!o->pull && !(o->tls_server || o->tls_client)) { /* we are in the classic P2P mode */ - msg( M_WARN, "Cipher negotiation is disabled since neither " - "P2MP client nor server mode is enabled"); + msg( M_WARN, "Cipher negotiation is disabled since TLS " + "mode is not enabled"); /* If the cipher is not set, use the old default of BF-CBC. We will * warn that this is deprecated on cipher initialisation, no need @@ -3101,26 +3102,68 @@ options_postprocess_cipher(struct options *o) /* We still need to set the ciphername to BF-CBC since various other * parts of OpenVPN assert that the ciphername is set */ o->ciphername = "BF-CBC"; + + msg(M_WARN, "Note: --cipher is not set. Previous OpenVPN versions " + "defaulted to BF-CBC as fallback when cipher negotiation " + "failed in this case. If you need this fallback please add " + "'--data-ciphers-fallback 'BF-CBC' to your configuration " + "and/or add BF-CBC to --data-ciphers."); } else if (!o->enable_ncp_fallback && !tls_item_in_cipher_list(o->ciphername, o->ncp_ciphers)) { - msg(M_WARN, "DEPRECATED OPTION: --cipher set to '%s' but missing in" - " --data-ciphers (%s). Future OpenVPN version will " - "ignore --cipher for cipher negotiations. " - "Add '%s' to --data-ciphers or change --cipher '%s' to " - "--data-ciphers-fallback '%s' to silence this warning.", - o->ciphername, o->ncp_ciphers, o->ciphername, - o->ciphername, o->ciphername); - o->enable_ncp_fallback = true; + msg(M_WARN, "DEPRECATED OPTION: --cipher set to '%s' but missing in " + "--data-ciphers (%s). OpenVPN ignores --cipher for cipher " + "negotiations. ", + o->ciphername, o->ncp_ciphers); + } +} - /* Append the --cipher to ncp_ciphers to allow it in NCP */ - size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(o->ciphername) + 1; - char *ncp_ciphers = gc_malloc(newlen, false, &o->gc); +static void +options_set_backwards_compatible_options(struct options *o) +{ + /* TLS min version is not set */ + if ((o->ssl_flags & SSLF_TLS_VERSION_MIN_MASK) == 0) + { + if (!need_compatibility(o, 203070)) + { + /* 2.3.6 and earlier have TLS 1.0 only, set minimum to TLS 1.0 */ + o->ssl_flags = (TLS_VER_1_0 << SSLF_TLS_VERSION_MIN_SHIFT); + } + else + { + /* Use TLS 1.2 as proper default */ + o->ssl_flags = (TLS_VER_1_2 << SSLF_TLS_VERSION_MIN_SHIFT); + } + } - ASSERT(openvpn_snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers, - o->ciphername)); - o->ncp_ciphers = ncp_ciphers; + /* Versions < 2.5.0 do need --cipher in the list of accepted ciphers. + * Version 2.4 might probably does not need it but NCP was not so + * good with 2.4 and ncp-disable might be more common on 2.4 peers. + * Only do this iif --cipher is not explicitly (BF-CBC). This is not + * 100% correct backwards compatible behaviour but 2.5 already behaved like + * this */ + if (o->ciphername && need_compatibility(o, 205000) + && !tls_item_in_cipher_list(o->ciphername, o->ncp_ciphers)) + { + append_cipher_to_ncp_list(o, o->ciphername); + } + + /* Versions <= 2.3.0 additionally might be compiled with --enable-small and + * not have OCC strings required for "poor man's NCP" */ + if (o->ciphername && need_compatibility(o, 204000)) + { + o->enable_ncp_fallback = true; + } + + /* Compression is deprecated and we do not want to announce support for it + * by default anymore, additionally DCO breaks with with compression. + * Disable compression by default starting with 2.6.0 if no other + * compression related options have been explicitly set */ + if (!comp_non_stub_enabled(&o->comp) && !need_compatibility(o, 206000) + && (o->comp.flags == 0)) + { + o->comp.flags = COMP_F_ALLOW_STUB_ONLY|COMP_F_ADVERTISE_STUBS_ONLY; } } @@ -3136,6 +3179,8 @@ options_postprocess_mutate(struct options *o) helper_keepalive(o); helper_tcp_nodelay(o); + options_set_backwards_compatible_options(o); + options_postprocess_cipher(o); options_postprocess_mutate_invariant(o); @@ -3213,6 +3258,12 @@ options_postprocess_mutate(struct options *o) * when using --pull */ pre_connect_save(o); + + /* Give a general warning at the end of initialisation that defaults + * have changed */ + msg(M_WARN, "Note that modernistation of defaults in OpenVPN 2.6 limits " + "compatibility with old versions. See Changes.rst and " + "--compat-mode in the manual for details."); } /* @@ -6704,6 +6755,17 @@ add_option(struct options *options, setenv_str(es, p[1], p[2] ? p[2] : ""); } } + else if (streq(p[0], "compat-mode") && p[1] && !p[3]) + { + unsigned int major, minor, patch; + if (!(sscanf(p[1], "%u.%u.%u", &major, &minor, &patch) == 3)) + { + msg(msglevel, "cannot parse version number for -compat-mode: %s", p[1]); + goto err; + } + + options->backwards_compatible = major * 10000 + minor * 100 + patch; + } else if (streq(p[0], "setenv-safe") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_SETENV); @@ -7701,6 +7763,7 @@ add_option(struct options *options, else if (streq(p[1], "asym")) { options->comp.flags &= ~COMP_F_ALLOW_COMPRESS; + options->comp.flags |= COMP_F_ALLOW_ASYM; } else if (streq(p[1], "yes")) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index b0e40cb7f..925083865 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -225,6 +225,10 @@ struct options /* enable forward compatibility for post-2.1 features */ bool forward_compatible; + /** What version we should try to be compatible with as major * 10000 + + * minor * 100 + patch, e.g. 2.4.7 => 204070 */ + unsigned int backwards_compatible; + /* list of options that should be ignored even if unknown */ const char **ignore_unknown_option; @@ -660,6 +664,19 @@ struct options unsigned int data_channel_crypto_flags; }; +/** + * Returns if we want 'backwards-compatible' to a certain version + * @param version the first version does that *NOT* need the compatibility + * e.g. 204000 for all versions <= 2.4.0 + * @return compatibility should be enabled. + */ +static inline bool +need_compatibility(const struct options *o, int version) +{ + return o->backwards_compatible != 0 && o->backwards_compatible < version; +} + + #define streq(x, y) (!strcmp((x), (y))) /* diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c index 0258e6a72..5ea76640f 100644 --- a/src/openvpn/ssl_ncp.c +++ b/src/openvpn/ssl_ncp.c @@ -172,6 +172,19 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) return ret; } + +void +append_cipher_to_ncp_list(struct options *o, const char *ciphername) +{ + /* Append the --cipher to ncp_ciphers to allow it in NCP */ + size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(ciphername) + 1; + char *ncp_ciphers = gc_malloc(newlen, false, &o->gc); + + ASSERT(openvpn_snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers, + ciphername)); + o->ncp_ciphers = ncp_ciphers; +} + bool tls_item_in_cipher_list(const char *item, const char *list) { diff --git a/src/openvpn/ssl_ncp.h b/src/openvpn/ssl_ncp.h index 3fa68e262..2fc68fb53 100644 --- a/src/openvpn/ssl_ncp.h +++ b/src/openvpn/ssl_ncp.h @@ -101,6 +101,14 @@ tls_peer_ncp_list(const char *peer_info, struct gc_arena *gc); char * mutate_ncp_cipher_list(const char *list, struct gc_arena *gc); +/** + * Appends the cipher specified by the ciphernamer parameter to to + * the o->ncp_ciphers list. + * @param o options struct to modify. Its gc is also used + * @param ciphername the ciphername to add + */ +void append_cipher_to_ncp_list(struct options *o, const char *ciphername); + /** * Return true iff item is present in the colon-separated zero-terminated * cipher list.
TLS 1.0 should be allowed anymore in a sensible default configuration. Bump the default to TLS 1.2 Also modify --cipher not to be automatically appended and default allow-compression to no. This also allows a default configuration to be compatible with DCO. Also introduce --compat-mode version to allow an easy way for UI/users to maximise compatibility to earlier versions at the cost of DCO and security. --compat-mode is only intended as an easier way to set options that are still present. It will not implement options that are removed (e.g. --keysize), so it is meant a best effort option and not as a mean to provide 100% compatibility. Signed-off-by: Arne Schwabe <arne@rfc2549.org> --- Changes.rst | 23 +++++++ doc/man-sections/generic-options.rst | 21 ++++++ src/openvpn/comp.h | 1 + src/openvpn/options.c | 97 +++++++++++++++++++++++----- src/openvpn/options.h | 17 +++++ src/openvpn/ssl_ncp.c | 13 ++++ src/openvpn/ssl_ncp.h | 8 +++ 7 files changed, 163 insertions(+), 17 deletions(-)