summaryrefslogtreecommitdiff
path: root/src/openvpn/options.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/options.c')
-rw-r--r--src/openvpn/options.c127
1 files changed, 96 insertions, 31 deletions
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index bfedb6a..fef5e90 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -17,10 +17,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
@@ -592,7 +591,8 @@ static const char usage_message[] =
"--x509-username-field : Field in x509 certificate containing the username.\n"
" Default is CN in the Subject field.\n"
#endif
- "--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n"
+ "--verify-hash hash [algo] : Specify fingerprint for level-1 certificate.\n"
+ " Valid algo flags are SHA1 and SHA256. \n"
#ifdef _WIN32
"--cryptoapicert select-string : Load the certificate and private key from the\n"
" Windows Certificate System Store.\n"
@@ -636,8 +636,8 @@ static const char usage_message[] =
"--verify-x509-name name: Accept connections only from a host with X509 subject\n"
" DN name. The remote host must also pass all other tests\n"
" of verification.\n"
- "--ns-cert-type t: Require that peer certificate was signed with an explicit\n"
- " nsCertType designation t = 'client' | 'server'.\n"
+ "--ns-cert-type t: (DEPRECATED) Require that peer certificate was signed with \n"
+ " an explicit nsCertType designation t = 'client' | 'server'.\n"
"--x509-track x : Save peer X509 attribute x in environment for use by\n"
" plugins and management interface.\n"
#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
@@ -716,7 +716,6 @@ static const char usage_message[] =
"--dhcp-renew : Ask Windows to renew the TAP adapter lease on startup.\n"
"--dhcp-pre-release : Ask Windows to release the previous TAP adapter lease on\n"
" startup.\n"
- "--dhcp-release : Ask Windows to release the TAP adapter lease on shutdown.\n"
"--register-dns : Run ipconfig /flushdns and ipconfig /registerdns\n"
" on connection initiation.\n"
"--tap-sleep n : Sleep for n seconds after TAP adapter open before\n"
@@ -999,7 +998,9 @@ setenv_settings(struct env_set *es, const struct options *o)
{
int i;
for (i = 0; i < o->connection_list->len; ++i)
+ {
setenv_connection_entry(es, o->connection_list->array[i], i+1);
+ }
}
else
{
@@ -1214,7 +1215,6 @@ show_tuntap_options(const struct tuntap_options *o)
SHOW_BOOL(dhcp_options);
SHOW_BOOL(dhcp_renew);
SHOW_BOOL(dhcp_pre_release);
- SHOW_BOOL(dhcp_release);
SHOW_STR(domain);
SHOW_STR(netbios_scope);
SHOW_INT(netbios_node_type);
@@ -1761,7 +1761,9 @@ show_settings(const struct options *o)
{
int i;
for (i = 0; i<MAX_PARMS; i++)
+ {
SHOW_INT(remote_cert_ku[i]);
+ }
}
SHOW_STR(remote_cert_eku);
SHOW_INT(ssl_flags);
@@ -1789,22 +1791,30 @@ show_settings(const struct options *o)
{
int i;
for (i = 0; i<MAX_PARMS && o->pkcs11_providers[i] != NULL; i++)
+ {
SHOW_PARM(pkcs11_providers, o->pkcs11_providers[i], "%s");
+ }
}
{
int i;
for (i = 0; i<MAX_PARMS; i++)
+ {
SHOW_PARM(pkcs11_protected_authentication, o->pkcs11_protected_authentication[i] ? "ENABLED" : "DISABLED", "%s");
+ }
}
{
int i;
for (i = 0; i<MAX_PARMS; i++)
+ {
SHOW_PARM(pkcs11_private_mode, o->pkcs11_private_mode[i], "%08x");
+ }
}
{
int i;
for (i = 0; i<MAX_PARMS; i++)
+ {
SHOW_PARM(pkcs11_cert_private, o->pkcs11_cert_private[i] ? "ENABLED" : "DISABLED", "%s");
+ }
}
SHOW_INT(pkcs11_pin_cache_period);
SHOW_STR(pkcs11_id);
@@ -2939,7 +2949,9 @@ options_postprocess_verify(const struct options *o)
{
int i;
for (i = 0; i < o->connection_list->len; ++i)
+ {
options_postprocess_verify_ce(o, o->connection_list->array[i]);
+ }
}
else
{
@@ -2990,7 +3002,9 @@ options_postprocess_mutate(struct options *o)
ASSERT(o->connection_list);
for (i = 0; i < o->connection_list->len; ++i)
+ {
options_postprocess_mutate_ce(o, o->connection_list->array[i]);
+ }
#ifdef ENABLE_CRYPTO
if (o->tls_server)
@@ -3803,7 +3817,9 @@ options_warning_safe_scan1(const int msglevel,
char *p = gc_malloc(OPTION_PARM_SIZE, true, &gc);
while (buf_parse(&b, delim, p, OPTION_PARM_SIZE))
+ {
options_warning_safe_scan2(msglevel, delim, report_inconsistent, p, b2_src, b1_name, b2_name);
+ }
gc_free(&gc);
}
@@ -4080,6 +4096,7 @@ usage(void)
fprintf(fp, usage_message,
title_string,
o.ce.connect_retry_seconds,
+ o.ce.connect_retry_seconds_max,
o.ce.local_port, o.ce.remote_port,
TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT,
o.verbosity);
@@ -4430,7 +4447,10 @@ read_inline_file(struct in_src *is, const char *close_tag, struct gc_arena *gc)
{
char *line_ptr = line;
/* Remove leading spaces */
- while (isspace(*line_ptr)) line_ptr++;
+ while (isspace(*line_ptr))
+ {
+ line_ptr++;
+ }
if (!strncmp(line_ptr, close_tag, strlen(close_tag)))
{
endtagfound = true;
@@ -4526,7 +4546,7 @@ read_config_file(struct options *options,
FILE *fp;
int line_num;
char line[OPTION_LINE_SIZE+1];
- char *p[MAX_PARMS];
+ char *p[MAX_PARMS+1];
++level;
if (level <= max_recursive_levels)
@@ -4558,7 +4578,7 @@ read_config_file(struct options *options,
{
offset = 3;
}
- if (parse_line(line + offset, p, SIZE(p), file, line_num, msglevel, &options->gc))
+ if (parse_line(line + offset, p, SIZE(p)-1, file, line_num, msglevel, &options->gc))
{
bypass_doubledash(&p[0]);
check_inline_file_via_fp(fp, p, &options->gc);
@@ -4600,10 +4620,10 @@ read_config_string(const char *prefix,
while (buf_parse(&multiline, '\n', line, sizeof(line)))
{
- char *p[MAX_PARMS];
+ char *p[MAX_PARMS+1];
CLEAR(p);
++line_num;
- if (parse_line(line, p, SIZE(p), prefix, line_num, msglevel, &options->gc))
+ if (parse_line(line, p, SIZE(p)-1, prefix, line_num, msglevel, &options->gc))
{
bypass_doubledash(&p[0]);
check_inline_file_via_buf(&multiline, p, &options->gc);
@@ -4734,14 +4754,14 @@ apply_push_options(struct options *options,
while (buf_parse(buf, ',', line, sizeof(line)))
{
- char *p[MAX_PARMS];
+ char *p[MAX_PARMS+1];
CLEAR(p);
++line_num;
if (!apply_pull_filter(options, line))
{
return false; /* Cause push/pull error and stop push processing */
}
- if (parse_line(line, p, SIZE(p), file, line_num, msglevel, &options->gc))
+ if (parse_line(line, p, SIZE(p)-1, file, line_num, msglevel, &options->gc))
{
add_option(options, p, file, line_num, 0, msglevel, permission_mask, option_types_found, es);
}
@@ -5147,7 +5167,7 @@ add_option(struct options *options,
}
#endif /* ifdef ENABLE_MANAGEMENT */
#ifdef ENABLE_PLUGIN
- else if (streq(p[0], "plugin") && p[1] && !p[3])
+ else if (streq(p[0], "plugin") && p[1])
{
VERIFY_PERMISSION(OPT_P_PLUGIN);
if (!options->plugin_list)
@@ -5297,12 +5317,14 @@ add_option(struct options *options,
if (!sub.ce.remote)
{
msg(msglevel, "Each 'connection' block must contain exactly one 'remote' directive");
+ uninit_options(&sub);
goto err;
}
e = alloc_connection_entry(options, msglevel);
if (!e)
{
+ uninit_options(&sub);
goto err;
}
*e = sub.ce;
@@ -5320,18 +5342,24 @@ add_option(struct options *options,
VERIFY_PERMISSION(OPT_P_GENERAL);
/* Find out how many options to be ignored */
for (i = 1; p[i]; i++)
+ {
numignored++;
+ }
/* add number of options already ignored */
for (i = 0; options->ignore_unknown_option
&& options->ignore_unknown_option[i]; i++)
+ {
numignored++;
+ }
/* Allocate array */
ALLOC_ARRAY_GC(ignore, const char *, numignored+1, &options->gc);
for (i = 0; options->ignore_unknown_option
&& options->ignore_unknown_option[i]; i++)
+ {
ignore[i] = options->ignore_unknown_option[i];
+ }
options->ignore_unknown_option = ignore;
@@ -6015,7 +6043,8 @@ add_option(struct options *options,
struct http_custom_header *custom_header = NULL;
int i;
/* Find the first free header */
- for (i = 0; i < MAX_CUSTOM_HTTP_HEADER; i++) {
+ for (i = 0; i < MAX_CUSTOM_HTTP_HEADER; i++)
+ {
if (!ho->custom_headers[i].name)
{
custom_header = &ho->custom_headers[i];
@@ -7200,11 +7229,11 @@ add_option(struct options *options,
{
VERIFY_PERMISSION(OPT_P_IPWIN32);
options->tuntap_options.dhcp_pre_release = true;
+ options->tuntap_options.dhcp_renew = true;
}
else if (streq(p[0], "dhcp-release") && !p[1])
{
- VERIFY_PERMISSION(OPT_P_IPWIN32);
- options->tuntap_options.dhcp_release = true;
+ msg(M_WARN, "Obsolete option --dhcp-release detected. This is now on by default");
}
else if (streq(p[0], "dhcp-internal") && p[1] && !p[2]) /* standalone method for internal use */
{
@@ -7676,10 +7705,25 @@ add_option(struct options *options,
options->extra_certs_file_inline = p[2];
}
}
- else if (streq(p[0], "verify-hash") && p[1] && !p[2])
+ else if (streq(p[0], "verify-hash") && p[1] && !p[3])
{
VERIFY_PERMISSION(OPT_P_GENERAL);
- options->verify_hash = parse_hash_fingerprint(p[1], SHA_DIGEST_LENGTH, msglevel, &options->gc);
+
+ if (!p[2] || (p[2] && streq(p[2], "SHA1")))
+ {
+ options->verify_hash = parse_hash_fingerprint(p[1], SHA_DIGEST_LENGTH, msglevel, &options->gc);
+ options->verify_hash_algo = MD_SHA1;
+ }
+ else if (p[2] && streq(p[2], "SHA256"))
+ {
+ options->verify_hash = parse_hash_fingerprint(p[1], SHA256_DIGEST_LENGTH, msglevel, &options->gc);
+ options->verify_hash_algo = MD_SHA256;
+ }
+ else
+ {
+ msg(msglevel, "invalid or unsupported hashing algorithm: %s (only SHA1 and SHA256 are valid)", p[2]);
+ goto err;
+ }
}
#ifdef ENABLE_CRYPTOAPI
else if (streq(p[0], "cryptoapicert") && p[1] && !p[2])
@@ -7903,12 +7947,18 @@ add_option(struct options *options,
}
else if (streq(p[0], "remote-cert-ku"))
{
- int j;
-
VERIFY_PERMISSION(OPT_P_GENERAL);
+ size_t j;
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
+ {
sscanf(p[j], "%x", &(options->remote_cert_ku[j-1]));
+ }
+ if (j == 1)
+ {
+ /* No specific KU required, but require KU to be present */
+ options->remote_cert_ku[0] = OPENVPN_KU_REQUIRED;
+ }
}
else if (streq(p[0], "remote-cert-eku") && p[1] && !p[2])
{
@@ -7921,15 +7971,12 @@ add_option(struct options *options,
if (streq(p[1], "server"))
{
- options->remote_cert_ku[0] = 0xa0;
- options->remote_cert_ku[1] = 0x88;
+ options->remote_cert_ku[0] = OPENVPN_KU_REQUIRED;
options->remote_cert_eku = "TLS Web Server Authentication";
}
else if (streq(p[1], "client"))
{
- options->remote_cert_ku[0] = 0x80;
- options->remote_cert_ku[1] = 0x08;
- options->remote_cert_ku[2] = 0x88;
+ options->remote_cert_ku[0] = OPENVPN_KU_REQUIRED;
options->remote_cert_eku = "TLS Web Client Authentication";
}
else
@@ -8037,15 +8084,25 @@ add_option(struct options *options,
if (strncmp("ext:", s, 4) != 0)
{
size_t i = 0;
- while (s[i] && !isupper(s[i])) i++;
+ while (s[i] && !isupper(s[i]))
+ {
+ i++;
+ }
if (strlen(s) == i)
{
- while ((*s = toupper(*s)) != '\0') s++;
+ while ((*s = toupper(*s)) != '\0')
+ {
+ s++;
+ }
msg(M_WARN, "DEPRECATED FEATURE: automatically upcased the "
"--x509-username-field parameter to '%s'; please update your"
"configuration", p[1]);
}
}
+ else if (!x509_username_field_ext_supported(s+4))
+ {
+ msg(msglevel, "Unsupported x509-username-field extension: %s", s);
+ }
options->x509_username_field = p[1];
}
#endif /* ENABLE_X509ALTUSERNAME */
@@ -8094,7 +8151,9 @@ add_option(struct options *options,
VERIFY_PERMISSION(OPT_P_GENERAL);
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
+ {
options->pkcs11_providers[j-1] = p[j];
+ }
}
else if (streq(p[0], "pkcs11-protected-authentication"))
{
@@ -8103,7 +8162,9 @@ add_option(struct options *options,
VERIFY_PERMISSION(OPT_P_GENERAL);
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
+ {
options->pkcs11_protected_authentication[j-1] = atoi(p[j]) != 0 ? 1 : 0;
+ }
}
else if (streq(p[0], "pkcs11-private-mode") && p[1])
{
@@ -8112,7 +8173,9 @@ add_option(struct options *options,
VERIFY_PERMISSION(OPT_P_GENERAL);
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
+ {
sscanf(p[j], "%x", &(options->pkcs11_private_mode[j-1]));
+ }
}
else if (streq(p[0], "pkcs11-cert-private"))
{
@@ -8121,7 +8184,9 @@ add_option(struct options *options,
VERIFY_PERMISSION(OPT_P_GENERAL);
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
+ {
options->pkcs11_cert_private[j-1] = atoi(p[j]) != 0 ? 1 : 0;
+ }
}
else if (streq(p[0], "pkcs11-pin-cache") && p[1] && !p[2])
{