Browse code

Fail if options have extra parameters [v2]

Throw an error if an option has extra parameters; previously they
were silently ignored (see also trac #557)

This feature was discussed on the openvpn-devel mailing list
(http://thread.gmane.org/gmane.network.openvpn.devel/9599).

The (modified) message "Unrecognized option or missing or extra
parameter(s)" is used except for a few options:

* The --help option: An extra parameter for --help generates a
specific error message after showing the syntax message. This
is done to help a user who tries "--help tls-cipher" or similar,
hoping to get more information about the "tls-cipher" option.

* The --dhcp-option option: It has its own similar message, into
which " or extra" has been inserted.

* Ten options such as --up that accept a command (instead of a
path) already detect extra parameters and generate specific
error messages that mention double-quoting commands which
contain embedded spaces.

Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <CAEsd45RvRfmqetu-EoFjSdyBk5F9X1K5muPGu-+_+30TMNOU_A@mail.gmail.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/9783
URL: https://community.openvpn.net/openvpn/ticket/557

Signed-off-by: Gert Doering <gert@greenie.muc.de>

Jonathan K. Bullard authored on 2015/06/02 21:43:26
Showing 1 changed files
... ...
@@ -4126,13 +4126,18 @@ add_option (struct options *options,
4126 4126
     {
4127 4127
       VERIFY_PERMISSION (OPT_P_GENERAL);
4128 4128
       usage ();
4129
+      if (p[1])
4130
+        {
4131
+	  msg (msglevel, "--help does not accept any parameters");
4132
+	  goto err;
4133
+        }
4129 4134
     }
4130
-  if (streq (p[0], "version"))
4135
+  if (streq (p[0], "version") && !p[1])
4131 4136
     {
4132 4137
       VERIFY_PERMISSION (OPT_P_GENERAL);
4133 4138
       usage_version ();
4134 4139
     }
4135
-  else if (streq (p[0], "config") && p[1])
4140
+  else if (streq (p[0], "config") && p[1] && !p[2])
4136 4141
     {
4137 4142
       VERIFY_PERMISSION (OPT_P_CONFIG);
4138 4143
 
... ...
@@ -4143,7 +4148,7 @@ add_option (struct options *options,
4143 4143
       read_config_file (options, p[1], level, file, line, msglevel, permission_mask, option_types_found, es);
4144 4144
     }
4145 4145
 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
4146
-  else if (streq (p[0], "show-gateway"))
4146
+  else if (streq (p[0], "show-gateway") && !p[1])
4147 4147
     {
4148 4148
       struct route_gateway_info rgi;
4149 4149
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -4193,7 +4198,7 @@ add_option (struct options *options,
4193 4193
 	msg (M_WARN, "echo/parameter option overflow");
4194 4194
     }
4195 4195
 #ifdef ENABLE_MANAGEMENT
4196
-  else if (streq (p[0], "management") && p[1] && p[2])
4196
+  else if (streq (p[0], "management") && p[1] && p[2] && !p[4])
4197 4197
     {
4198 4198
       VERIFY_PERMISSION (OPT_P_GENERAL);
4199 4199
       if (streq (p[2], "unix"))
... ...
@@ -4213,64 +4218,64 @@ add_option (struct options *options,
4213 4213
 	  options->management_user_pass = p[3];
4214 4214
 	}
4215 4215
     }
4216
-  else if (streq (p[0], "management-client-user") && p[1])
4216
+  else if (streq (p[0], "management-client-user") && p[1] && !p[2])
4217 4217
     {
4218 4218
       VERIFY_PERMISSION (OPT_P_GENERAL);
4219 4219
       options->management_client_user = p[1];
4220 4220
     }
4221
-  else if (streq (p[0], "management-client-group") && p[1])
4221
+  else if (streq (p[0], "management-client-group") && p[1] && !p[2])
4222 4222
     {
4223 4223
       VERIFY_PERMISSION (OPT_P_GENERAL);
4224 4224
       options->management_client_group = p[1];
4225 4225
     }
4226
-  else if (streq (p[0], "management-query-passwords"))
4226
+  else if (streq (p[0], "management-query-passwords") && !p[1])
4227 4227
     {
4228 4228
       VERIFY_PERMISSION (OPT_P_GENERAL);
4229 4229
       options->management_flags |= MF_QUERY_PASSWORDS;
4230 4230
     }
4231
-  else if (streq (p[0], "management-query-remote"))
4231
+  else if (streq (p[0], "management-query-remote") && !p[1])
4232 4232
     {
4233 4233
       VERIFY_PERMISSION (OPT_P_GENERAL);
4234 4234
       options->management_flags |= MF_QUERY_REMOTE;
4235 4235
     }
4236
-  else if (streq (p[0], "management-query-proxy"))
4236
+  else if (streq (p[0], "management-query-proxy") && !p[1])
4237 4237
     {
4238 4238
       VERIFY_PERMISSION (OPT_P_GENERAL);
4239 4239
       options->management_flags |= MF_QUERY_PROXY;
4240 4240
     }
4241
-  else if (streq (p[0], "management-hold"))
4241
+  else if (streq (p[0], "management-hold") && !p[1])
4242 4242
     {
4243 4243
       VERIFY_PERMISSION (OPT_P_GENERAL);
4244 4244
       options->management_flags |= MF_HOLD;
4245 4245
     }
4246
-  else if (streq (p[0], "management-signal"))
4246
+  else if (streq (p[0], "management-signal") && !p[1])
4247 4247
     {
4248 4248
       VERIFY_PERMISSION (OPT_P_GENERAL);
4249 4249
       options->management_flags |= MF_SIGNAL;
4250 4250
     }
4251
-  else if (streq (p[0], "management-forget-disconnect"))
4251
+  else if (streq (p[0], "management-forget-disconnect") && !p[1])
4252 4252
     {
4253 4253
       VERIFY_PERMISSION (OPT_P_GENERAL);
4254 4254
       options->management_flags |= MF_FORGET_DISCONNECT;
4255 4255
     }
4256
-  else if (streq (p[0], "management-up-down"))
4256
+  else if (streq (p[0], "management-up-down") && !p[1])
4257 4257
     {
4258 4258
       VERIFY_PERMISSION (OPT_P_GENERAL);
4259 4259
       options->management_flags |= MF_UP_DOWN;
4260 4260
     }
4261
-  else if (streq (p[0], "management-client"))
4261
+  else if (streq (p[0], "management-client") && !p[2])
4262 4262
     {
4263 4263
       VERIFY_PERMISSION (OPT_P_GENERAL);
4264 4264
       options->management_flags |= MF_CONNECT_AS_CLIENT;
4265 4265
       options->management_write_peer_info_file = p[1];
4266 4266
     }
4267 4267
 #ifdef MANAGMENT_EXTERNAL_KEY
4268
-  else if (streq (p[0], "management-external-key"))
4268
+  else if (streq (p[0], "management-external-key") && !p[1])
4269 4269
     {
4270 4270
       VERIFY_PERMISSION (OPT_P_GENERAL);
4271 4271
       options->management_flags |= MF_EXTERNAL_KEY;
4272 4272
     }
4273
-  else if (streq (p[0], "management-external-cert") && p[1])
4273
+  else if (streq (p[0], "management-external-cert") && p[1] && !p[2])
4274 4274
     {
4275 4275
       VERIFY_PERMISSION (OPT_P_GENERAL);
4276 4276
       options->management_flags |= MF_EXTERNAL_CERT;
... ...
@@ -4278,27 +4283,27 @@ add_option (struct options *options,
4278 4278
     }
4279 4279
 #endif
4280 4280
 #ifdef MANAGEMENT_DEF_AUTH
4281
-  else if (streq (p[0], "management-client-auth"))
4281
+  else if (streq (p[0], "management-client-auth") && !p[1])
4282 4282
     {
4283 4283
       VERIFY_PERMISSION (OPT_P_GENERAL);
4284 4284
       options->management_flags |= MF_CLIENT_AUTH;
4285 4285
     }
4286 4286
 #endif
4287 4287
 #ifdef ENABLE_X509_TRACK
4288
-  else if (streq (p[0], "x509-track") && p[1])
4288
+  else if (streq (p[0], "x509-track") && p[1] && !p[2])
4289 4289
     {
4290 4290
       VERIFY_PERMISSION (OPT_P_GENERAL);
4291 4291
       x509_track_add (&options->x509_track, p[1], msglevel, &options->gc);
4292 4292
     }
4293 4293
 #endif
4294 4294
 #ifdef MANAGEMENT_PF
4295
-  else if (streq (p[0], "management-client-pf"))
4295
+  else if (streq (p[0], "management-client-pf") && !p[1])
4296 4296
     {
4297 4297
       VERIFY_PERMISSION (OPT_P_GENERAL);
4298 4298
       options->management_flags |= (MF_CLIENT_PF | MF_CLIENT_AUTH);
4299 4299
     }
4300 4300
 #endif
4301
-  else if (streq (p[0], "management-log-cache") && p[1])
4301
+  else if (streq (p[0], "management-log-cache") && p[1] && !p[2])
4302 4302
     {
4303 4303
       int cache;
4304 4304
 
... ...
@@ -4313,7 +4318,7 @@ add_option (struct options *options,
4313 4313
     }
4314 4314
 #endif
4315 4315
 #ifdef ENABLE_PLUGIN
4316
-  else if (streq (p[0], "plugin") && p[1])
4316
+  else if (streq (p[0], "plugin") && p[1] && !p[2])
4317 4317
     {
4318 4318
       VERIFY_PERMISSION (OPT_P_PLUGIN);
4319 4319
       if (!options->plugin_list)
... ...
@@ -4325,7 +4330,7 @@ add_option (struct options *options,
4325 4325
 	}
4326 4326
     }
4327 4327
 #endif
4328
-  else if (streq (p[0], "mode") && p[1])
4328
+  else if (streq (p[0], "mode") && p[1] && !p[2])
4329 4329
     {
4330 4330
       VERIFY_PERMISSION (OPT_P_GENERAL);
4331 4331
       if (streq (p[1], "p2p"))
... ...
@@ -4340,22 +4345,22 @@ add_option (struct options *options,
4340 4340
 	  goto err;
4341 4341
 	}
4342 4342
     }
4343
-  else if (streq (p[0], "dev") && p[1])
4343
+  else if (streq (p[0], "dev") && p[1] && !p[2])
4344 4344
     {
4345 4345
       VERIFY_PERMISSION (OPT_P_GENERAL);
4346 4346
       options->dev = p[1];
4347 4347
     }
4348
-  else if (streq (p[0], "dev-type") && p[1])
4348
+  else if (streq (p[0], "dev-type") && p[1] && !p[2])
4349 4349
     {
4350 4350
       VERIFY_PERMISSION (OPT_P_GENERAL);
4351 4351
       options->dev_type = p[1];
4352 4352
     }
4353
-  else if (streq (p[0], "dev-node") && p[1])
4353
+  else if (streq (p[0], "dev-node") && p[1] && !p[2])
4354 4354
     {
4355 4355
       VERIFY_PERMISSION (OPT_P_GENERAL);
4356 4356
       options->dev_node = p[1];
4357 4357
     }
4358
-  else if (streq (p[0], "lladdr") && p[1])
4358
+  else if (streq (p[0], "lladdr") && p[1] && !p[2])
4359 4359
     {
4360 4360
       VERIFY_PERMISSION (OPT_P_UP);
4361 4361
       if (mac_addr_safe (p[1])) /* MAC address only */
... ...
@@ -4366,24 +4371,24 @@ add_option (struct options *options,
4366 4366
 	  goto err;
4367 4367
 	}
4368 4368
     }
4369
-  else if (streq (p[0], "topology") && p[1])
4369
+  else if (streq (p[0], "topology") && p[1] && !p[2])
4370 4370
     {
4371 4371
       VERIFY_PERMISSION (OPT_P_UP);
4372 4372
       options->topology = parse_topology (p[1], msglevel);
4373 4373
     }
4374
-  else if (streq (p[0], "tun-ipv6"))
4374
+  else if (streq (p[0], "tun-ipv6") && !p[1])
4375 4375
     {
4376 4376
       VERIFY_PERMISSION (OPT_P_UP);
4377 4377
       options->tun_ipv6 = true;
4378 4378
     }
4379 4379
 #ifdef ENABLE_IPROUTE
4380
-  else if (streq (p[0], "iproute") && p[1])
4380
+  else if (streq (p[0], "iproute") && p[1] && !p[2])
4381 4381
     {
4382 4382
       VERIFY_PERMISSION (OPT_P_GENERAL);
4383 4383
       iproute_path = p[1];
4384 4384
     }
4385 4385
 #endif
4386
-  else if (streq (p[0], "ifconfig") && p[1] && p[2])
4386
+  else if (streq (p[0], "ifconfig") && p[1] && p[2] && !p[3])
4387 4387
     {
4388 4388
       VERIFY_PERMISSION (OPT_P_UP);
4389 4389
       if (ip_or_dns_addr_safe (p[1], options->allow_pull_fqdn) && ip_or_dns_addr_safe (p[2], options->allow_pull_fqdn)) /* FQDN -- may be DNS name */
... ...
@@ -4397,7 +4402,7 @@ add_option (struct options *options,
4397 4397
 	  goto err;
4398 4398
 	}
4399 4399
     }
4400
-  else if (streq (p[0], "ifconfig-ipv6") && p[1] && p[2] )
4400
+  else if (streq (p[0], "ifconfig-ipv6") && p[1] && p[2] && !p[3])
4401 4401
     {
4402 4402
       unsigned int netbits;
4403 4403
       char * ipv6_local;
... ...
@@ -4426,27 +4431,27 @@ add_option (struct options *options,
4426 4426
 	  goto err;
4427 4427
 	}
4428 4428
     }
4429
-  else if (streq (p[0], "ifconfig-noexec"))
4429
+  else if (streq (p[0], "ifconfig-noexec") && !p[1])
4430 4430
     {
4431 4431
       VERIFY_PERMISSION (OPT_P_UP);
4432 4432
       options->ifconfig_noexec = true;
4433 4433
     }
4434
-  else if (streq (p[0], "ifconfig-nowarn"))
4434
+  else if (streq (p[0], "ifconfig-nowarn") && !p[1])
4435 4435
     {
4436 4436
       VERIFY_PERMISSION (OPT_P_UP);
4437 4437
       options->ifconfig_nowarn = true;
4438 4438
     }
4439
-  else if (streq (p[0], "local") && p[1])
4439
+  else if (streq (p[0], "local") && p[1] && !p[2])
4440 4440
     {
4441 4441
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4442 4442
       options->ce.local = p[1];
4443 4443
     }
4444
-  else if (streq (p[0], "remote-random"))
4444
+  else if (streq (p[0], "remote-random") && !p[1])
4445 4445
     {
4446 4446
       VERIFY_PERMISSION (OPT_P_GENERAL);
4447 4447
       options->remote_random = true;
4448 4448
     }
4449
-  else if (streq (p[0], "connection") && p[1])
4449
+  else if (streq (p[0], "connection") && p[1] && !p[3])
4450 4450
     {
4451 4451
       VERIFY_PERMISSION (OPT_P_GENERAL);
4452 4452
       if (streq (p[1], INLINE_FILE_TAG) && p[2])
... ...
@@ -4509,7 +4514,7 @@ add_option (struct options *options,
4509 4509
       options->ignore_unknown_option[i] = NULL;
4510 4510
     }
4511 4511
 #if ENABLE_MANAGEMENT
4512
-  else if (streq (p[0], "http-proxy-override") && p[1] && p[2])
4512
+  else if (streq (p[0], "http-proxy-override") && p[1] && p[2] && !p[4])
4513 4513
     {
4514 4514
       VERIFY_PERMISSION (OPT_P_GENERAL);
4515 4515
       options->http_proxy_override = parse_http_proxy_override(p[1], p[2], p[3], msglevel, &options->gc);
... ...
@@ -4517,7 +4522,7 @@ add_option (struct options *options,
4517 4517
 	goto err;
4518 4518
     }
4519 4519
 #endif
4520
-  else if (streq (p[0], "remote") && p[1])
4520
+  else if (streq (p[0], "remote") && p[1] && !p[4])
4521 4521
     {
4522 4522
       struct remote_entry re;
4523 4523
       re.remote = re.remote_port= NULL;
... ...
@@ -4554,7 +4559,7 @@ add_option (struct options *options,
4554 4554
 	  connection_entry_load_re (&options->ce, &re);
4555 4555
 	}
4556 4556
     }
4557
-  else if (streq (p[0], "resolv-retry") && p[1])
4557
+  else if (streq (p[0], "resolv-retry") && p[1] && !p[2])
4558 4558
     {
4559 4559
       VERIFY_PERMISSION (OPT_P_GENERAL);
4560 4560
       if (streq (p[1], "infinite"))
... ...
@@ -4562,7 +4567,7 @@ add_option (struct options *options,
4562 4562
       else
4563 4563
 	options->resolve_retry_seconds = positive_atoi (p[1]);
4564 4564
     }
4565
-  else if (streq (p[0], "preresolve") || streq (p[0], "ip-remote-hint"))
4565
+  else if (streq (p[0], "preresolve") || streq (p[0], "ip-remote-hint") && !p[2])
4566 4566
     {
4567 4567
       VERIFY_PERMISSION (OPT_P_GENERAL);
4568 4568
       options->resolve_in_advance = true;
... ...
@@ -4571,18 +4576,18 @@ add_option (struct options *options,
4571 4571
       if (p[1])
4572 4572
 	options->ip_remote_hint=p[1];
4573 4573
     }
4574
-  else if (streq (p[0], "connect-retry") && p[1])
4574
+  else if (streq (p[0], "connect-retry") && p[1] && !p[2])
4575 4575
     {
4576 4576
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4577 4577
       options->ce.connect_retry_seconds = positive_atoi (p[1]);
4578 4578
     }
4579
-  else if (streq (p[0], "connect-timeout") && p[1])
4579
+  else if (streq (p[0], "connect-timeout") && p[1] && !p[2])
4580 4580
     {
4581 4581
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4582 4582
       options->ce.connect_timeout = positive_atoi (p[1]);
4583 4583
       options->ce.connect_timeout_defined = true;
4584 4584
     }
4585
-  else if (streq (p[0], "connect-retry-max") && p[1])
4585
+  else if (streq (p[0], "connect-retry-max") && p[1] && !p[2])
4586 4586
     {
4587 4587
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4588 4588
       options->connect_retry_max = positive_atoi (p[1]);
... ...
@@ -4597,24 +4602,24 @@ add_option (struct options *options,
4597 4597
 		       string_substitute (p[1], ',', ' ', &options->gc),
4598 4598
 		       "ipchange", true);
4599 4599
     }
4600
-  else if (streq (p[0], "float"))
4600
+  else if (streq (p[0], "float") && !p[1])
4601 4601
     {
4602 4602
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4603 4603
       options->ce.remote_float = true;
4604 4604
     }
4605 4605
 #ifdef ENABLE_DEBUG
4606
-  else if (streq (p[0], "gremlin") && p[1])
4606
+  else if (streq (p[0], "gremlin") && p[1] && !p[2])
4607 4607
     {
4608 4608
       VERIFY_PERMISSION (OPT_P_GENERAL);
4609 4609
       options->gremlin = positive_atoi (p[1]);
4610 4610
     }
4611 4611
 #endif
4612
-  else if (streq (p[0], "chroot") && p[1])
4612
+  else if (streq (p[0], "chroot") && p[1] && !p[2])
4613 4613
     {
4614 4614
       VERIFY_PERMISSION (OPT_P_GENERAL);
4615 4615
       options->chroot_dir = p[1];
4616 4616
     }
4617
-  else if (streq (p[0], "cd") && p[1])
4617
+  else if (streq (p[0], "cd") && p[1] && !p[2])
4618 4618
     {
4619 4619
       VERIFY_PERMISSION (OPT_P_GENERAL);
4620 4620
       if (platform_chdir (p[1]))
... ...
@@ -4625,13 +4630,13 @@ add_option (struct options *options,
4625 4625
       options->cd_dir = p[1];
4626 4626
     }
4627 4627
 #ifdef ENABLE_SELINUX
4628
-  else if (streq (p[0], "setcon") && p[1])
4628
+  else if (streq (p[0], "setcon") && p[1] && !p[2])
4629 4629
     {
4630 4630
       VERIFY_PERMISSION (OPT_P_GENERAL);
4631 4631
       options->selinux_context = p[1];
4632 4632
     }
4633 4633
 #endif
4634
-  else if (streq (p[0], "writepid") && p[1])
4634
+  else if (streq (p[0], "writepid") && p[1] && !p[2])
4635 4635
     {
4636 4636
       VERIFY_PERMISSION (OPT_P_GENERAL);
4637 4637
       options->writepid = p[1];
... ...
@@ -4650,27 +4655,27 @@ add_option (struct options *options,
4650 4650
 	goto err;
4651 4651
       set_user_script (options, &options->down_script, p[1], "down", true);
4652 4652
     }
4653
-  else if (streq (p[0], "down-pre"))
4653
+  else if (streq (p[0], "down-pre") && !p[1])
4654 4654
     {
4655 4655
       VERIFY_PERMISSION (OPT_P_GENERAL);
4656 4656
       options->down_pre = true;
4657 4657
     }
4658
-  else if (streq (p[0], "up-delay"))
4658
+  else if (streq (p[0], "up-delay") && !p[1])
4659 4659
     {
4660 4660
       VERIFY_PERMISSION (OPT_P_GENERAL);
4661 4661
       options->up_delay = true;
4662 4662
     }
4663
-  else if (streq (p[0], "up-restart"))
4663
+  else if (streq (p[0], "up-restart") && !p[1])
4664 4664
     {
4665 4665
       VERIFY_PERMISSION (OPT_P_GENERAL);
4666 4666
       options->up_restart = true;
4667 4667
     }
4668
-  else if (streq (p[0], "syslog"))
4668
+  else if (streq (p[0], "syslog") && !p[2])
4669 4669
     {
4670 4670
       VERIFY_PERMISSION (OPT_P_GENERAL);
4671 4671
       open_syslog (p[1], false);
4672 4672
     }
4673
-  else if (streq (p[0], "daemon"))
4673
+  else if (streq (p[0], "daemon") && !p[2])
4674 4674
     {
4675 4675
       bool didit = false;
4676 4676
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -4688,7 +4693,7 @@ add_option (struct options *options,
4688 4688
 	    }
4689 4689
 	}
4690 4690
     }
4691
-  else if (streq (p[0], "inetd"))
4691
+  else if (streq (p[0], "inetd") && !p[3])
4692 4692
     {
4693 4693
       VERIFY_PERMISSION (OPT_P_GENERAL);
4694 4694
       if (!options->inetd)
... ...
@@ -4743,50 +4748,50 @@ add_option (struct options *options,
4743 4743
 	  open_syslog (name, true);
4744 4744
 	}
4745 4745
     }
4746
-  else if (streq (p[0], "log") && p[1])
4746
+  else if (streq (p[0], "log") && p[1] && !p[2])
4747 4747
     {
4748 4748
       VERIFY_PERMISSION (OPT_P_GENERAL);
4749 4749
       options->log = true;
4750 4750
       redirect_stdout_stderr (p[1], false);
4751 4751
     }
4752
-  else if (streq (p[0], "suppress-timestamps"))
4752
+  else if (streq (p[0], "suppress-timestamps") && !p[1])
4753 4753
     {
4754 4754
       VERIFY_PERMISSION (OPT_P_GENERAL);
4755 4755
       options->suppress_timestamps = true;
4756 4756
       set_suppress_timestamps(true);
4757 4757
     }
4758
-  else if (streq (p[0], "machine-readable-output"))
4758
+  else if (streq (p[0], "machine-readable-output") && !p[1])
4759 4759
     {
4760 4760
       VERIFY_PERMISSION (OPT_P_GENERAL);
4761 4761
       options->machine_readable_output = true;
4762 4762
       set_machine_readable_output(true);
4763 4763
     }
4764
-  else if (streq (p[0], "log-append") && p[1])
4764
+  else if (streq (p[0], "log-append") && p[1] && !p[2])
4765 4765
     {
4766 4766
       VERIFY_PERMISSION (OPT_P_GENERAL);
4767 4767
       options->log = true;
4768 4768
       redirect_stdout_stderr (p[1], true);
4769 4769
     }
4770 4770
 #ifdef ENABLE_MEMSTATS
4771
-  else if (streq (p[0], "memstats") && p[1])
4771
+  else if (streq (p[0], "memstats") && p[1] && !p[2])
4772 4772
     {
4773 4773
       VERIFY_PERMISSION (OPT_P_GENERAL);
4774 4774
       options->memstats_fn = p[1];
4775 4775
     }
4776 4776
 #endif
4777
-  else if (streq (p[0], "mlock"))
4777
+  else if (streq (p[0], "mlock") && !p[1])
4778 4778
     {
4779 4779
       VERIFY_PERMISSION (OPT_P_GENERAL);
4780 4780
       options->mlock = true;
4781 4781
     }
4782 4782
 #if ENABLE_IP_PKTINFO
4783
-  else if (streq (p[0], "multihome"))
4783
+  else if (streq (p[0], "multihome") && !p[1])
4784 4784
     {
4785 4785
       VERIFY_PERMISSION (OPT_P_GENERAL);
4786 4786
       options->sockflags |= SF_USE_IP_PKTINFO;
4787 4787
     }
4788 4788
 #endif
4789
-  else if (streq (p[0], "verb") && p[1])
4789
+  else if (streq (p[0], "verb") && p[1] && !p[2])
4790 4790
     {
4791 4791
       VERIFY_PERMISSION (OPT_P_MESSAGES);
4792 4792
       options->verbosity = positive_atoi (p[1]);
... ...
@@ -4797,17 +4802,17 @@ add_option (struct options *options,
4797 4797
 	    options->verbosity);
4798 4798
 #endif
4799 4799
     }
4800
-  else if (streq (p[0], "mute") && p[1])
4800
+  else if (streq (p[0], "mute") && p[1] && !p[2])
4801 4801
     {
4802 4802
       VERIFY_PERMISSION (OPT_P_MESSAGES);
4803 4803
       options->mute = positive_atoi (p[1]);
4804 4804
     }
4805
-  else if (streq (p[0], "errors-to-stderr"))
4805
+  else if (streq (p[0], "errors-to-stderr") && !p[1])
4806 4806
     {
4807 4807
       VERIFY_PERMISSION (OPT_P_MESSAGES);
4808 4808
       errors_to_stderr();
4809 4809
     }
4810
-  else if (streq (p[0], "status") && p[1])
4810
+  else if (streq (p[0], "status") && p[1] && !p[3])
4811 4811
     {
4812 4812
       VERIFY_PERMISSION (OPT_P_GENERAL);
4813 4813
       options->status_file = p[1];
... ...
@@ -4816,7 +4821,7 @@ add_option (struct options *options,
4816 4816
 	  options->status_file_update_freq = positive_atoi (p[2]);
4817 4817
 	}
4818 4818
     }
4819
-  else if (streq (p[0], "status-version") && p[1])
4819
+  else if (streq (p[0], "status-version") && p[1] && !p[2])
4820 4820
     {
4821 4821
       int version;
4822 4822
 
... ...
@@ -4829,7 +4834,7 @@ add_option (struct options *options,
4829 4829
 	}
4830 4830
       options->status_file_version = version;
4831 4831
     }
4832
-  else if (streq (p[0], "remap-usr1") && p[1])
4832
+  else if (streq (p[0], "remap-usr1") && p[1] && !p[2])
4833 4833
     {
4834 4834
       VERIFY_PERMISSION (OPT_P_GENERAL);
4835 4835
       if (streq (p[1], "SIGHUP"))
... ...
@@ -4842,19 +4847,19 @@ add_option (struct options *options,
4842 4842
 	  goto err;
4843 4843
 	}
4844 4844
     }
4845
-  else if ((streq (p[0], "link-mtu") || streq (p[0], "udp-mtu")) && p[1])
4845
+  else if ((streq (p[0], "link-mtu") || streq (p[0], "udp-mtu")) && p[1] && !p[2])
4846 4846
     {
4847 4847
       VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
4848 4848
       options->ce.link_mtu = positive_atoi (p[1]);
4849 4849
       options->ce.link_mtu_defined = true;
4850 4850
     }
4851
-  else if (streq (p[0], "tun-mtu") && p[1])
4851
+  else if (streq (p[0], "tun-mtu") && p[1] && !p[2])
4852 4852
     {
4853 4853
       VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
4854 4854
       options->ce.tun_mtu = positive_atoi (p[1]);
4855 4855
       options->ce.tun_mtu_defined = true;
4856 4856
     }
4857
-  else if (streq (p[0], "tun-mtu-extra") && p[1])
4857
+  else if (streq (p[0], "tun-mtu-extra") && p[1] && !p[2])
4858 4858
     {
4859 4859
       VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
4860 4860
       options->ce.tun_mtu_extra = positive_atoi (p[1]);
... ...
@@ -4867,41 +4872,41 @@ add_option (struct options *options,
4867 4867
       msg (msglevel, "--mtu-dynamic has been replaced by --fragment");
4868 4868
       goto err;
4869 4869
     }
4870
-  else if (streq (p[0], "fragment") && p[1])
4870
+  else if (streq (p[0], "fragment") && p[1] && !p[2])
4871 4871
     {
4872 4872
 /*      VERIFY_PERMISSION (OPT_P_MTU); */
4873 4873
       VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
4874 4874
       options->ce.fragment = positive_atoi (p[1]);
4875 4875
     }
4876 4876
 #endif
4877
-  else if (streq (p[0], "mtu-disc") && p[1])
4877
+  else if (streq (p[0], "mtu-disc") && p[1] && !p[2])
4878 4878
     {
4879 4879
       VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
4880 4880
       options->ce.mtu_discover_type = translate_mtu_discover_type_name (p[1]);
4881 4881
     }
4882 4882
 #ifdef ENABLE_OCC
4883
-  else if (streq (p[0], "mtu-test"))
4883
+  else if (streq (p[0], "mtu-test") && !p[1])
4884 4884
     {
4885 4885
       VERIFY_PERMISSION (OPT_P_GENERAL);
4886 4886
       options->mtu_test = true;
4887 4887
     }
4888 4888
 #endif
4889
-  else if (streq (p[0], "nice") && p[1])
4889
+  else if (streq (p[0], "nice") && p[1] && !p[2])
4890 4890
     {
4891 4891
       VERIFY_PERMISSION (OPT_P_NICE);
4892 4892
       options->nice = atoi (p[1]);
4893 4893
     }
4894
-  else if (streq (p[0], "rcvbuf") && p[1])
4894
+  else if (streq (p[0], "rcvbuf") && p[1] && !p[2])
4895 4895
     {
4896 4896
       VERIFY_PERMISSION (OPT_P_SOCKBUF);
4897 4897
       options->rcvbuf = positive_atoi (p[1]);
4898 4898
     }
4899
-  else if (streq (p[0], "sndbuf") && p[1])
4899
+  else if (streq (p[0], "sndbuf") && p[1] && !p[2])
4900 4900
     {
4901 4901
       VERIFY_PERMISSION (OPT_P_SOCKBUF);
4902 4902
       options->sndbuf = positive_atoi (p[1]);
4903 4903
     }
4904
-  else if (streq (p[0], "mark") && p[1])
4904
+  else if (streq (p[0], "mark") && p[1] && !p[2])
4905 4905
     {
4906 4906
 #if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK
4907 4907
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -4920,7 +4925,7 @@ add_option (struct options *options,
4920 4920
 	    msg (msglevel, "unknown socket flag: %s", p[j]);	    
4921 4921
 	}
4922 4922
     }
4923
-  else if (streq (p[0], "txqueuelen") && p[1])
4923
+  else if (streq (p[0], "txqueuelen") && p[1] && !p[2])
4924 4924
     {
4925 4925
       VERIFY_PERMISSION (OPT_P_GENERAL);
4926 4926
 #ifdef TARGET_LINUX
... ...
@@ -4930,7 +4935,7 @@ add_option (struct options *options,
4930 4930
       goto err;
4931 4931
 #endif
4932 4932
     }
4933
-  else if (streq (p[0], "shaper") && p[1])
4933
+  else if (streq (p[0], "shaper") && p[1] && !p[2])
4934 4934
     {
4935 4935
 #ifdef ENABLE_FEATURE_SHAPER
4936 4936
       int shaper;
... ...
@@ -4950,23 +4955,23 @@ add_option (struct options *options,
4950 4950
       goto err;
4951 4951
 #endif /* ENABLE_FEATURE_SHAPER */
4952 4952
     }
4953
-  else if (streq (p[0], "port") && p[1])
4953
+  else if (streq (p[0], "port") && p[1] && !p[2])
4954 4954
     {
4955 4955
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4956 4956
       options->ce.local_port = options->ce.remote_port = p[1];
4957 4957
     }
4958
-  else if (streq (p[0], "lport") && p[1])
4958
+  else if (streq (p[0], "lport") && p[1] && !p[2])
4959 4959
     {
4960 4960
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4961 4961
       options->ce.local_port_defined = true;
4962 4962
       options->ce.local_port = p[1];
4963 4963
     }
4964
-  else if (streq (p[0], "rport") && p[1])
4964
+  else if (streq (p[0], "rport") && p[1] && !p[2])
4965 4965
     {
4966 4966
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4967 4967
       options->ce.remote_port = p[1];
4968 4968
     }
4969
-  else if (streq (p[0], "bind"))
4969
+  else if (streq (p[0], "bind") && !p[1])
4970 4970
     {
4971 4971
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4972 4972
       options->ce.bind_defined = true;
... ...
@@ -4974,24 +4979,24 @@ add_option (struct options *options,
4974 4974
           options->ce.bind_ipv6_only=true;
4975 4975
 
4976 4976
     }
4977
-  else if (streq (p[0], "nobind"))
4977
+  else if (streq (p[0], "nobind") && !p[1])
4978 4978
     {
4979 4979
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
4980 4980
       options->ce.bind_local = false;
4981 4981
     }
4982
-  else if (streq (p[0], "fast-io"))
4982
+  else if (streq (p[0], "fast-io") && !p[1])
4983 4983
     {
4984 4984
       VERIFY_PERMISSION (OPT_P_GENERAL);
4985 4985
       options->fast_io = true;
4986 4986
     }
4987
-  else if (streq (p[0], "inactive") && p[1])
4987
+  else if (streq (p[0], "inactive") && p[1] && !p[3])
4988 4988
     {
4989 4989
       VERIFY_PERMISSION (OPT_P_TIMER);
4990 4990
       options->inactivity_timeout = positive_atoi (p[1]);
4991 4991
       if (p[2])
4992 4992
 	options->inactivity_minimum_bytes = positive_atoi (p[2]);
4993 4993
     }
4994
-  else if (streq (p[0], "proto") && p[1])
4994
+  else if (streq (p[0], "proto") && p[1] && !p[2])
4995 4995
     {
4996 4996
       int proto;
4997 4997
       sa_family_t af;
... ...
@@ -5008,7 +5013,7 @@ add_option (struct options *options,
5008 5008
       options->ce.proto = proto;
5009 5009
       options->ce.af = af;
5010 5010
     }
5011
-  else if (streq (p[0], "proto-force") && p[1])
5011
+  else if (streq (p[0], "proto-force") && p[1] && !p[2])
5012 5012
     {
5013 5013
       int proto_force;
5014 5014
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -5020,7 +5025,7 @@ add_option (struct options *options,
5020 5020
 	}
5021 5021
       options->proto_force = proto_force;
5022 5022
     }
5023
-  else if (streq (p[0], "http-proxy") && p[1])
5023
+  else if (streq (p[0], "http-proxy") && p[1] && !p[5])
5024 5024
     {
5025 5025
       struct http_proxy_options *ho;
5026 5026
 
... ...
@@ -5064,14 +5069,14 @@ add_option (struct options *options,
5064 5064
 	  ho->auth_method_string = "none";
5065 5065
 	}
5066 5066
     }
5067
-  else if (streq (p[0], "http-proxy-retry"))
5067
+  else if (streq (p[0], "http-proxy-retry") && !p[1])
5068 5068
     {
5069 5069
       struct http_proxy_options *ho;
5070 5070
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
5071 5071
       ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc);
5072 5072
       ho->retry = true;
5073 5073
     }
5074
-  else if (streq (p[0], "http-proxy-timeout") && p[1])
5074
+  else if (streq (p[0], "http-proxy-timeout") && p[1] && !p[2])
5075 5075
     {
5076 5076
       struct http_proxy_options *ho;
5077 5077
 
... ...
@@ -5079,18 +5084,18 @@ add_option (struct options *options,
5079 5079
       ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc);
5080 5080
       ho->timeout = positive_atoi (p[1]);
5081 5081
     }
5082
-  else if (streq (p[0], "http-proxy-option") && p[1])
5082
+  else if (streq (p[0], "http-proxy-option") && p[1] && !p[4])
5083 5083
     {
5084 5084
       struct http_proxy_options *ho;
5085 5085
 
5086 5086
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
5087 5087
       ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc);
5088 5088
 
5089
-      if (streq (p[1], "VERSION") && p[2])
5089
+      if (streq (p[1], "VERSION") && p[2] && !p[3])
5090 5090
 	{
5091 5091
 	  ho->http_version = p[2];
5092 5092
 	}
5093
-      else if (streq (p[1], "AGENT") && p[2])
5093
+      else if (streq (p[1], "AGENT") && p[2] && !p[3])
5094 5094
 	{
5095 5095
 	  ho->user_agent = p[2];
5096 5096
 	}
... ...
@@ -5123,10 +5128,10 @@ add_option (struct options *options,
5123 5123
 	}
5124 5124
       else
5125 5125
 	{
5126
-	  msg (msglevel, "Bad http-proxy-option or missing parameter: '%s'", p[1]);
5126
+	  msg (msglevel, "Bad http-proxy-option or missing or extra parameter: '%s'", p[1]);
5127 5127
 	}
5128 5128
     }
5129
-  else if (streq (p[0], "socks-proxy") && p[1])
5129
+  else if (streq (p[0], "socks-proxy") && p[1] && !p[4])
5130 5130
     {
5131 5131
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
5132 5132
 
... ...
@@ -5141,41 +5146,41 @@ add_option (struct options *options,
5141 5141
       options->ce.socks_proxy_server = p[1];
5142 5142
       options->ce.socks_proxy_authfile = p[3]; /* might be NULL */
5143 5143
     }
5144
-  else if (streq (p[0], "socks-proxy-retry"))
5144
+  else if (streq (p[0], "socks-proxy-retry") && !p[1])
5145 5145
     {
5146 5146
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
5147 5147
       options->ce.socks_proxy_retry = true;
5148 5148
     }
5149
-  else if (streq (p[0], "keepalive") && p[1] && p[2])
5149
+  else if (streq (p[0], "keepalive") && p[1] && p[2] && !p[3])
5150 5150
     {
5151 5151
       VERIFY_PERMISSION (OPT_P_GENERAL);
5152 5152
       options->keepalive_ping = atoi (p[1]);
5153 5153
       options->keepalive_timeout = atoi (p[2]);
5154 5154
     }
5155
-  else if (streq (p[0], "ping") && p[1])
5155
+  else if (streq (p[0], "ping") && p[1] && !p[2])
5156 5156
     {
5157 5157
       VERIFY_PERMISSION (OPT_P_TIMER);
5158 5158
       options->ping_send_timeout = positive_atoi (p[1]);
5159 5159
     }
5160
-  else if (streq (p[0], "ping-exit") && p[1])
5160
+  else if (streq (p[0], "ping-exit") && p[1] && !p[2])
5161 5161
     {
5162 5162
       VERIFY_PERMISSION (OPT_P_TIMER);
5163 5163
       options->ping_rec_timeout = positive_atoi (p[1]);
5164 5164
       options->ping_rec_timeout_action = PING_EXIT;
5165 5165
     }
5166
-  else if (streq (p[0], "ping-restart") && p[1])
5166
+  else if (streq (p[0], "ping-restart") && p[1] && !p[2])
5167 5167
     {
5168 5168
       VERIFY_PERMISSION (OPT_P_TIMER);
5169 5169
       options->ping_rec_timeout = positive_atoi (p[1]);
5170 5170
       options->ping_rec_timeout_action = PING_RESTART;
5171 5171
     }
5172
-  else if (streq (p[0], "ping-timer-rem"))
5172
+  else if (streq (p[0], "ping-timer-rem") && !p[1])
5173 5173
     {
5174 5174
       VERIFY_PERMISSION (OPT_P_TIMER);
5175 5175
       options->ping_timer_remote = true;
5176 5176
     }
5177 5177
 #ifdef ENABLE_OCC
5178
-  else if (streq (p[0], "explicit-exit-notify"))
5178
+  else if (streq (p[0], "explicit-exit-notify") && !p[2])
5179 5179
     {
5180 5180
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION|OPT_P_EXPLICIT_NOTIFY);
5181 5181
       if (p[1])
... ...
@@ -5188,35 +5193,35 @@ add_option (struct options *options,
5188 5188
 	}
5189 5189
     }
5190 5190
 #endif
5191
-  else if (streq (p[0], "persist-tun"))
5191
+  else if (streq (p[0], "persist-tun") && !p[1])
5192 5192
     {
5193 5193
       VERIFY_PERMISSION (OPT_P_PERSIST);
5194 5194
       options->persist_tun = true;
5195 5195
     }
5196
-  else if (streq (p[0], "persist-key"))
5196
+  else if (streq (p[0], "persist-key") && !p[1])
5197 5197
     {
5198 5198
       VERIFY_PERMISSION (OPT_P_PERSIST);
5199 5199
       options->persist_key = true;
5200 5200
     }
5201
-  else if (streq (p[0], "persist-local-ip"))
5201
+  else if (streq (p[0], "persist-local-ip") && !p[1])
5202 5202
     {
5203 5203
       VERIFY_PERMISSION (OPT_P_PERSIST_IP);
5204 5204
       options->persist_local_ip = true;
5205 5205
     }
5206
-  else if (streq (p[0], "persist-remote-ip"))
5206
+  else if (streq (p[0], "persist-remote-ip") && !p[1])
5207 5207
     {
5208 5208
       VERIFY_PERMISSION (OPT_P_PERSIST_IP);
5209 5209
       options->persist_remote_ip = true;
5210 5210
     }
5211 5211
 #ifdef ENABLE_CLIENT_NAT
5212
-  else if (streq (p[0], "client-nat") && p[1] && p[2] && p[3] && p[4])
5212
+  else if (streq (p[0], "client-nat") && p[1] && p[2] && p[3] && p[4] && !p[5])
5213 5213
     {
5214 5214
       VERIFY_PERMISSION (OPT_P_ROUTE);
5215 5215
       cnol_check_alloc (options);
5216 5216
       add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel);
5217 5217
     }
5218 5218
 #endif
5219
-  else if (streq (p[0], "route") && p[1])
5219
+  else if (streq (p[0], "route") && p[1] && !p[5])
5220 5220
     {
5221 5221
       VERIFY_PERMISSION (OPT_P_ROUTE);
5222 5222
       rol_check_alloc (options);
... ...
@@ -5240,7 +5245,7 @@ add_option (struct options *options,
5240 5240
 	}
5241 5241
       add_route_to_option_list (options->routes, p[1], p[2], p[3], p[4]);
5242 5242
     }
5243
-  else if (streq (p[0], "route-ipv6") && p[1])
5243
+  else if (streq (p[0], "route-ipv6") && p[1] && !p[4])
5244 5244
     {
5245 5245
       VERIFY_PERMISSION (OPT_P_ROUTE);
5246 5246
       rol6_check_alloc (options);
... ...
@@ -5260,14 +5265,14 @@ add_option (struct options *options,
5260 5260
 	}
5261 5261
       add_route_ipv6_to_option_list (options->routes_ipv6, p[1], p[2], p[3]);
5262 5262
     }
5263
-  else if (streq (p[0], "max-routes"))
5263
+  else if (streq (p[0], "max-routes") && !p[2])
5264 5264
     {
5265 5265
       msg (M_WARN, "DEPRECATED OPTION: --max-routes option ignored."
5266 5266
 	   "The number of routes is unlimited as of version 2.4. "
5267 5267
 	   "This option will be removed in a future version, "
5268 5268
 	   "please remove it from your configuration.");
5269 5269
     }
5270
-  else if (streq (p[0], "route-gateway") && p[1])
5270
+  else if (streq (p[0], "route-gateway") && p[1] && !p[2])
5271 5271
     {
5272 5272
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
5273 5273
       if (streq (p[1], "dhcp"))
... ...
@@ -5287,12 +5292,12 @@ add_option (struct options *options,
5287 5287
 	    }
5288 5288
 	}
5289 5289
     }
5290
-  else if (streq (p[0], "route-metric") && p[1])
5290
+  else if (streq (p[0], "route-metric") && p[1] && !p[2])
5291 5291
     {
5292 5292
       VERIFY_PERMISSION (OPT_P_ROUTE);
5293 5293
       options->route_default_metric = positive_atoi (p[1]);
5294 5294
     }
5295
-  else if (streq (p[0], "route-delay"))
5295
+  else if (streq (p[0], "route-delay") && !p[3])
5296 5296
     {
5297 5297
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
5298 5298
       options->route_delay_defined = true;
... ...
@@ -5326,17 +5331,17 @@ add_option (struct options *options,
5326 5326
 		       p[1],
5327 5327
 		       "route-pre-down", true);
5328 5328
     }
5329
-  else if (streq (p[0], "route-noexec"))
5329
+  else if (streq (p[0], "route-noexec") && !p[1])
5330 5330
     {
5331 5331
       VERIFY_PERMISSION (OPT_P_SCRIPT);
5332 5332
       options->route_noexec = true;
5333 5333
     }
5334
-  else if (streq (p[0], "route-nopull"))
5334
+  else if (streq (p[0], "route-nopull") && !p[1])
5335 5335
     {
5336 5336
       VERIFY_PERMISSION (OPT_P_GENERAL);
5337 5337
       options->route_nopull = true;
5338 5338
     }
5339
-  else if (streq (p[0], "allow-pull-fqdn"))
5339
+  else if (streq (p[0], "allow-pull-fqdn") && !p[1])
5340 5340
     {
5341 5341
       VERIFY_PERMISSION (OPT_P_GENERAL);
5342 5342
       options->allow_pull_fqdn = true;
... ...
@@ -5370,15 +5375,15 @@ add_option (struct options *options,
5370 5370
 	}
5371 5371
       options->routes->flags |= RG_ENABLE;
5372 5372
     }
5373
-  else if (streq (p[0], "remote-random-hostname"))
5373
+  else if (streq (p[0], "remote-random-hostname") && !p[1])
5374 5374
     {
5375 5375
       VERIFY_PERMISSION (OPT_P_GENERAL);
5376 5376
       options->sockflags |= SF_HOST_RANDOMIZE;
5377 5377
     }
5378
-  else if (streq (p[0], "setenv") && p[1])
5378
+  else if (streq (p[0], "setenv") && p[1] && !p[3])
5379 5379
     {
5380 5380
       VERIFY_PERMISSION (OPT_P_GENERAL);
5381
-      if (streq (p[1], "REMOTE_RANDOM_HOSTNAME"))
5381
+      if (streq (p[1], "REMOTE_RANDOM_HOSTNAME") && !p[2])
5382 5382
 	{
5383 5383
 	  options->sockflags |= SF_HOST_RANDOMIZE;
5384 5384
 	}
... ...
@@ -5388,7 +5393,7 @@ add_option (struct options *options,
5388 5388
 	  goto err;
5389 5389
 	}
5390 5390
 #ifdef ENABLE_PUSH_PEER_INFO
5391
-      else if (streq (p[1], "PUSH_PEER_INFO"))
5391
+      else if (streq (p[1], "PUSH_PEER_INFO") && !p[2])
5392 5392
 	{
5393 5393
 	  options->push_peer_info = true;
5394 5394
 	}
... ...
@@ -5409,17 +5414,17 @@ add_option (struct options *options,
5409 5409
 	  setenv_str (es, p[1], p[2] ? p[2] : "");
5410 5410
 	}
5411 5411
     }
5412
-  else if (streq (p[0], "setenv-safe") && p[1])
5412
+  else if (streq (p[0], "setenv-safe") && p[1] && !p[3])
5413 5413
     {
5414 5414
       VERIFY_PERMISSION (OPT_P_SETENV);
5415 5415
       setenv_str_safe (es, p[1], p[2] ? p[2] : "");
5416 5416
     }
5417
-  else if (streq (p[0], "script-security") && p[1])
5417
+  else if (streq (p[0], "script-security") && p[1] && !p[2])
5418 5418
     {
5419 5419
       VERIFY_PERMISSION (OPT_P_GENERAL);
5420 5420
       script_security = atoi (p[1]);
5421 5421
     }
5422
-  else if (streq (p[0], "mssfix"))
5422
+  else if (streq (p[0], "mssfix") && !p[2])
5423 5423
     {
5424 5424
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
5425 5425
       if (p[1])
... ...
@@ -5431,7 +5436,7 @@ add_option (struct options *options,
5431 5431
 
5432 5432
     }
5433 5433
 #ifdef ENABLE_OCC
5434
-  else if (streq (p[0], "disable-occ"))
5434
+  else if (streq (p[0], "disable-occ") && !p[1])
5435 5435
     {
5436 5436
       VERIFY_PERMISSION (OPT_P_GENERAL);
5437 5437
       options->occ = false;
... ...
@@ -5439,7 +5444,7 @@ add_option (struct options *options,
5439 5439
 #endif
5440 5440
 #if P2MP
5441 5441
 #if P2MP_SERVER
5442
-  else if (streq (p[0], "server") && p[1] && p[2])
5442
+  else if (streq (p[0], "server") && p[1] && p[2] && !p[4])
5443 5443
     {
5444 5444
       const int lev = M_WARN;
5445 5445
       bool error = false;
... ...
@@ -5468,7 +5473,7 @@ add_option (struct options *options,
5468 5468
 	    }
5469 5469
 	}
5470 5470
     }
5471
-  else if (streq (p[0], "server-ipv6") && p[1] )
5471
+  else if (streq (p[0], "server-ipv6") && p[1] && !p[3])
5472 5472
     {
5473 5473
       const int lev = M_WARN;
5474 5474
       struct in6_addr network;
... ...
@@ -5495,7 +5500,7 @@ add_option (struct options *options,
5495 5495
 	  goto err;
5496 5496
 	}
5497 5497
     }
5498
-  else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4])
5498
+  else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4] && !p[5])
5499 5499
     {
5500 5500
       const int lev = M_WARN;
5501 5501
       bool error = false;
... ...
@@ -5517,7 +5522,7 @@ add_option (struct options *options,
5517 5517
       options->server_bridge_pool_start = pool_start;
5518 5518
       options->server_bridge_pool_end = pool_end;
5519 5519
     }
5520
-  else if (streq (p[0], "server-bridge") && p[1] && streq (p[1], "nogw"))
5520
+  else if (streq (p[0], "server-bridge") && p[1] && streq (p[1], "nogw") && !p[2])
5521 5521
     {
5522 5522
       VERIFY_PERMISSION (OPT_P_GENERAL);
5523 5523
       options->server_bridge_proxy_dhcp = true;
... ...
@@ -5528,17 +5533,17 @@ add_option (struct options *options,
5528 5528
       VERIFY_PERMISSION (OPT_P_GENERAL);
5529 5529
       options->server_bridge_proxy_dhcp = true;
5530 5530
     }
5531
-  else if (streq (p[0], "push") && p[1])
5531
+  else if (streq (p[0], "push") && p[1] && !p[2])
5532 5532
     {
5533 5533
       VERIFY_PERMISSION (OPT_P_PUSH);
5534 5534
       push_options (options, &p[1], msglevel, &options->gc);
5535 5535
     }
5536
-  else if (streq (p[0], "push-reset"))
5536
+  else if (streq (p[0], "push-reset") && !p[1])
5537 5537
     {
5538 5538
       VERIFY_PERMISSION (OPT_P_INSTANCE);
5539 5539
       push_reset (options);
5540 5540
     }
5541
-  else if (streq (p[0], "ifconfig-pool") && p[1] && p[2])
5541
+  else if (streq (p[0], "ifconfig-pool") && p[1] && p[2] && !p[4])
5542 5542
     {
5543 5543
       const int lev = M_WARN;
5544 5544
       bool error = false;
... ...
@@ -5565,7 +5570,7 @@ add_option (struct options *options,
5565 5565
       if (netmask)
5566 5566
 	options->ifconfig_pool_netmask = netmask;
5567 5567
     }
5568
-  else if (streq (p[0], "ifconfig-pool-persist") && p[1])
5568
+  else if (streq (p[0], "ifconfig-pool-persist") && p[1] && !p[3])
5569 5569
     {
5570 5570
       VERIFY_PERMISSION (OPT_P_GENERAL);
5571 5571
       options->ifconfig_pool_persist_filename = p[1];
... ...
@@ -5574,12 +5579,12 @@ add_option (struct options *options,
5574 5574
 	  options->ifconfig_pool_persist_refresh_freq = positive_atoi (p[2]);
5575 5575
 	}
5576 5576
     }
5577
-  else if (streq (p[0], "ifconfig-pool-linear"))
5577
+  else if (streq (p[0], "ifconfig-pool-linear") && !p[1])
5578 5578
     {
5579 5579
       VERIFY_PERMISSION (OPT_P_GENERAL);
5580 5580
       options->topology = TOP_P2P;
5581 5581
     }
5582
-  else if (streq (p[0], "ifconfig-ipv6-pool") && p[1] )
5582
+  else if (streq (p[0], "ifconfig-ipv6-pool") && p[1] && !p[2])
5583 5583
     {
5584 5584
       const int lev = M_WARN;
5585 5585
       struct in6_addr network;
... ...
@@ -5601,7 +5606,7 @@ add_option (struct options *options,
5601 5601
       options->ifconfig_ipv6_pool_base = network;
5602 5602
       options->ifconfig_ipv6_pool_netbits = netbits;
5603 5603
     }
5604
-  else if (streq (p[0], "hash-size") && p[1] && p[2])
5604
+  else if (streq (p[0], "hash-size") && p[1] && p[2] && !p[3])
5605 5605
     {
5606 5606
       int real, virtual;
5607 5607
 
... ...
@@ -5616,7 +5621,7 @@ add_option (struct options *options,
5616 5616
       options->real_hash_size = real;
5617 5617
       options->virtual_hash_size = real;
5618 5618
     }
5619
-  else if (streq (p[0], "connect-freq") && p[1] && p[2])
5619
+  else if (streq (p[0], "connect-freq") && p[1] && p[2] && !p[3])
5620 5620
     {
5621 5621
       int cf_max, cf_per;
5622 5622
 
... ...
@@ -5631,7 +5636,7 @@ add_option (struct options *options,
5631 5631
       options->cf_max = cf_max;
5632 5632
       options->cf_per = cf_per;
5633 5633
     }
5634
-  else if (streq (p[0], "max-clients") && p[1])
5634
+  else if (streq (p[0], "max-clients") && p[1] && !p[2])
5635 5635
     {
5636 5636
       int max_clients;
5637 5637
 
... ...
@@ -5644,27 +5649,27 @@ add_option (struct options *options,
5644 5644
 	}
5645 5645
       options->max_clients = max_clients;
5646 5646
     }
5647
-  else if (streq (p[0], "max-routes-per-client") && p[1])
5647
+  else if (streq (p[0], "max-routes-per-client") && p[1] && !p[2])
5648 5648
     {
5649 5649
       VERIFY_PERMISSION (OPT_P_INHERIT);
5650 5650
       options->max_routes_per_client = max_int (atoi (p[1]), 1);
5651 5651
     }
5652
-  else if (streq (p[0], "client-cert-not-required"))
5652
+  else if (streq (p[0], "client-cert-not-required") && !p[1])
5653 5653
     {
5654 5654
       VERIFY_PERMISSION (OPT_P_GENERAL);
5655 5655
       options->ssl_flags |= SSLF_CLIENT_CERT_NOT_REQUIRED;
5656 5656
     }
5657
-  else if (streq (p[0], "username-as-common-name"))
5657
+  else if (streq (p[0], "username-as-common-name") && !p[1])
5658 5658
     {
5659 5659
       VERIFY_PERMISSION (OPT_P_GENERAL);
5660 5660
       options->ssl_flags |= SSLF_USERNAME_AS_COMMON_NAME;
5661 5661
     }
5662
-  else if (streq (p[0], "auth-user-pass-optional"))
5662
+  else if (streq (p[0], "auth-user-pass-optional") && !p[1])
5663 5663
     {
5664 5664
       VERIFY_PERMISSION (OPT_P_GENERAL);
5665 5665
       options->ssl_flags |= SSLF_AUTH_USER_PASS_OPTIONAL;
5666 5666
     }
5667
-  else if (streq (p[0], "opt-verify"))
5667
+  else if (streq (p[0], "opt-verify") && !p[1])
5668 5668
     {
5669 5669
       VERIFY_PERMISSION (OPT_P_GENERAL);
5670 5670
       options->ssl_flags |= SSLF_OPT_VERIFY;
... ...
@@ -5719,22 +5724,22 @@ add_option (struct options *options,
5719 5719
       set_user_script (options, &options->learn_address_script,
5720 5720
 		       p[1], "learn-address", true);
5721 5721
     }
5722
-  else if (streq (p[0], "tmp-dir") && p[1])
5722
+  else if (streq (p[0], "tmp-dir") && p[1] && !p[2])
5723 5723
     {
5724 5724
       VERIFY_PERMISSION (OPT_P_GENERAL);
5725 5725
       options->tmp_dir = p[1];
5726 5726
     }
5727
-  else if (streq (p[0], "client-config-dir") && p[1])
5727
+  else if (streq (p[0], "client-config-dir") && p[1] && !p[2])
5728 5728
     {
5729 5729
       VERIFY_PERMISSION (OPT_P_GENERAL);
5730 5730
       options->client_config_dir = p[1];
5731 5731
     }
5732
-  else if (streq (p[0], "ccd-exclusive"))
5732
+  else if (streq (p[0], "ccd-exclusive") && !p[1])
5733 5733
     {
5734 5734
       VERIFY_PERMISSION (OPT_P_GENERAL);
5735 5735
       options->ccd_exclusive = true;
5736 5736
     }
5737
-  else if (streq (p[0], "bcast-buffers") && p[1])
5737
+  else if (streq (p[0], "bcast-buffers") && p[1] && !p[2])
5738 5738
     {
5739 5739
       int n_bcast_buf;
5740 5740
 
... ...
@@ -5744,7 +5749,7 @@ add_option (struct options *options,
5744 5744
 	msg (msglevel, "--bcast-buffers parameter must be > 0");
5745 5745
       options->n_bcast_buf = n_bcast_buf;
5746 5746
     }
5747
-  else if (streq (p[0], "tcp-queue-limit") && p[1])
5747
+  else if (streq (p[0], "tcp-queue-limit") && p[1] && !p[2])
5748 5748
     {
5749 5749
       int tcp_queue_limit;
5750 5750
 
... ...
@@ -5755,7 +5760,7 @@ add_option (struct options *options,
5755 5755
       options->tcp_queue_limit = tcp_queue_limit;
5756 5756
     }
5757 5757
 #if PORT_SHARE
5758
-  else if (streq (p[0], "port-share") && p[1] && p[2])
5758
+  else if (streq (p[0], "port-share") && p[1] && p[2] && !p[4])
5759 5759
     {
5760 5760
       VERIFY_PERMISSION (OPT_P_GENERAL);
5761 5761
       options->port_share_host = p[1];
... ...
@@ -5763,17 +5768,17 @@ add_option (struct options *options,
5763 5763
       options->port_share_journal_dir = p[3];
5764 5764
     }
5765 5765
 #endif
5766
-  else if (streq (p[0], "client-to-client"))
5766
+  else if (streq (p[0], "client-to-client") && !p[1])
5767 5767
     {
5768 5768
       VERIFY_PERMISSION (OPT_P_GENERAL);
5769 5769
       options->enable_c2c = true;
5770 5770
     }
5771
-  else if (streq (p[0], "duplicate-cn"))
5771
+  else if (streq (p[0], "duplicate-cn") && !p[1])
5772 5772
     {
5773 5773
       VERIFY_PERMISSION (OPT_P_GENERAL);
5774 5774
       options->duplicate_cn = true;
5775 5775
     }
5776
-  else if (streq (p[0], "iroute") && p[1])
5776
+  else if (streq (p[0], "iroute") && p[1] && !p[3])
5777 5777
     {
5778 5778
       const char *netmask = NULL;
5779 5779
 
... ...
@@ -5784,12 +5789,12 @@ add_option (struct options *options,
5784 5784
 	}
5785 5785
       option_iroute (options, p[1], netmask, msglevel);
5786 5786
     }
5787
-  else if (streq (p[0], "iroute-ipv6") && p[1])
5787
+  else if (streq (p[0], "iroute-ipv6") && p[1] && !p[2])
5788 5788
     {
5789 5789
       VERIFY_PERMISSION (OPT_P_INSTANCE);
5790 5790
       option_iroute_ipv6 (options, p[1], msglevel);
5791 5791
     }
5792
-  else if (streq (p[0], "ifconfig-push") && p[1] && p[2])
5792
+  else if (streq (p[0], "ifconfig-push") && p[1] && p[2] && !p[4])
5793 5793
     {
5794 5794
       in_addr_t local, remote_netmask;
5795 5795
 
... ...
@@ -5812,7 +5817,7 @@ add_option (struct options *options,
5812 5812
 	  goto err;
5813 5813
 	}
5814 5814
     }
5815
-  else if (streq (p[0], "ifconfig-push-constraint") && p[1] && p[2])
5815
+  else if (streq (p[0], "ifconfig-push-constraint") && p[1] && p[2] && !p[3])
5816 5816
     {
5817 5817
       in_addr_t network, netmask;
5818 5818
 
... ...
@@ -5831,7 +5836,7 @@ add_option (struct options *options,
5831 5831
 	  goto err;
5832 5832
 	}
5833 5833
     }
5834
-  else if (streq (p[0], "ifconfig-ipv6-push") && p[1] )
5834
+  else if (streq (p[0], "ifconfig-ipv6-push") && p[1] && !p[3])
5835 5835
     {
5836 5836
       struct in6_addr local, remote;
5837 5837
       unsigned int netbits;
... ...
@@ -5868,17 +5873,17 @@ add_option (struct options *options,
5868 5868
       options->push_ifconfig_ipv6_netbits = netbits;
5869 5869
       options->push_ifconfig_ipv6_remote = remote;
5870 5870
     }
5871
-  else if (streq (p[0], "disable"))
5871
+  else if (streq (p[0], "disable") && !p[1])
5872 5872
     {
5873 5873
       VERIFY_PERMISSION (OPT_P_INSTANCE);
5874 5874
       options->disable = true;
5875 5875
     }
5876
-  else if (streq (p[0], "tcp-nodelay"))
5876
+  else if (streq (p[0], "tcp-nodelay") && !p[1])
5877 5877
     {
5878 5878
       VERIFY_PERMISSION (OPT_P_GENERAL);
5879 5879
       options->server_flags |= SF_TCP_NODELAY_HELPER;
5880 5880
     }
5881
-  else if (streq (p[0], "stale-routes-check") && p[1])
5881
+  else if (streq (p[0], "stale-routes-check") && p[1] && !p[3])
5882 5882
     {
5883 5883
       int ageing_time, check_interval;
5884 5884
 
... ...
@@ -5899,27 +5904,27 @@ add_option (struct options *options,
5899 5899
     }
5900 5900
 #endif /* P2MP_SERVER */
5901 5901
 
5902
-  else if (streq (p[0], "client"))
5902
+  else if (streq (p[0], "client") && !p[1])
5903 5903
     {
5904 5904
       VERIFY_PERMISSION (OPT_P_GENERAL);
5905 5905
       options->client = true;
5906 5906
     }
5907
-  else if (streq (p[0], "pull"))
5907
+  else if (streq (p[0], "pull") && !p[1])
5908 5908
     {
5909 5909
       VERIFY_PERMISSION (OPT_P_GENERAL);
5910 5910
       options->pull = true;
5911 5911
     }
5912
-  else if (streq (p[0], "push-continuation") && p[1])
5912
+  else if (streq (p[0], "push-continuation") && p[1] && !p[2])
5913 5913
     {
5914 5914
       VERIFY_PERMISSION (OPT_P_PULL_MODE);
5915 5915
       options->push_continuation = atoi(p[1]);
5916 5916
     }
5917
-  else if (streq (p[0], "server-poll-timeout") && p[1])
5917
+  else if (streq (p[0], "server-poll-timeout") && p[1] && !p[2])
5918 5918
     {
5919 5919
       VERIFY_PERMISSION (OPT_P_GENERAL);
5920 5920
       options->server_poll_timeout = positive_atoi(p[1]);
5921 5921
     }
5922
-  else if (streq (p[0], "auth-user-pass"))
5922
+  else if (streq (p[0], "auth-user-pass") && !p[2])
5923 5923
     {
5924 5924
       VERIFY_PERMISSION (OPT_P_GENERAL);
5925 5925
       if (p[1])
... ...
@@ -5929,13 +5934,13 @@ add_option (struct options *options,
5929 5929
       else
5930 5930
 	options->auth_user_pass_file = "stdin";
5931 5931
     }
5932
-  else if (streq (p[0], "auth-retry") && p[1])
5932
+  else if (streq (p[0], "auth-retry") && p[1] && !p[2])
5933 5933
     {
5934 5934
       VERIFY_PERMISSION (OPT_P_GENERAL);
5935 5935
       auth_retry_set (msglevel, p[1]);
5936 5936
     }
5937 5937
 #ifdef ENABLE_CLIENT_CR
5938
-  else if (streq (p[0], "static-challenge") && p[1] && p[2])
5938
+  else if (streq (p[0], "static-challenge") && p[1] && p[2] && !p[3])
5939 5939
     {
5940 5940
       VERIFY_PERMISSION (OPT_P_GENERAL);
5941 5941
       options->sc_info.challenge_text = p[1];
... ...
@@ -5945,7 +5950,7 @@ add_option (struct options *options,
5945 5945
 #endif
5946 5946
 #endif
5947 5947
 #ifdef WIN32
5948
-  else if (streq (p[0], "win-sys") && p[1])
5948
+  else if (streq (p[0], "win-sys") && p[1] && !p[2])
5949 5949
     {
5950 5950
       VERIFY_PERMISSION (OPT_P_GENERAL);
5951 5951
       if (streq (p[1], "env"))
... ...
@@ -5955,7 +5960,7 @@ add_option (struct options *options,
5955 5955
       else
5956 5956
 	set_win_sys_path (p[1], es);
5957 5957
     }
5958
-  else if (streq (p[0], "route-method") && p[1])
5958
+  else if (streq (p[0], "route-method") && p[1] && !p[2])
5959 5959
     {
5960 5960
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
5961 5961
       if (streq (p[1], "adaptive"))
... ...
@@ -5970,7 +5975,7 @@ add_option (struct options *options,
5970 5970
 	  goto err;
5971 5971
 	}
5972 5972
     }
5973
-  else if (streq (p[0], "ip-win32") && p[1])
5973
+  else if (streq (p[0], "ip-win32") && p[1] && !p[4])
5974 5974
     {
5975 5975
       const int index = ascii2ipset (p[1]);
5976 5976
       struct tuntap_options *to = &options->tuntap_options;
... ...
@@ -6026,7 +6031,7 @@ add_option (struct options *options,
6026 6026
     }
6027 6027
 #endif
6028 6028
 #if defined(WIN32) || defined(TARGET_ANDROID)
6029
-  else if (streq (p[0], "dhcp-option") && p[1])
6029
+  else if (streq (p[0], "dhcp-option") && p[1] && !p[3])
6030 6030
     {
6031 6031
       struct tuntap_options *o = &options->tuntap_options;
6032 6032
       VERIFY_PERMISSION (OPT_P_IPWIN32);
... ...
@@ -6066,38 +6071,38 @@ add_option (struct options *options,
6066 6066
 	{
6067 6067
 	  dhcp_option_address_parse ("NBDD", p[2], o->nbdd, &o->nbdd_len, msglevel);
6068 6068
 	}
6069
-      else if (streq (p[1], "DISABLE-NBT"))
6069
+      else if (streq (p[1], "DISABLE-NBT") && !p[2])
6070 6070
 	{
6071 6071
 	  o->disable_nbt = 1;
6072 6072
 	}
6073 6073
       else
6074 6074
 	{
6075
-	  msg (msglevel, "--dhcp-option: unknown option type '%s' or missing parameter", p[1]);
6075
+	  msg (msglevel, "--dhcp-option: unknown option type '%s' or missing or unknown parameter", p[1]);
6076 6076
 	  goto err;
6077 6077
 	}
6078 6078
       o->dhcp_options = true;
6079 6079
     }
6080 6080
 #endif
6081 6081
 #ifdef WIN32
6082
-  else if (streq (p[0], "show-adapters"))
6082
+  else if (streq (p[0], "show-adapters") && !p[1])
6083 6083
     {
6084 6084
       VERIFY_PERMISSION (OPT_P_GENERAL);
6085 6085
       show_tap_win_adapters (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX);
6086 6086
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
6087 6087
     }
6088
-  else if (streq (p[0], "show-net"))
6088
+  else if (streq (p[0], "show-net") && !p[1])
6089 6089
     {
6090 6090
       VERIFY_PERMISSION (OPT_P_GENERAL);
6091 6091
       show_routes (M_INFO|M_NOPREFIX);
6092 6092
       show_adapters (M_INFO|M_NOPREFIX);
6093 6093
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
6094 6094
     }
6095
-  else if (streq (p[0], "show-net-up"))
6095
+  else if (streq (p[0], "show-net-up") && !p[1])
6096 6096
     {
6097 6097
       VERIFY_PERMISSION (OPT_P_UP);
6098 6098
       options->show_net_up = true;
6099 6099
     }
6100
-  else if (streq (p[0], "tap-sleep") && p[1])
6100
+  else if (streq (p[0], "tap-sleep") && p[1] && !p[2])
6101 6101
     {
6102 6102
       int s;
6103 6103
       VERIFY_PERMISSION (OPT_P_IPWIN32);
... ...
@@ -6109,22 +6114,22 @@ add_option (struct options *options,
6109 6109
 	}
6110 6110
       options->tuntap_options.tap_sleep = s;
6111 6111
     }
6112
-  else if (streq (p[0], "dhcp-renew"))
6112
+  else if (streq (p[0], "dhcp-renew") && !p[1])
6113 6113
     {
6114 6114
       VERIFY_PERMISSION (OPT_P_IPWIN32);
6115 6115
       options->tuntap_options.dhcp_renew = true;
6116 6116
     }
6117
-  else if (streq (p[0], "dhcp-pre-release"))
6117
+  else if (streq (p[0], "dhcp-pre-release") && !p[1])
6118 6118
     {
6119 6119
       VERIFY_PERMISSION (OPT_P_IPWIN32);
6120 6120
       options->tuntap_options.dhcp_pre_release = true;
6121 6121
     }
6122
-  else if (streq (p[0], "dhcp-release"))
6122
+  else if (streq (p[0], "dhcp-release") && !p[1])
6123 6123
     {
6124 6124
       VERIFY_PERMISSION (OPT_P_IPWIN32);
6125 6125
       options->tuntap_options.dhcp_release = true;
6126 6126
     }
6127
-  else if (streq (p[0], "dhcp-internal") && p[1]) /* standalone method for internal use */
6127
+  else if (streq (p[0], "dhcp-internal") && p[1] && !p[2]) /* standalone method for internal use */
6128 6128
     {
6129 6129
       unsigned int adapter_index;
6130 6130
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -6137,12 +6142,12 @@ add_option (struct options *options,
6137 6137
 	dhcp_renew_by_adapter_index (adapter_index);
6138 6138
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
6139 6139
     }
6140
-  else if (streq (p[0], "register-dns"))
6140
+  else if (streq (p[0], "register-dns") && !p[1])
6141 6141
     {
6142 6142
       VERIFY_PERMISSION (OPT_P_IPWIN32);
6143 6143
       options->tuntap_options.register_dns = true;
6144 6144
     }
6145
-  else if (streq (p[0], "rdns-internal"))
6145
+  else if (streq (p[0], "rdns-internal") && !p[1])
6146 6146
      /* standalone method for internal use
6147 6147
       *
6148 6148
       * (if --register-dns is set, openvpn needs to call itself in a
... ...
@@ -6156,18 +6161,18 @@ add_option (struct options *options,
6156 6156
 	ipconfig_register_dns (NULL);
6157 6157
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
6158 6158
     }
6159
-  else if (streq (p[0], "show-valid-subnets"))
6159
+  else if (streq (p[0], "show-valid-subnets") && !p[1])
6160 6160
     {
6161 6161
       VERIFY_PERMISSION (OPT_P_GENERAL);
6162 6162
       show_valid_win32_tun_subnets ();
6163 6163
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
6164 6164
     }
6165
-  else if (streq (p[0], "pause-exit"))
6165
+  else if (streq (p[0], "pause-exit") && !p[1])
6166 6166
     {
6167 6167
       VERIFY_PERMISSION (OPT_P_GENERAL);
6168 6168
       set_pause_exit_win32 ();
6169 6169
     }
6170
-  else if (streq (p[0], "service") && p[1])
6170
+  else if (streq (p[0], "service") && p[1] && !p[3])
6171 6171
     {
6172 6172
       VERIFY_PERMISSION (OPT_P_GENERAL);
6173 6173
       options->exit_event_name = p[1];
... ...
@@ -6176,52 +6181,52 @@ add_option (struct options *options,
6176 6176
 	  options->exit_event_initial_state = (atoi(p[2]) != 0);
6177 6177
 	}
6178 6178
     }
6179
-  else if (streq (p[0], "allow-nonadmin"))
6179
+  else if (streq (p[0], "allow-nonadmin") && !p[2])
6180 6180
     {
6181 6181
       VERIFY_PERMISSION (OPT_P_GENERAL);
6182 6182
       tap_allow_nonadmin_access (p[1]);
6183 6183
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
6184 6184
     }
6185
-  else if (streq (p[0], "user") && p[1])
6185
+  else if (streq (p[0], "user") && p[1] && !p[2])
6186 6186
     {
6187 6187
       VERIFY_PERMISSION (OPT_P_GENERAL);
6188 6188
       msg (M_WARN, "NOTE: --user option is not implemented on Windows");
6189 6189
     }
6190
-  else if (streq (p[0], "group") && p[1])
6190
+  else if (streq (p[0], "group") && p[1] && !p[2])
6191 6191
     {
6192 6192
       VERIFY_PERMISSION (OPT_P_GENERAL);
6193 6193
       msg (M_WARN, "NOTE: --group option is not implemented on Windows");
6194 6194
     }
6195 6195
 #else
6196
-  else if (streq (p[0], "user") && p[1])
6196
+  else if (streq (p[0], "user") && p[1] && !p[2])
6197 6197
     {
6198 6198
       VERIFY_PERMISSION (OPT_P_GENERAL);
6199 6199
       options->username = p[1];
6200 6200
     }
6201
-  else if (streq (p[0], "group") && p[1])
6201
+  else if (streq (p[0], "group") && p[1] && !p[2])
6202 6202
     {
6203 6203
       VERIFY_PERMISSION (OPT_P_GENERAL);
6204 6204
       options->groupname = p[1];
6205 6205
     }
6206
-  else if (streq (p[0], "dhcp-option") && p[1])
6206
+  else if (streq (p[0], "dhcp-option") && p[1] && !p[3])
6207 6207
     {
6208 6208
       VERIFY_PERMISSION (OPT_P_IPWIN32);
6209 6209
       foreign_option (options, p, 3, es);
6210 6210
     }
6211
-  else if (streq (p[0], "route-method") && p[1]) /* ignore when pushed to non-Windows OS */
6211
+  else if (streq (p[0], "route-method") && p[1] && !p[2]) /* ignore when pushed to non-Windows OS */
6212 6212
     {
6213 6213
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
6214 6214
     }
6215 6215
 #endif
6216 6216
 #if PASSTOS_CAPABILITY
6217
-  else if (streq (p[0], "passtos"))
6217
+  else if (streq (p[0], "passtos") && !p[1])
6218 6218
     {
6219 6219
       VERIFY_PERMISSION (OPT_P_GENERAL);
6220 6220
       options->passtos = true;
6221 6221
     }
6222 6222
 #endif
6223 6223
 #if defined(USE_COMP)
6224
-  else if (streq (p[0], "comp-lzo"))
6224
+  else if (streq (p[0], "comp-lzo") && !p[2])
6225 6225
     {
6226 6226
       VERIFY_PERMISSION (OPT_P_COMP);
6227 6227
 
... ...
@@ -6258,12 +6263,12 @@ add_option (struct options *options,
6258 6258
 	}
6259 6259
 #endif
6260 6260
     }
6261
-  else if (streq (p[0], "comp-noadapt"))
6261
+  else if (streq (p[0], "comp-noadapt") && !p[1])
6262 6262
     {
6263 6263
       VERIFY_PERMISSION (OPT_P_COMP);
6264 6264
       options->comp.flags &= ~COMP_F_ADAPTIVE;
6265 6265
     }
6266
-  else if (streq (p[0], "compress"))
6266
+  else if (streq (p[0], "compress") && !p[2])
6267 6267
     {
6268 6268
       VERIFY_PERMISSION (OPT_P_COMP);
6269 6269
       if (p[1])
... ...
@@ -6308,22 +6313,22 @@ add_option (struct options *options,
6308 6308
     }
6309 6309
 #endif /* USE_COMP */
6310 6310
 #ifdef ENABLE_CRYPTO
6311
-  else if (streq (p[0], "show-ciphers"))
6311
+  else if (streq (p[0], "show-ciphers") && !p[1])
6312 6312
     {
6313 6313
       VERIFY_PERMISSION (OPT_P_GENERAL);
6314 6314
       options->show_ciphers = true;
6315 6315
     }
6316
-  else if (streq (p[0], "show-digests"))
6316
+  else if (streq (p[0], "show-digests") && !p[1])
6317 6317
     {
6318 6318
       VERIFY_PERMISSION (OPT_P_GENERAL);
6319 6319
       options->show_digests = true;
6320 6320
     }
6321
-  else if (streq (p[0], "show-engines"))
6321
+  else if (streq (p[0], "show-engines") && !p[1])
6322 6322
     {
6323 6323
       VERIFY_PERMISSION (OPT_P_GENERAL);
6324 6324
       options->show_engines = true;
6325 6325
     }
6326
-  else if (streq (p[0], "key-direction") && p[1])
6326
+  else if (streq (p[0], "key-direction") && p[1] && !p[2])
6327 6327
     {
6328 6328
       int key_direction;
6329 6329
 
... ...
@@ -6333,7 +6338,7 @@ add_option (struct options *options,
6333 6333
       else
6334 6334
 	goto err;
6335 6335
     }
6336
-  else if (streq (p[0], "secret") && p[1])
6336
+  else if (streq (p[0], "secret") && p[1] && !p[3])
6337 6337
     {
6338 6338
       VERIFY_PERMISSION (OPT_P_GENERAL);
6339 6339
       if (streq (p[1], INLINE_FILE_TAG) && p[2])
... ...
@@ -6353,12 +6358,12 @@ add_option (struct options *options,
6353 6353
 	}
6354 6354
       options->shared_secret_file = p[1];
6355 6355
     }
6356
-  else if (streq (p[0], "genkey"))
6356
+  else if (streq (p[0], "genkey") && !p[1])
6357 6357
     {
6358 6358
       VERIFY_PERMISSION (OPT_P_GENERAL);
6359 6359
       options->genkey = true;
6360 6360
     }
6361
-  else if (streq (p[0], "auth") && p[1])
6361
+  else if (streq (p[0], "auth") && p[1] && !p[2])
6362 6362
     {
6363 6363
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6364 6364
       options->authname_defined = true;
... ...
@@ -6369,12 +6374,12 @@ add_option (struct options *options,
6369 6369
 	  options->authname = NULL;
6370 6370
 	}
6371 6371
     }
6372
-  else if (streq (p[0], "auth"))
6372
+  else if (streq (p[0], "auth") && !p[1])
6373 6373
     {
6374 6374
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6375 6375
       options->authname_defined = true;
6376 6376
     }
6377
-  else if (streq (p[0], "cipher") && p[1])
6377
+  else if (streq (p[0], "cipher") && p[1] && !p[2])
6378 6378
     {
6379 6379
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6380 6380
       options->ciphername_defined = true;
... ...
@@ -6385,12 +6390,12 @@ add_option (struct options *options,
6385 6385
 	  options->ciphername = NULL;
6386 6386
 	}
6387 6387
     }
6388
-  else if (streq (p[0], "cipher"))
6388
+  else if (streq (p[0], "cipher") && !p[1])
6389 6389
     {
6390 6390
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6391 6391
       options->ciphername_defined = true;
6392 6392
     }
6393
-  else if (streq (p[0], "prng") && p[1])
6393
+  else if (streq (p[0], "prng") && p[1] && !p[3])
6394 6394
     {
6395 6395
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6396 6396
       if (streq (p[1], "none"))
... ...
@@ -6412,12 +6417,12 @@ add_option (struct options *options,
6412 6412
 	    }
6413 6413
 	}
6414 6414
     }
6415
-  else if (streq (p[0], "no-replay"))
6415
+  else if (streq (p[0], "no-replay") && !p[1])
6416 6416
     {
6417 6417
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6418 6418
       options->replay = false;
6419 6419
     }
6420
-  else if (streq (p[0], "replay-window"))
6420
+  else if (streq (p[0], "replay-window") && !p[3])
6421 6421
     {
6422 6422
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6423 6423
       if (p[1])
... ...
@@ -6457,28 +6462,28 @@ add_option (struct options *options,
6457 6457
 	  goto err;
6458 6458
 	}
6459 6459
     }
6460
-  else if (streq (p[0], "mute-replay-warnings"))
6460
+  else if (streq (p[0], "mute-replay-warnings") && !p[1])
6461 6461
     {
6462 6462
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6463 6463
       options->mute_replay_warnings = true;
6464 6464
     }
6465
-  else if (streq (p[0], "no-iv"))
6465
+  else if (streq (p[0], "no-iv") && !p[1])
6466 6466
     {
6467 6467
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6468 6468
       options->use_iv = false;
6469 6469
     }
6470
-  else if (streq (p[0], "replay-persist") && p[1])
6470
+  else if (streq (p[0], "replay-persist") && p[1] && !p[2])
6471 6471
     {
6472 6472
       VERIFY_PERMISSION (OPT_P_GENERAL);
6473 6473
       options->packet_id_file = p[1];
6474 6474
     }
6475
-  else if (streq (p[0], "test-crypto"))
6475
+  else if (streq (p[0], "test-crypto") && !p[1])
6476 6476
     {
6477 6477
       VERIFY_PERMISSION (OPT_P_GENERAL);
6478 6478
       options->test_crypto = true;
6479 6479
     }
6480 6480
 #ifndef ENABLE_CRYPTO_POLARSSL
6481
-  else if (streq (p[0], "engine"))
6481
+  else if (streq (p[0], "engine") && !p[2])
6482 6482
     {
6483 6483
       VERIFY_PERMISSION (OPT_P_GENERAL);
6484 6484
       if (p[1])
... ...
@@ -6490,7 +6495,7 @@ add_option (struct options *options,
6490 6490
     }  
6491 6491
 #endif /* ENABLE_CRYPTO_POLARSSL */
6492 6492
 #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
6493
-  else if (streq (p[0], "keysize") && p[1])
6493
+  else if (streq (p[0], "keysize") && p[1] && !p[2])
6494 6494
     {
6495 6495
       int keysize;
6496 6496
 
... ...
@@ -6505,38 +6510,38 @@ add_option (struct options *options,
6505 6505
     }
6506 6506
 #endif
6507 6507
 #ifdef ENABLE_PREDICTION_RESISTANCE
6508
-  else if (streq (p[0], "use-prediction-resistance"))
6508
+  else if (streq (p[0], "use-prediction-resistance") && !p[1])
6509 6509
     {
6510 6510
       VERIFY_PERMISSION (OPT_P_GENERAL);
6511 6511
       options->use_prediction_resistance = true;
6512 6512
     }
6513 6513
 #endif
6514
-  else if (streq (p[0], "show-tls"))
6514
+  else if (streq (p[0], "show-tls") && !p[1])
6515 6515
     {
6516 6516
       VERIFY_PERMISSION (OPT_P_GENERAL);
6517 6517
       options->show_tls_ciphers = true;
6518 6518
     }
6519
-  else if (streq (p[0], "show-curves"))
6519
+  else if (streq (p[0], "show-curves") && !p[1])
6520 6520
     {
6521 6521
       VERIFY_PERMISSION (OPT_P_GENERAL);
6522 6522
       options->show_curves = true;
6523 6523
     }
6524
-  else if (streq (p[0], "ecdh-curve") && p[1])
6524
+  else if (streq (p[0], "ecdh-curve") && p[1] && !p[2])
6525 6525
     {
6526 6526
       VERIFY_PERMISSION (OPT_P_CRYPTO);
6527 6527
       options->ecdh_curve= p[1];
6528 6528
     }
6529
-  else if (streq (p[0], "tls-server"))
6529
+  else if (streq (p[0], "tls-server") && !p[1])
6530 6530
     {
6531 6531
       VERIFY_PERMISSION (OPT_P_GENERAL);
6532 6532
       options->tls_server = true;
6533 6533
     }
6534
-  else if (streq (p[0], "tls-client"))
6534
+  else if (streq (p[0], "tls-client") && !p[1])
6535 6535
     {
6536 6536
       VERIFY_PERMISSION (OPT_P_GENERAL);
6537 6537
       options->tls_client = true;
6538 6538
     }
6539
-  else if (streq (p[0], "ca") && p[1])
6539
+  else if (streq (p[0], "ca") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
6540 6540
     {
6541 6541
       VERIFY_PERMISSION (OPT_P_GENERAL);
6542 6542
       options->ca_file = p[1];
... ...
@@ -6546,13 +6551,13 @@ add_option (struct options *options,
6546 6546
 	}
6547 6547
     }
6548 6548
 #ifndef ENABLE_CRYPTO_POLARSSL
6549
-  else if (streq (p[0], "capath") && p[1])
6549
+  else if (streq (p[0], "capath") && p[1] && !p[2])
6550 6550
     {
6551 6551
       VERIFY_PERMISSION (OPT_P_GENERAL);
6552 6552
       options->ca_path = p[1];
6553 6553
     }
6554 6554
 #endif /* ENABLE_CRYPTO_POLARSSL */
6555
-  else if (streq (p[0], "dh") && p[1])
6555
+  else if (streq (p[0], "dh") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
6556 6556
     {
6557 6557
       VERIFY_PERMISSION (OPT_P_GENERAL);
6558 6558
       options->dh_file = p[1];
... ...
@@ -6561,7 +6566,7 @@ add_option (struct options *options,
6561 6561
 	  options->dh_file_inline = p[2];
6562 6562
 	}
6563 6563
     }
6564
-  else if (streq (p[0], "cert") && p[1])
6564
+  else if (streq (p[0], "cert") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
6565 6565
     {
6566 6566
       VERIFY_PERMISSION (OPT_P_GENERAL);
6567 6567
       options->cert_file = p[1];
... ...
@@ -6570,7 +6575,7 @@ add_option (struct options *options,
6570 6570
 	  options->cert_file_inline = p[2];
6571 6571
 	}
6572 6572
     }
6573
-  else if (streq (p[0], "extra-certs") && p[1])
6573
+  else if (streq (p[0], "extra-certs") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
6574 6574
     {
6575 6575
       VERIFY_PERMISSION (OPT_P_GENERAL);
6576 6576
       options->extra_certs_file = p[1];
... ...
@@ -6579,19 +6584,19 @@ add_option (struct options *options,
6579 6579
 	  options->extra_certs_file_inline = p[2];
6580 6580
 	}
6581 6581
     }
6582
-  else if (streq (p[0], "verify-hash") && p[1])
6582
+  else if (streq (p[0], "verify-hash") && p[1] && !p[2])
6583 6583
     {
6584 6584
       VERIFY_PERMISSION (OPT_P_GENERAL);
6585 6585
       options->verify_hash = parse_hash_fingerprint(p[1], SHA_DIGEST_LENGTH, msglevel, &options->gc);
6586 6586
     }
6587 6587
 #ifdef ENABLE_CRYPTOAPI
6588
-  else if (streq (p[0], "cryptoapicert") && p[1])
6588
+  else if (streq (p[0], "cryptoapicert") && p[1] && !p[2])
6589 6589
     {
6590 6590
       VERIFY_PERMISSION (OPT_P_GENERAL);
6591 6591
       options->cryptoapi_cert = p[1];
6592 6592
     }
6593 6593
 #endif
6594
-  else if (streq (p[0], "key") && p[1])
6594
+  else if (streq (p[0], "key") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
6595 6595
     {
6596 6596
       VERIFY_PERMISSION (OPT_P_GENERAL);
6597 6597
       options->priv_key_file = p[1];
... ...
@@ -6600,7 +6605,7 @@ add_option (struct options *options,
6600 6600
 	  options->priv_key_file_inline = p[2];
6601 6601
 	}
6602 6602
     }
6603
-  else if (streq (p[0], "tls-version-min") && p[1])
6603
+  else if (streq (p[0], "tls-version-min") && p[1] && !p[3])
6604 6604
     {
6605 6605
       int ver;
6606 6606
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -6614,7 +6619,7 @@ add_option (struct options *options,
6614 6614
 	  ~(SSLF_TLS_VERSION_MIN_MASK << SSLF_TLS_VERSION_MIN_SHIFT);
6615 6615
       options->ssl_flags |= (ver << SSLF_TLS_VERSION_MIN_SHIFT);
6616 6616
     }
6617
-  else if (streq (p[0], "tls-version-max") && p[1])
6617
+  else if (streq (p[0], "tls-version-max") && p[1] && !p[2])
6618 6618
     {
6619 6619
       int ver;
6620 6620
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -6629,7 +6634,7 @@ add_option (struct options *options,
6629 6629
       options->ssl_flags |= (ver << SSLF_TLS_VERSION_MAX_SHIFT);
6630 6630
     }
6631 6631
 #ifndef ENABLE_CRYPTO_POLARSSL
6632
-  else if (streq (p[0], "pkcs12") && p[1])
6632
+  else if (streq (p[0], "pkcs12") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
6633 6633
     {
6634 6634
       VERIFY_PERMISSION (OPT_P_GENERAL);
6635 6635
       options->pkcs12_file = p[1];
... ...
@@ -6639,7 +6644,7 @@ add_option (struct options *options,
6639 6639
 	}
6640 6640
     }
6641 6641
 #endif /* ENABLE_CRYPTO_POLARSSL */
6642
-  else if (streq (p[0], "askpass"))
6642
+  else if (streq (p[0], "askpass") && !p[2])
6643 6643
     {
6644 6644
       VERIFY_PERMISSION (OPT_P_GENERAL);
6645 6645
       if (p[1])
... ...
@@ -6649,12 +6654,12 @@ add_option (struct options *options,
6649 6649
       else
6650 6650
 	options->key_pass_file = "stdin";	
6651 6651
     }
6652
-  else if (streq (p[0], "auth-nocache"))
6652
+  else if (streq (p[0], "auth-nocache") && !p[1])
6653 6653
     {
6654 6654
       VERIFY_PERMISSION (OPT_P_GENERAL);
6655 6655
       ssl_set_auth_nocache ();
6656 6656
     }
6657
-  else if (streq (p[0], "auth-token") && p[1])
6657
+  else if (streq (p[0], "auth-token") && p[1] && !p[2])
6658 6658
     {
6659 6659
       VERIFY_PERMISSION (OPT_P_ECHO);
6660 6660
       ssl_set_auth_token(p[1]);
... ...
@@ -6663,29 +6668,29 @@ add_option (struct options *options,
6663 6663
 	management_auth_token (management, p[1]);
6664 6664
 #endif
6665 6665
     }
6666
-  else if (streq (p[0], "single-session"))
6666
+  else if (streq (p[0], "single-session") && !p[1])
6667 6667
     {
6668 6668
       VERIFY_PERMISSION (OPT_P_GENERAL);
6669 6669
       options->single_session = true;
6670 6670
     }
6671 6671
 #ifdef ENABLE_PUSH_PEER_INFO
6672
-  else if (streq (p[0], "push-peer-info"))
6672
+  else if (streq (p[0], "push-peer-info") && !p[1])
6673 6673
     {
6674 6674
       VERIFY_PERMISSION (OPT_P_GENERAL);
6675 6675
       options->push_peer_info = true;
6676 6676
     }
6677 6677
 #endif
6678
-  else if (streq (p[0], "tls-exit"))
6678
+  else if (streq (p[0], "tls-exit") && !p[1])
6679 6679
     {
6680 6680
       VERIFY_PERMISSION (OPT_P_GENERAL);
6681 6681
       options->tls_exit = true;
6682 6682
     }
6683
-  else if (streq (p[0], "tls-cipher") && p[1])
6683
+  else if (streq (p[0], "tls-cipher") && p[1] && !p[2])
6684 6684
     {
6685 6685
       VERIFY_PERMISSION (OPT_P_GENERAL);
6686 6686
       options->cipher_list = p[1];
6687 6687
     }
6688
-  else if (streq (p[0], "crl-verify") && p[1])
6688
+  else if (streq (p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || !p[2]) && !p[3])
6689 6689
     {
6690 6690
       VERIFY_PERMISSION (OPT_P_GENERAL);
6691 6691
       if (p[2] && streq(p[2], "dir"))
... ...
@@ -6702,13 +6707,17 @@ add_option (struct options *options,
6702 6702
 		       "tls-verify", true);
6703 6703
     }
6704 6704
 #ifndef ENABLE_CRYPTO_POLARSSL
6705
-  else if (streq (p[0], "tls-export-cert") && p[1])
6705
+  else if (streq (p[0], "tls-export-cert") && p[1] && !p[2])
6706 6706
     {
6707 6707
       VERIFY_PERMISSION (OPT_P_GENERAL);
6708 6708
       options->tls_export_cert = p[1];
6709 6709
     }
6710 6710
 #endif
6711
-  else if (streq (p[0], "compat-names"))
6711
+#if P2MP_SERVER
6712
+  else if (streq (p[0], "compat-names") && ((p[1] && streq (p[1], "no-remapping")) || !p[1]) && !p[2])
6713
+#else
6714
+  else if (streq (p[0], "compat-names") && !p[1])
6715
+#endif
6712 6716
     {
6713 6717
       VERIFY_PERMISSION (OPT_P_GENERAL);
6714 6718
       if (options->verify_x509_type != VERIFY_X509_NONE &&
... ...
@@ -6724,7 +6733,7 @@ add_option (struct options *options,
6724 6724
       if (p[1] && streq (p[1], "no-remapping"))
6725 6725
         compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING);
6726 6726
     }
6727
-  else if (streq (p[0], "no-name-remapping"))
6727
+  else if (streq (p[0], "no-name-remapping") && !p[1])
6728 6728
     {
6729 6729
       VERIFY_PERMISSION (OPT_P_GENERAL);
6730 6730
       if (options->verify_x509_type != VERIFY_X509_NONE &&
... ...
@@ -6739,7 +6748,7 @@ add_option (struct options *options,
6739 6739
       compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING);
6740 6740
 #endif
6741 6741
     }
6742
-  else if (streq (p[0], "tls-remote") && p[1])
6742
+  else if (streq (p[0], "tls-remote") && p[1] && !p[2])
6743 6743
     {
6744 6744
       VERIFY_PERMISSION (OPT_P_GENERAL);
6745 6745
 
... ...
@@ -6770,7 +6779,7 @@ add_option (struct options *options,
6770 6770
           options->verify_x509_name = p[1];
6771 6771
         }
6772 6772
     }
6773
-  else if (streq (p[0], "verify-x509-name") && p[1] && strlen (p[1]))
6773
+  else if (streq (p[0], "verify-x509-name") && p[1] && strlen (p[1]) && !p[3])
6774 6774
     {
6775 6775
       int type = VERIFY_X509_SUBJECT_DN;
6776 6776
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -6803,7 +6812,7 @@ add_option (struct options *options,
6803 6803
       options->verify_x509_type = type;
6804 6804
       options->verify_x509_name = p[1];
6805 6805
     }
6806
-  else if (streq (p[0], "ns-cert-type") && p[1])
6806
+  else if (streq (p[0], "ns-cert-type") && p[1] && !p[2])
6807 6807
     {
6808 6808
       VERIFY_PERMISSION (OPT_P_GENERAL);
6809 6809
       if (streq (p[1], "server"))
... ...
@@ -6825,12 +6834,12 @@ add_option (struct options *options,
6825 6825
       for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
6826 6826
 	sscanf (p[j], "%x", &(options->remote_cert_ku[j-1]));
6827 6827
     }
6828
-  else if (streq (p[0], "remote-cert-eku") && p[1])
6828
+  else if (streq (p[0], "remote-cert-eku") && p[1] && !p[2])
6829 6829
     {
6830 6830
       VERIFY_PERMISSION (OPT_P_GENERAL);
6831 6831
       options->remote_cert_eku = p[1];
6832 6832
     }
6833
-  else if (streq (p[0], "remote-cert-tls") && p[1])
6833
+  else if (streq (p[0], "remote-cert-tls") && p[1] && !p[2])
6834 6834
     {
6835 6835
       VERIFY_PERMISSION (OPT_P_GENERAL);
6836 6836
 
... ...
@@ -6853,37 +6862,37 @@ add_option (struct options *options,
6853 6853
 	  goto err;
6854 6854
 	}
6855 6855
     }
6856
-  else if (streq (p[0], "tls-timeout") && p[1])
6856
+  else if (streq (p[0], "tls-timeout") && p[1] && !p[2])
6857 6857
     {
6858 6858
       VERIFY_PERMISSION (OPT_P_TLS_PARMS);
6859 6859
       options->tls_timeout = positive_atoi (p[1]);
6860 6860
     }
6861
-  else if (streq (p[0], "reneg-bytes") && p[1])
6861
+  else if (streq (p[0], "reneg-bytes") && p[1] && !p[2])
6862 6862
     {
6863 6863
       VERIFY_PERMISSION (OPT_P_TLS_PARMS);
6864 6864
       options->renegotiate_bytes = positive_atoi (p[1]);
6865 6865
     }
6866
-  else if (streq (p[0], "reneg-pkts") && p[1])
6866
+  else if (streq (p[0], "reneg-pkts") && p[1] && !p[2])
6867 6867
     {
6868 6868
       VERIFY_PERMISSION (OPT_P_TLS_PARMS);
6869 6869
       options->renegotiate_packets = positive_atoi (p[1]);
6870 6870
     }
6871
-  else if (streq (p[0], "reneg-sec") && p[1])
6871
+  else if (streq (p[0], "reneg-sec") && p[1] && !p[2])
6872 6872
     {
6873 6873
       VERIFY_PERMISSION (OPT_P_TLS_PARMS);
6874 6874
       options->renegotiate_seconds = positive_atoi (p[1]);
6875 6875
     }
6876
-  else if (streq (p[0], "hand-window") && p[1])
6876
+  else if (streq (p[0], "hand-window") && p[1] && !p[2])
6877 6877
     {
6878 6878
       VERIFY_PERMISSION (OPT_P_TLS_PARMS);
6879 6879
       options->handshake_window = positive_atoi (p[1]);
6880 6880
     }
6881
-  else if (streq (p[0], "tran-window") && p[1])
6881
+  else if (streq (p[0], "tran-window") && p[1] && !p[2])
6882 6882
     {
6883 6883
       VERIFY_PERMISSION (OPT_P_TLS_PARMS);
6884 6884
       options->transition_window = positive_atoi (p[1]);
6885 6885
     }
6886
-  else if (streq (p[0], "tls-auth") && p[1])
6886
+  else if (streq (p[0], "tls-auth") && p[1] && !p[3])
6887 6887
     {
6888 6888
       VERIFY_PERMISSION (OPT_P_GENERAL);
6889 6889
       if (streq (p[1], INLINE_FILE_TAG) && p[2])
... ...
@@ -6903,7 +6912,7 @@ add_option (struct options *options,
6903 6903
 	}
6904 6904
       options->tls_auth_file = p[1];
6905 6905
     }
6906
-  else if (streq (p[0], "key-method") && p[1])
6906
+  else if (streq (p[0], "key-method") && p[1] && !p[2])
6907 6907
     {
6908 6908
       int key_method;
6909 6909
 
... ...
@@ -6920,7 +6929,7 @@ add_option (struct options *options,
6920 6920
       options->key_method = key_method;
6921 6921
     }
6922 6922
 #ifdef ENABLE_X509ALTUSERNAME
6923
-  else if (streq (p[0], "x509-username-field") && p[1])
6923
+  else if (streq (p[0], "x509-username-field") && p[1] && !p[2])
6924 6924
     {
6925 6925
       /* This option used to automatically upcase the fieldname passed as the
6926 6926
        * option argument, e.g., "ou" became "OU". Now, this "helpfulness" is
... ...
@@ -6949,7 +6958,7 @@ add_option (struct options *options,
6949 6949
 #endif /* ENABLE_X509ALTUSERNAME */
6950 6950
 #endif /* ENABLE_CRYPTO */
6951 6951
 #ifdef ENABLE_PKCS11
6952
-  else if (streq (p[0], "show-pkcs11-ids"))
6952
+  else if (streq (p[0], "show-pkcs11-ids") && !p[3])
6953 6953
     {
6954 6954
       char *provider =  p[1];
6955 6955
       bool cert_private = (p[2] == NULL ? false : ( atoi (p[2]) != 0 ));
... ...
@@ -7019,35 +7028,35 @@ add_option (struct options *options,
7019 7019
       for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
7020 7020
         options->pkcs11_cert_private[j-1] = atoi (p[j]) != 0 ? 1 : 0;
7021 7021
     }
7022
-   else if (streq (p[0], "pkcs11-pin-cache") && p[1])
7022
+   else if (streq (p[0], "pkcs11-pin-cache") && p[1] && !p[2])
7023 7023
     {
7024 7024
       VERIFY_PERMISSION (OPT_P_GENERAL);
7025 7025
       options->pkcs11_pin_cache_period = atoi (p[1]);
7026 7026
     }
7027
-  else if (streq (p[0], "pkcs11-id") && p[1])
7027
+  else if (streq (p[0], "pkcs11-id") && p[1] && !p[2])
7028 7028
     {
7029 7029
       VERIFY_PERMISSION (OPT_P_GENERAL);
7030 7030
       options->pkcs11_id = p[1];
7031 7031
     }
7032
-  else if (streq (p[0], "pkcs11-id-management"))
7032
+  else if (streq (p[0], "pkcs11-id-management") && !p[1])
7033 7033
     {
7034 7034
       VERIFY_PERMISSION (OPT_P_GENERAL);
7035 7035
       options->pkcs11_id_management = true;
7036 7036
     }
7037 7037
 #endif
7038
-  else if (streq (p[0], "rmtun"))
7038
+  else if (streq (p[0], "rmtun") && !p[1])
7039 7039
     {
7040 7040
       VERIFY_PERMISSION (OPT_P_GENERAL);
7041 7041
       options->persist_config = true;
7042 7042
       options->persist_mode = 0;
7043 7043
     }
7044
-  else if (streq (p[0], "mktun"))
7044
+  else if (streq (p[0], "mktun") && !p[1])
7045 7045
     {
7046 7046
       VERIFY_PERMISSION (OPT_P_GENERAL);
7047 7047
       options->persist_config = true;
7048 7048
       options->persist_mode = 1;
7049 7049
     }
7050
-  else if (streq (p[0], "peer-id") && p[1])
7050
+  else if (streq (p[0], "peer-id") && p[1] && !p[2])
7051 7051
     {
7052 7052
       VERIFY_PERMISSION (OPT_P_PEER_ID);
7053 7053
       options->use_peer_id = true;
... ...
@@ -7068,9 +7077,9 @@ add_option (struct options *options,
7068 7068
             }
7069 7069
         }
7070 7070
       if (file)
7071
-	msg (msglevel, "Unrecognized option or missing parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
7071
+	msg (msglevel, "Unrecognized option or missing or extra parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
7072 7072
       else
7073
-	msg (msglevel, "Unrecognized option or missing parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
7073
+	msg (msglevel, "Unrecognized option or missing or extra parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
7074 7074
     }
7075 7075
  err:
7076 7076
   gc_free (&gc);