69
74
" [--dnskeyondemand]"
71
76
" [--updown <updown>]"
74
" (--host <ip-address> | --id <identity> | --cert <path>)"
78
" (--host <ip-address> | --id <identity>)"
81
" [--groups <access control groups>]"
75
82
" [--ca <distinguished name>]"
76
" [--sendcert yes|always|no|never|ifasked]"
84
" [--sendcerttype number]"
77
86
" [--ikeport <port-number>]"
79
88
" [--nexthop <ip-address>]"
80
90
" [--client <subnet> | --clientwithin <address range>]"
82
92
" [--clientprotoport <protocol>/<port>]"
83
94
" [--dnskeyondemand]"
85
95
" [--updown <updown>]"
213
259
exit(RC_WHACK_PROBLEM);
216
/* conditially calls diag; prints second arg, if non-NULL, as quoted string */
263
* Conditially calls diag if ugh is set.
264
* Prints second arg, if non-NULL, as quoted string
266
* @param ugh Error message
267
* @param this Optional 2nd part of error message
218
271
diagq(err_t ugh, const char *this)
236
/* complex combined operands return one of these enumerated values
290
* complex combined operands return one of these enumerated values
237
291
* Note: these become flags in an lset_t. Since there are more than
238
292
* 32, we partition them into:
239
293
* - OPT_* options (most random options)
294
* - LST_* options (list various internal data)
240
295
* - DBGOPT_* option (DEBUG options)
296
* - END_* options (End description options)
241
297
* - CD_* options (Connection Description options)
243
299
enum option_enums {
321
396
# define CD_POLICY_FIRST CD_PSK
322
CD_PSK, /* same order as POLICY_* */
323
CD_RSASIG, /* same order as POLICY_* */
324
CD_ENCRYPT, /* same order as POLICY_* */
325
CD_AUTHENTICATE, /* same order as POLICY_* */
326
CD_COMPRESS, /* same order as POLICY_* */
327
CD_TUNNEL, /* same order as POLICY_* */
328
CD_PFS, /* same order as POLICY_* */
329
CD_DISABLEARRIVALCHECK, /* same order as POLICY_* */
330
CD_SHUNT0, /* same order as POLICY_* */
331
CD_SHUNT1, /* same order as POLICY_* */
332
CD_FAIL0, /* same order as POLICY_* */
333
CD_FAIL1, /* same order as POLICY_* */
334
CD_DONT_REKEY, /* same order as POLICY_* */
335
CD_OPP0, /* same order as POLICY_* */
336
CD_GROUP, /* same order as POLICY_* */
337
CD_GROUPED, /* same order as POLICY_* */
338
CD_UP, /* same order as POLICY_* */
339
CD_DUMMY, /* same order as POLICY_* */
340
CD_MODECFG, /* same order as POLICY_* */
397
CD_PSK, /* same order as POLICY_* 0 */
398
CD_RSASIG, /* same order as POLICY_* 1 */
399
CD_ENCRYPT, /* same order as POLICY_* 2 */
400
CD_AUTHENTICATE, /* same order as POLICY_* 3 */
401
CD_COMPRESS, /* same order as POLICY_* 4 */
402
CD_TUNNEL, /* same order as POLICY_* 5 */
403
CD_PFS, /* same order as POLICY_* 6 */
404
CD_DISABLEARRIVALCHECK, /* same order as POLICY_* 7 */
405
CD_SHUNT0, /* same order as POLICY_* 8 */
406
CD_SHUNT1, /* same order as POLICY_* 9 */
407
CD_FAIL0, /* same order as POLICY_* 10 */
408
CD_FAIL1, /* same order as POLICY_* 11 */
409
CD_DONT_REKEY, /* same order as POLICY_* 12 */
410
CD_OPP0, /* same order as POLICY_* 13 */
411
CD_GROUP, /* same order as POLICY_* 14 */
412
CD_GROUPED, /* same order as POLICY_* 15 */
413
CD_UP, /* same order as POLICY_* 16 */
414
CD_DUMMY, /* same order as POLICY_* 17 -- was XAUTH */
415
CD_MODECFGPULL, /* same order as POLICY_* 18 */
416
CD_AGGRESSIVE, /* same order as POLICY_* 19 */
369
451
DBGOPT_OPPO, /* same order as DBG_* */
370
452
DBGOPT_CONTROLMORE, /* same order as DBG_* */
371
453
DBGOPT_PFKEY, /* same order as DBG_* */
372
DBGOPT_NATTRAVERSAL, /* same order as DBG_* */
454
DBGOPT_NATT, /* same order as DBG_* */
455
DBGOPT_X509, /* same order as DBG_* */
456
DBGOPT_DPD, /* same order as DBG_* */
374
464
DBGOPT_PRIVATE, /* same order as DBG_* */
420
510
{ "crash", required_argument, NULL, OPT_DELETECRASH + OO },
421
511
{ "listen", no_argument, NULL, OPT_LISTEN + OO },
422
512
{ "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
423
{ "utc", no_argument, NULL, OPT_UTC + OO },
424
{ "listpubkeys", no_argument, NULL, OPT_LISTPUBKEYS + OO },
425
{ "listcerts", no_argument, NULL, OPT_LISTCERTS + OO },
426
{ "listcacerts", no_argument, NULL, OPT_LISTCACERTS + OO },
427
{ "listcrls", no_argument, NULL, OPT_LISTCRLS + OO },
428
{ "listcards", no_argument, NULL, OPT_LISTCARDS + OO },
429
{ "listall", no_argument, NULL, OPT_LISTALL + OO },
513
{ "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO },
430
515
{ "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
431
516
{ "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
517
{ "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
518
{ "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
519
{ "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO },
432
521
{ "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
433
522
{ "rereadall", no_argument, NULL, OPT_REREADALL + OO },
434
523
{ "status", no_argument, NULL, OPT_STATUS + OO },
443
532
{ "asynchronous", no_argument, NULL, OPT_ASYNC + OO },
536
{ "utc", no_argument, NULL, LST_UTC + OO },
537
{ "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
538
{ "listcerts", no_argument, NULL, LST_CERTS + OO },
539
{ "listcacerts", no_argument, NULL, LST_CACERTS + OO },
540
{ "listacerts", no_argument, NULL, LST_ACERTS + OO },
541
{ "listaacerts", no_argument, NULL, LST_AACERTS + OO },
542
{ "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
543
{ "listgroups", no_argument, NULL, LST_GROUPS + OO },
544
{ "listcrls", no_argument, NULL, LST_CRLS + OO },
545
{ "listocsp", no_argument, NULL, LST_OCSP + OO },
546
{ "listcards", no_argument, NULL, LST_CARDS + OO },
547
{ "listevents", no_argument, NULL, LST_EVENTS + OO },
548
{ "listall", no_argument, NULL, LST_ALL + OO },
446
551
/* options for an end description */
449
554
{ "id", required_argument, NULL, END_ID + OO },
450
555
{ "cert", required_argument, NULL, END_CERT + OO },
451
556
{ "ca", required_argument, NULL, END_CA + OO },
557
{ "groups", required_argument, NULL, END_GROUPS + OO },
452
558
{ "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
453
559
{ "nexthop", required_argument, NULL, END_NEXTHOP + OO },
454
560
{ "client", required_argument, NULL, END_CLIENT + OO },
473
579
{ "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
474
580
{ "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
475
581
{ "pfs", no_argument, NULL, CD_PFS + OO },
582
{ "aggrmode", no_argument, NULL, CD_AGGRESSIVE + OO },
476
583
{ "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
477
584
{ "initiateontraffic", no_argument, NULL
478
585
, CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
491
598
{ "failreject", no_argument, NULL
492
599
, CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
493
600
{ "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
601
{ "forceencaps", no_argument, NULL, CD_FORCEENCAPS + OO },
602
{ "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
603
{ "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
604
{ "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
495
606
{ "xauth", no_argument, NULL, END_XAUTHSERVER + OO },
496
607
{ "xauthserver", no_argument, NULL, END_XAUTHSERVER + OO },
497
608
{ "xauthclient", no_argument, NULL, END_XAUTHCLIENT + OO },
611
{ "modecfgpull", no_argument, NULL, CD_MODECFGPULL + OO },
500
612
{ "modecfgserver", no_argument, NULL, END_MODECFGSERVER + OO },
501
613
{ "modecfgclient", no_argument, NULL, END_MODECFGCLIENT + OO },
502
614
{ "modeconfigserver", no_argument, NULL, END_MODECFGSERVER + OO },
503
615
{ "modeconfigclient", no_argument, NULL, END_MODECFGCLIENT + OO },
505
617
{ "sendcert", required_argument, NULL, END_SENDCERT + OO },
618
{ "certtype", required_argument, NULL, END_CERTTYPE + OO + NUMERIC_ARG },
506
619
{ "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
507
620
{ "ipv6", no_argument, NULL, CD_CONNIPV6 + OO },
512
625
{ "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
513
626
{ "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
514
627
{ "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
628
{ "ike", required_argument, NULL, CD_IKE + OO },
629
{ "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
630
{ "esp", required_argument, NULL, CD_ESP + OO },
516
632
{ "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
517
633
{ "debug-all]", no_argument, NULL, DBGOPT_ALL + OO },
526
642
{ "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
527
643
{ "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
528
644
{ "debug-pfkey", no_argument, NULL, DBGOPT_PFKEY + OO },
529
{ "debug-nattraversal", no_argument, NULL, DBGOPT_NATTRAVERSAL + OO },
645
{ "debug-nattraversal", no_argument, NULL, DBGOPT_NATT + OO },
646
{ "debug-x509", no_argument, NULL, DBGOPT_X509 + OO },
647
{ "debug-dpd", no_argument, NULL, DBGOPT_DPD + OO },
530
648
{ "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO },
532
650
{ "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
761
869
assert(OPTION_OFFSET + CD_LAST < NUMERIC_ARG);
763
assert(OPT_LAST - OPT_FIRST < 32);
764
assert(END_LAST - END_FIRST < 32);
765
assert(CD_LAST - CD_FIRST < 32);
766
#ifdef DEBUG /* must be last so others are less than 32 to fit in lset_t */
767
assert(DBGOPT_LAST - DBGOPT_FIRST < 32);
871
assert(OPT_LAST - OPT_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
872
assert(LST_LAST - LST_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
873
assert(END_LAST - END_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
874
assert(CD_LAST - CD_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
875
#ifdef DEBUG /* must be last so others are less than (sizeof cd_seen * BITS_PER_BYTE) to fit in lset_t */
876
assert(DBGOPT_LAST - DBGOPT_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
769
878
/* check that POLICY bit assignment matches with CD_ */
770
879
assert(LELEM(CD_DONT_REKEY - CD_POLICY_FIRST) == POLICY_DONT_REKEY);
830
942
diagq("duplicated flag", long_opts[long_index].name);
945
else if (LST_FIRST <= c && c <= LST_LAST)
947
/* LST_* options get added lst_seen.
948
* Reject repeated options (unless later code intervenes).
950
lset_t f = LELEM(c - LST_FIRST);
953
diagq("duplicated flag", long_opts[long_index].name);
834
957
else if (DBGOPT_FIRST <= c && c <= DBGOPT_LAST)
992
1115
msg.whack_unlisten = TRUE;
995
case OPT_UTC: /* --utc */
996
msg.whack_utc = TRUE;
1118
case OPT_PURGEOCSP: /* --purgeocsp */
1119
msg.whack_purgeocsp = TRUE;
999
case OPT_LISTPUBKEYS: /* --listpubkeys */
1000
case OPT_LISTCERTS: /* --listcerts */
1001
case OPT_LISTCACERTS: /* --listcacerts */
1002
case OPT_LISTCRLS: /* --listcrls */
1003
case OPT_LISTCARDS: /* --listcards */
1004
msg.whack_list |= LELEM(c-OPT_LISTPUBKEYS);
1007
case OPT_LISTALL: /* --listall */
1008
msg.whack_list = LIST_ALL;
1011
case OPT_REREADSECRETS: /* --rereadsecrets */
1012
case OPT_REREADCACERTS: /* --rereadcacerts */
1013
case OPT_REREADCRLS: /* --rereadcrls */
1122
case OPT_REREADSECRETS: /* --rereadsecrets */
1123
case OPT_REREADCACERTS: /* --rereadcacerts */
1124
case OPT_REREADAACERTS: /* --rereadaacerts */
1125
case OPT_REREADOCSPCERTS: /* --rereadocspcerts */
1126
case OPT_REREADACERTS: /* --rereadacerts */
1127
case OPT_REREADCRLS: /* --rereadcrls */
1014
1128
msg.whack_reread |= LELEM(c-OPT_REREADSECRETS);
1044
1158
msg.whack_async = TRUE;
1163
case LST_UTC: /* --utc */
1164
msg.whack_utc = TRUE;
1167
case LST_PUBKEYS: /* --listpubkeys */
1168
case LST_CERTS: /* --listcerts */
1169
case LST_CACERTS: /* --listcacerts */
1170
case LST_ACERTS: /* --listacerts */
1171
case LST_AACERTS: /* --listaacerts */
1172
case LST_OCSPCERTS: /* --listocspcerts */
1173
case LST_GROUPS: /* --listgroups */
1174
case LST_CRLS: /* --listcrls */
1175
case LST_OCSP: /* --listocsp */
1176
case LST_CARDS: /* --listcards */
1177
case LST_EVENTS: /* --listcards */
1178
msg.whack_list |= LELEM(c - LST_PUBKEYS);
1181
case LST_ALL: /* --listall */
1182
msg.whack_list = LIST_ALL;
1048
1185
/* Connection Description options */
1215
1370
case END_CLIENTPROTOPORT: /* --clientprotoport <protocol>/<port> */
1216
diagq(ttoprotoport(optarg, 0, &msg.right.protocol,
1217
&msg.right.port), optarg);
1371
diagq(ttoprotoport(optarg, 0, &msg.right.protocol, &msg.right.port
1372
, &msg.right.has_port_wildcard), optarg);
1220
1375
case END_DNSKEYONDEMAND: /* --dnskeyondemand */
1288
1444
msg.sa_keying_tries = opt_whole;
1447
case CD_FORCEENCAPS:
1448
msg.forceencaps = TRUE;
1452
msg.dpd_delay = opt_whole;
1456
msg.dpd_timeout = opt_whole;
1460
msg.dpd_action = 255;
1461
if( strcmp(optarg, "clear") == 0) {
1462
msg.dpd_action = DPD_ACTION_CLEAR;
1464
if( strcmp(optarg, "hold") == 0) {
1465
msg.dpd_action = DPD_ACTION_HOLD;
1469
case CD_IKE: /* --ike <ike_alg1,ike_alg2,...> */
1473
case CD_PFSGROUP: /* --pfsgroup modpXXXX */
1474
msg.pfsgroup = optarg;
1477
case CD_ESP: /* --esp <esp_alg1,esp_alg2,...> */
1291
1481
case CD_CONNIPV4:
1292
1482
if (LHAS(cd_seen, CD_CONNIPV6 - CD_FIRST))
1293
1483
diag("--ipv4 conflicts with --ipv6");
1371
1561
case DBGOPT_OPPO: /* --debug-oppo */
1372
1562
case DBGOPT_CONTROLMORE: /* --debug-controlmore */
1373
1563
case DBGOPT_PFKEY: /* --debug-pfkey */
1564
case DBGOPT_NATT: /* --debug-pfkey */
1565
case DBGOPT_X509: /* --debug-pfkey */
1566
case DBGOPT_DPD: /* --debug-dpd */
1374
1567
case DBGOPT_PRIVATE: /* --debug-private */
1375
1568
case DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER: /* --impair-delay-adns-key-answer */
1376
1569
case DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER: /* --impair-delay-adns-txt-answer */
1493
1686
|| msg.whack_delete || msg.whack_deletestate
1494
1687
|| msg.whack_initiate || msg.whack_oppo_initiate || msg.whack_terminate
1495
1688
|| msg.whack_route || msg.whack_unroute || msg.whack_listen
1496
|| msg.whack_unlisten || msg.whack_list || msg.whack_reread
1689
|| msg.whack_unlisten || msg.whack_list || msg.whack_purgeocsp || msg.whack_reread
1497
1690
|| msg.whack_status || msg.whack_options || msg.whack_shutdown))
1499
1692
diag("no action specified; try --help for hints");
1695
if(msg.policy & POLICY_AGGRESSIVE) {
1696
if(msg.ike == NULL) {
1697
diag("can not specify aggressive mode without ike= to set algorithm");
1502
1701
update_ports(&msg);
1504
1703
/* tricky quick and dirty check for wild values */
1513
1712
check_life_time(msg.sa_ipsec_life_seconds, SA_LIFE_DURATION_MAXIMUM
1514
1713
, "ipseclifetime", &msg);
1715
if(msg.dpd_delay && !msg.dpd_timeout)
1716
diag("dpddelay specified, but dpdtimeout is zero, both should be specified");
1717
if(!msg.dpd_delay && msg.dpd_timeout)
1718
diag("dpdtimeout specified, but dpddelay is zero, both should be specified");
1719
if(msg.dpd_action != DPD_ACTION_CLEAR && msg.dpd_action != DPD_ACTION_HOLD) {
1720
diag("dpdaction can only be \"clear\" or \"hold\", defaulting to \"hold\"");
1721
msg.dpd_action = DPD_ACTION_HOLD;
1516
1725
/* pack strings for inclusion in message */
1517
1726
next_str = msg.string;
1518
1727
str_roof = &msg.string[sizeof(msg.string)];
1729
/* build esp message as esp="<esp>;<pfsgroup>" */
1731
snprintf(esp_buf, sizeof (esp_buf), "%s;%s",
1732
msg.esp ? msg.esp : "",
1733
msg.pfsgroup ? msg.pfsgroup : "");
1520
1736
if (!pack_str(&msg.name) /* string 1 */
1521
1737
|| !pack_str(&msg.left.id) /* string 2 */
1522
1738
|| !pack_str(&msg.left.cert) /* string 3 */
1523
1739
|| !pack_str(&msg.left.ca) /* string 4 */
1524
|| !pack_str(&msg.left.updown) /* string 5 */
1740
|| !pack_str(&msg.left.groups) /* string 5 */
1741
|| !pack_str(&msg.left.updown) /* string 6 */
1525
1742
#ifdef VIRTUAL_IP
1526
1743
|| !pack_str(&msg.left.virt)
1528
|| !pack_str(&msg.right.id) /* string 6 */
1529
|| !pack_str(&msg.right.cert) /* string 7 */
1530
|| !pack_str(&msg.right.ca) /* string 8 */
1531
|| !pack_str(&msg.right.updown) /* string 9 */
1745
|| !pack_str(&msg.right.id) /* string 7 */
1746
|| !pack_str(&msg.right.cert) /* string 8 */
1747
|| !pack_str(&msg.right.ca) /* string 9 */
1748
|| !pack_str(&msg.right.groups) /* string 10 */
1749
|| !pack_str(&msg.right.updown) /* string 11 */
1532
1750
#ifdef VIRTUAL_IP
1533
1751
|| !pack_str(&msg.right.virt)
1535
|| !pack_str(&msg.keyid) /* string 10 */
1536
|| !pack_str(&msg.myid) /* string 11 */
1753
|| !pack_str(&msg.keyid) /* string 12 */
1754
|| !pack_str(&msg.myid) /* string 13 */
1755
|| !pack_str(&msg.ike) /* string 14 */
1756
|| !pack_str(&msg.esp) /* string 15 */
1537
1757
|| str_roof - next_str < (ptrdiff_t)msg.keyval.len) /* chunk (sort of string 5) */
1538
1758
diag("too many bytes of strings to fit in message to pluto");