Set route to VPN gateway before configuring tunnel
[vpnc.git] / config.c
blob635af620d1c5c71985bb18f61ec703ae14ca6ce0
1 /* IPSec VPN client compatible with Cisco equipment.
2 Copyright (C) 2004-2005 Maurice Massar
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 $Id$
21 #define _GNU_SOURCE
23 #include <inttypes.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <sys/utsname.h>
32 #include <gcrypt.h>
34 #include "sysdep.h"
35 #include "config.h"
36 #include "vpnc.h"
37 #include "supp.h"
38 #include "decrypt-utils.h"
40 const char *config[LAST_CONFIG];
42 int opt_debug = 0;
43 int opt_nd;
44 int opt_1des, opt_no_encryption, opt_auth_mode;
45 enum natt_mode_enum opt_natt_mode;
46 enum vendor_enum opt_vendor;
47 enum if_mode_enum opt_if_mode;
48 uint16_t opt_udpencapport;
50 static void log_to_stderr(int priority __attribute__((unused)), const char *format, ...)
52 va_list ap;
54 va_start(ap, format);
55 vfprintf(stderr, format, ap);
56 fprintf(stderr, "\n");
57 va_end(ap);
60 void (*logmsg)(int priority, const char *format, ...) = log_to_stderr;
63 void hex_dump(const char *str, const void *data, ssize_t len, const struct debug_strings *decode)
65 size_t i;
66 const uint8_t *p = data;
67 const char *decodedval;
69 if (opt_debug < 3)
70 return;
72 printf(" ");
73 switch (len) {
74 case DUMP_UINT8:
75 decodedval = val_to_string(*(uint8_t *)p, decode);
76 printf("%s: %02x%s\n", str, *(uint8_t *)p, decodedval);
77 return;
78 case DUMP_UINT16:
79 decodedval = val_to_string(*(uint16_t *)p, decode);
80 printf("%s: %04x%s\n", str, *(uint16_t *)p, decodedval);
81 return;
82 case DUMP_UINT32:
83 decodedval = val_to_string(*(uint32_t *)p, decode);
84 printf("%s: %08x%s\n", str, *(uint32_t *)p, decodedval);
85 return;
88 printf("%s:%s", str, (len <= 16) ? " " : "\n ");
89 for (i = 0; i < (size_t)len; i++) {
90 if (i && !(i % 32))
91 printf("\n ");
92 else if (i && !(i % 4))
93 printf(" ");
94 printf("%02x", p[i]);
96 printf("\n");
99 static void config_deobfuscate(int obfuscated, int clear)
101 int ret, len = 0;
102 char *bin = NULL;
104 if (config[obfuscated] == NULL)
105 return;
107 if (config[clear] != NULL) {
108 config[obfuscated] = NULL;
109 error(0, 0, "warning: ignoring obfuscated password because cleartext password set");
110 return;
113 ret = hex2bin(config[obfuscated], &bin, &len);
114 if (ret != 0) {
115 error(1, 0, "error: deobfuscating of password failed (input not a hex string)");
118 ret = deobfuscate(bin, len, config+clear, NULL);
119 free(bin);
120 if (ret != 0) {
121 error(1, 0, "error: deobfuscating of password failed");
124 config[obfuscated] = NULL;
125 return;
128 static const char *config_def_ike_dh(void)
130 return "dh2";
133 static const char *config_def_pfs(void)
135 return "server";
138 static const char *config_def_local_addr(void)
140 return "0.0.0.0";
143 static const char *config_def_local_port(void)
145 return "500";
148 static const char *config_def_if_mode(void)
150 return "tun";
153 static const char *config_def_natt_mode(void)
155 return "natt";
158 static const char *config_def_udp_port(void)
160 return "10000";
163 static const char *config_def_dpd_idle(void)
165 return "300";
168 static const char *config_ca_dir(void)
170 return "/etc/ssl/certs";
173 static const char *config_def_auth_mode(void)
175 return "psk";
178 static const char *config_def_app_version(void)
180 struct utsname uts;
181 char *version;
183 uname(&uts);
184 asprintf(&version, "Cisco Systems VPN Client %s:%s", VERSION, uts.sysname);
185 return version;
188 static const char *config_def_script(void)
190 return "/etc/vpnc/vpnc-script";
193 static const char *config_def_pid_file(void)
195 return "/var/run/vpnc/pid";
198 static const char *config_def_vendor(void)
200 return "cisco";
203 static const char *config_def_target_network(void)
205 return "0.0.0.0/0.0.0.0";
208 static const struct config_names_s {
209 enum config_enum nm;
210 const int needsArgument;
211 const int long_only;
212 const char *option;
213 const char *name;
214 const char *type;
215 const char *desc;
216 const char *(*get_def) (void);
217 } config_names[] = {
218 /* Note: broken config file parser does NOT support option
219 * names where one is a prefix of another option. Needs just a bit work to
220 * fix the parser to care about ' ' or '\t' after the wanted
221 * option... */
223 CONFIG_IPSEC_GATEWAY, 1, 0,
224 "--gateway",
225 "IPSec gateway ",
226 "<ip/hostname>",
227 "IP/name of your IPSec gateway",
228 NULL
229 }, {
230 CONFIG_IPSEC_ID, 1, 0,
231 "--id",
232 "IPSec ID ",
233 "<ASCII string>",
234 "your group name",
235 NULL
236 }, {
237 CONFIG_IPSEC_SECRET, 1, 0,
238 NULL,
239 "IPSec secret ",
240 "<ASCII string>",
241 "your group password (cleartext)",
242 NULL
243 }, {
244 CONFIG_IPSEC_SECRET_OBF, 1, 1,
245 NULL,
246 "IPSec obfuscated secret ",
247 "<hex string>",
248 "your group password (obfuscated)",
249 NULL
250 }, {
251 CONFIG_XAUTH_USERNAME, 1, 0,
252 "--username",
253 "Xauth username ",
254 "<ASCII string>",
255 "your username",
256 NULL
257 }, {
258 CONFIG_XAUTH_PASSWORD, 1, 0,
259 NULL,
260 "Xauth password ",
261 "<ASCII string>",
262 "your password (cleartext)",
263 NULL
264 }, {
265 CONFIG_XAUTH_PASSWORD_OBF, 1, 1,
266 NULL,
267 "Xauth obfuscated password ",
268 "<hex string>",
269 "your password (obfuscated)",
270 NULL
271 }, {
272 CONFIG_DOMAIN, 1, 1,
273 "--domain",
274 "Domain ",
275 "<ASCII string>",
276 "(NT-) Domain name for authentication",
277 NULL
278 }, {
279 CONFIG_XAUTH_INTERACTIVE, 0, 1,
280 "--xauth-inter",
281 "Xauth interactive",
282 NULL,
283 "enable interactive extended authentication (for challenge response auth)",
284 NULL
285 }, {
286 CONFIG_VENDOR, 1, 1,
287 "--vendor",
288 "Vendor ",
289 "<cisco/netscreen>",
290 "vendor of your IPSec gateway",
291 config_def_vendor
292 }, {
293 CONFIG_NATT_MODE, 1, 1,
294 "--natt-mode",
295 "NAT Traversal Mode ",
296 "<natt/none/force-natt/cisco-udp>",
297 "Which NAT-Traversal Method to use:\n"
298 " * natt -- NAT-T as defined in RFC3947\n"
299 " * none -- disable use of any NAT-T method\n"
300 " * force-natt -- always use NAT-T encapsulation even\n"
301 " without presence of a NAT device\n"
302 " (useful if the OS captures all ESP traffic)\n"
303 " * cisco-udp -- Cisco proprietary UDP encapsulation, commonly over Port 10000\n"
304 "Note: cisco-tcp encapsulation is not yet supported\n",
305 config_def_natt_mode
306 }, {
307 CONFIG_SCRIPT, 1, 1,
308 "--script",
309 "Script ",
310 "<command>",
311 "command is executed using system() to configure the interface,\n"
312 "routing and so on. Device name, IP, etc. are passed using enviroment\n"
313 "variables, see README. This script is executed right after ISAKMP is\n"
314 "done, but before tunneling is enabled. It is called when vpnc\n"
315 "terminates, too\n",
316 config_def_script
317 }, {
318 CONFIG_IKE_DH, 1, 1,
319 "--dh",
320 "IKE DH Group ",
321 "<dh1/dh2/dh5>",
322 "name of the IKE DH Group",
323 config_def_ike_dh
324 }, {
325 CONFIG_IPSEC_PFS, 1, 1,
326 "--pfs",
327 "Perfect Forward Secrecy ",
328 "<nopfs/dh1/dh2/dh5/server>",
329 "Diffie-Hellman group to use for PFS",
330 config_def_pfs
331 }, {
332 CONFIG_ENABLE_1DES, 0, 1,
333 "--enable-1des",
334 "Enable Single DES",
335 NULL,
336 "enables weak single DES encryption",
337 NULL
338 }, {
339 CONFIG_ENABLE_NO_ENCRYPTION, 0, 1,
340 "--enable-no-encryption",
341 "Enable no encryption",
342 NULL,
343 "enables using no encryption for data traffic (key exchanged must be encrypted)",
344 NULL
345 }, {
346 CONFIG_VERSION, 1, 1,
347 "--application-version",
348 "Application version ",
349 "<ASCII string>",
350 "Application Version to report. Note: Default string is generated at runtime.",
351 config_def_app_version
352 }, {
353 CONFIG_IF_NAME, 1, 1,
354 "--ifname",
355 "Interface name ",
356 "<ASCII string>",
357 "visible name of the TUN/TAP interface",
358 NULL
359 }, {
360 CONFIG_IF_MODE, 1, 1,
361 "--ifmode",
362 "Interface mode ",
363 "<tun/tap>",
364 "mode of TUN/TAP interface:\n"
365 " * tun: virtual point to point interface (default)\n"
366 " * tap: virtual ethernet interface\n",
367 config_def_if_mode
368 }, {
369 CONFIG_DEBUG, 1, 1,
370 "--debug",
371 "Debug ",
372 "<0/1/2/3/99>",
373 "Show verbose debug messages\n"
374 " * 0: Do not print debug information.\n"
375 " * 1: Print minimal debug information.\n"
376 " * 2: Show statemachine and packet/payload type information.\n"
377 " * 3: Dump everything exluding authentication data.\n"
378 " * 99: Dump everything INCLUDING AUTHENTICATION data (e.g. PASSWORDS).\n",
379 NULL
380 }, {
381 CONFIG_ND, 0, 1,
382 "--no-detach",
383 "No Detach",
384 NULL,
385 "Don't detach from the console after login",
386 NULL
387 }, {
388 CONFIG_PID_FILE, 1, 1,
389 "--pid-file",
390 "Pidfile ",
391 "<filename>",
392 "store the pid of background process in <filename>",
393 config_def_pid_file
394 }, {
395 CONFIG_LOCAL_ADDR, 1, 1,
396 "--local-addr",
397 "Local Addr ",
398 "<ip/hostname>",
399 "local IP to use for ISAKMP / ESP / ... (0.0.0.0 == automatically assign)",
400 config_def_local_addr
401 }, {
402 CONFIG_LOCAL_PORT, 1, 1,
403 "--local-port",
404 "Local Port ",
405 "<0-65535>",
406 "local ISAKMP port number to use (0 == use random port)",
407 config_def_local_port
408 }, {
409 CONFIG_UDP_ENCAP_PORT, 1, 1,
410 "--udp-port",
411 "Cisco UDP Encapsulation Port ",
412 "<0-65535>",
413 "Local UDP port number to use (0 == use random port).\n"
414 "This is only relevant if cisco-udp nat-traversal is used.\n"
415 "This is the _local_ port, the remote udp port is discovered automatically.\n"
416 "It is especially not the cisco-tcp port.\n",
417 config_def_udp_port
418 }, {
419 CONFIG_DPD_IDLE, 1, 1,
420 "--dpd-idle",
421 "DPD idle timeout (our side) ",
422 "<0,10-86400>",
423 "Send DPD packet after not receiving anything for <idle> seconds.\n"
424 "Use 0 to disable DPD completely (both ways).\n",
425 config_def_dpd_idle
426 }, {
427 CONFIG_NON_INTERACTIVE, 0, 1,
428 "--non-inter",
429 "Noninteractive",
430 NULL,
431 "Don't ask anything, exit on missing options",
432 NULL
433 }, {
434 CONFIG_AUTH_MODE, 1, 1,
435 "--auth-mode",
436 "IKE Authmode ",
437 "<psk/cert/hybrid>",
438 "Authentication mode:\n"
439 " * psk: pre-shared key (default)\n"
440 " * cert: server + client certificate (not implemented yet)\n"
441 " * hybrid: server certificate + xauth (if built with openssl support)\n",
442 config_def_auth_mode
443 }, {
444 CONFIG_CA_FILE, 1, 1,
445 "--ca-file",
446 "CA-File ",
447 "<filename>",
448 "filename and path to the CA-PEM-File",
449 NULL
450 }, {
451 CONFIG_CA_DIR, 1, 1,
452 "--ca-dir",
453 "CA-Dir ",
454 "<directory>",
455 "path of the trusted CA-Directory",
456 config_ca_dir
457 }, {
458 CONFIG_IPSEC_TARGET_NETWORK, 1, 1,
459 "--target-network",
460 "IPSEC target network ",
461 "<target network/netmask>",
462 "Target network in dotted decimal or CIDR notation\n",
463 config_def_target_network
464 }, {
465 0, 0, 0, NULL, NULL, NULL, NULL, NULL
469 static char *get_config_filename(const char *name, int add_dot_conf)
471 char *realname;
473 asprintf(&realname, "%s%s%s", index(name, '/') ? "" : "/etc/vpnc/", name, add_dot_conf ? ".conf" : "");
474 return realname;
477 static void read_config_file(const char *name, const char **configs, int missingok)
479 FILE *f;
480 char *line = NULL;
481 size_t line_length = 0;
482 int linenum = 0;
483 char *realname;
485 if (!strcmp(name, "-")) {
486 f = stdin;
487 realname = strdup("stdin");
488 } else {
489 realname = get_config_filename(name, 0);
490 f = fopen(realname, "r");
491 if (f == NULL && errno == ENOENT) {
492 free(realname);
493 realname = get_config_filename(name, 1);
494 f = fopen(realname, "r");
496 if (missingok && f == NULL && errno == ENOENT) {
497 free(realname);
498 return;
500 if (f == NULL)
501 error(1, errno, "couldn't open `%s'", realname);
503 for (;;) {
504 ssize_t llen;
505 int i;
507 llen = getline(&line, &line_length, f);
508 if (llen == -1 && feof(f))
509 break;
510 if (llen == -1)
511 error(1, errno, "reading `%s'", realname);
512 if (llen > 0 && line[llen - 1] == '\n')
513 line[--llen] = 0;
514 if (llen > 0 && line[llen - 1] == '\r')
515 line[--llen] = 0;
516 linenum++;
517 for (i = 0; config_names[i].name != NULL; i++) {
518 if (strncasecmp(config_names[i].name, line,
519 strlen(config_names[i].name)) == 0) {
520 /* boolean implementation, using harmless pointer targets as true */
521 if (!config_names[i].needsArgument) {
522 configs[config_names[i].nm] = config_names[i].name;
523 break;
525 if (configs[config_names[i].nm] == NULL)
526 configs[config_names[i].nm] =
527 strdup(line + strlen(config_names[i].name));
528 if (configs[config_names[i].nm] == NULL)
529 error(1, errno, "can't allocate memory");
530 break;
533 if (config_names[i].name == NULL && line[0] != '#' && line[0] != 0)
534 error(0, 0, "warning: unknown configuration directive in %s at line %d",
535 realname, linenum);
537 free(line);
538 free(realname);
539 if (strcmp(name, "-"))
540 fclose(f);
543 static void print_desc(const char *pre, const char *text)
545 const char *p, *q;
547 for (p = text, q = strchr(p, '\n'); q; p = q+1, q = strchr(p, '\n'))
548 printf("%s%.*s\n", pre, (int)(q-p), p);
550 if (*p != '\0')
551 printf("%s%s\n", pre, p);
554 static void print_usage(char *argv0, int print_level)
556 int c;
558 printf("Usage: %s [--version] [--print-config] [--help] [--long-help] [options] [config files]\n\n",
559 argv0);
560 printf("Options:\n");
561 for (c = 0; config_names[c].name != NULL; c++) {
562 if (config_names[c].long_only > print_level)
563 continue;
565 printf(" %s %s\n", (config_names[c].option == NULL ?
566 "(configfile only option)" : config_names[c].option),
567 ((config_names[c].type == NULL || config_names[c].option == NULL) ?
568 "" : config_names[c].type));
570 print_desc(" ", config_names[c].desc);
572 if (config_names[c].get_def != NULL)
573 printf(" Default: %s\n", config_names[c].get_def());
575 printf(" conf-variable: %s%s\n", config_names[c].name,
576 (config_names[c].type == NULL ? "" : config_names[c].type));
578 printf("\n");
581 if (!print_level)
582 printf("Use --long-help to see all options\n\n");
584 printf("Report bugs to vpnc@unix-ag.uni-kl.de\n");
587 static void print_version(void)
589 unsigned int i;
591 printf("vpnc version " VERSION "\n");
592 printf("Copyright (C) 2002-2006 Geoffrey Keating, Maurice Massar, others\n");
593 printf("vpnc comes with NO WARRANTY, to the extent permitted by law.\n"
594 "You may redistribute copies of vpnc under the terms of the GNU General\n"
595 "Public License. For more information about these matters, see the files\n"
596 "named COPYING.\n");
597 #ifdef OPENSSL_GPL_VIOLATION
598 printf("Built with openssl certificate support. Be aware of the\n"
599 "license implications.\n");
600 #else /* OPENSSL_GPL_VIOLATION */
601 printf("Built with certificate support.\n");
602 #endif /* OPENSSL_GPL_VIOLATION */
603 printf("\n");
605 printf("Supported DH-Groups:");
606 for (i = 0; supp_dh_group[i].name != NULL; i++)
607 printf(" %s", supp_dh_group[i].name);
608 printf("\n");
610 printf("Supported Hash-Methods:");
611 for (i = 0; supp_hash[i].name != NULL; i++)
612 printf(" %s", supp_hash[i].name);
613 printf("\n");
615 printf("Supported Encryptions:");
616 for (i = 0; supp_crypt[i].name != NULL; i++)
617 printf(" %s", supp_crypt[i].name);
618 printf("\n");
620 printf("Supported Auth-Methods:");
621 for (i = 0; supp_auth[i].name != NULL; i++)
622 printf(" %s", supp_auth[i].name);
623 printf("\n");
626 void do_config(int argc, char **argv)
628 char *s;
629 int i, c, known;
630 int got_conffile = 0, print_config = 0;
631 size_t s_len;
633 for (i = 1; i < argc; i++) {
634 if (argv[i][0] && (argv[i][0] != '-' || argv[i][1] == '\0')) {
635 read_config_file(argv[i], config, 0);
636 got_conffile = 1;
637 continue;
640 known = 0;
642 for (c = 0; config_names[c].name != NULL && !known; c++) {
643 if (config_names[c].option == NULL
644 || strncmp(argv[i], config_names[c].option,
645 strlen(config_names[c].option)) != 0)
646 continue;
648 s = NULL;
650 known = 1;
651 if (argv[i][strlen(config_names[c].option)] == '=')
652 s = argv[i] + strlen(config_names[c].option) + 1;
653 else if (argv[i][strlen(config_names[c].option)] == 0) {
654 if (config_names[c].needsArgument) {
655 if (i + 1 < argc)
656 s = argv[++i];
657 else
658 known = 0;
659 } else
660 s = argv[i]; /* no arg, fill in something */
661 } else
662 known = 0;
663 if (known)
664 config[config_names[c].nm] = s;
667 if (!known && strcmp(argv[i], "--version") == 0) {
668 print_version();
669 exit(0);
671 if (!known && strcmp(argv[i], "--print-config") == 0) {
672 print_config = 1;
673 known = 1;
675 if (!known && strcmp(argv[i], "--help") == 0) {
676 print_usage(argv[0], 0);
677 exit(0);
679 if (!known && strcmp(argv[i], "--long-help") == 0) {
680 print_usage(argv[0], 1);
681 exit(0);
683 if (!known) {
684 printf("%s: unknown option %s\n\n", argv[0], argv[i]);
686 print_usage(argv[0], 1);
687 exit(1);
691 if (!got_conffile) {
692 read_config_file("/etc/vpnc/default.conf", config, 1);
693 read_config_file("/etc/vpnc.conf", config, 1);
696 if (!print_config) {
697 for (i = 0; config_names[i].name != NULL; i++)
698 if (!config[config_names[i].nm]
699 && config_names[i].get_def != NULL)
700 config[config_names[i].nm] = config_names[i].get_def();
702 opt_debug = (config[CONFIG_DEBUG]) ? atoi(config[CONFIG_DEBUG]) : 0;
703 opt_nd = (config[CONFIG_ND]) ? 1 : 0;
704 opt_1des = (config[CONFIG_ENABLE_1DES]) ? 1 : 0;
706 if (!strcmp(config[CONFIG_AUTH_MODE], "psk")) {
707 opt_auth_mode = AUTH_MODE_PSK;
708 } else if (!strcmp(config[CONFIG_AUTH_MODE], "cert")) {
709 opt_auth_mode = AUTH_MODE_CERT;
710 } else if (!strcmp(config[CONFIG_AUTH_MODE], "hybrid")) {
711 opt_auth_mode = AUTH_MODE_HYBRID;
712 } else {
713 printf("%s: unknown authentication mode %s\nknown modes: psk cert hybrid\n", argv[0], config[CONFIG_AUTH_MODE]);
714 exit(1);
716 opt_no_encryption = (config[CONFIG_ENABLE_NO_ENCRYPTION]) ? 1 : 0;
717 opt_udpencapport=atoi(config[CONFIG_UDP_ENCAP_PORT]);
719 if (!strcmp(config[CONFIG_NATT_MODE], "natt")) {
720 opt_natt_mode = NATT_NORMAL;
721 } else if (!strcmp(config[CONFIG_NATT_MODE], "none")) {
722 opt_natt_mode = NATT_NONE;
723 } else if (!strcmp(config[CONFIG_NATT_MODE], "force-natt")) {
724 opt_natt_mode = NATT_FORCE;
725 } else if (!strcmp(config[CONFIG_NATT_MODE], "cisco-udp")) {
726 opt_natt_mode = NATT_CISCO_UDP;
727 } else {
728 printf("%s: unknown nat traversal mode %s\nknown modes: natt none force-natt cisco-udp\n", argv[0], config[CONFIG_NATT_MODE]);
729 exit(1);
732 if (!strcmp(config[CONFIG_IF_MODE], "tun")) {
733 opt_if_mode = IF_MODE_TUN;
734 } else if (!strcmp(config[CONFIG_IF_MODE], "tap")) {
735 opt_if_mode = IF_MODE_TAP;
736 } else {
737 printf("%s: unknown interface mode %s\nknown modes: tun tap\n", argv[0], config[CONFIG_IF_MODE]);
738 exit(1);
741 if (!strcmp(config[CONFIG_VENDOR], "cisco")) {
742 opt_vendor = VENDOR_CISCO;
743 } else if (!strcmp(config[CONFIG_VENDOR], "netscreen")) {
744 opt_vendor = VENDOR_NETSCREEN;
745 } else {
746 printf("%s: unknown vendor %s\nknown vendors: cisco netscreen\n", argv[0], config[CONFIG_VENDOR]);
747 exit(1);
751 if (opt_debug >= 99) {
752 printf("WARNING! active debug level is >= 99, output includes username and password (hex encoded)\n");
753 fprintf(stderr,
754 "WARNING! active debug level is >= 99, output includes username and password (hex encoded)\n");
757 config_deobfuscate(CONFIG_IPSEC_SECRET_OBF, CONFIG_IPSEC_SECRET);
758 config_deobfuscate(CONFIG_XAUTH_PASSWORD_OBF, CONFIG_XAUTH_PASSWORD);
760 for (i = 0; i < LAST_CONFIG; i++) {
761 if (config[i] != NULL || config[CONFIG_NON_INTERACTIVE] != NULL)
762 continue;
763 if (config[CONFIG_XAUTH_INTERACTIVE] && i == CONFIG_XAUTH_PASSWORD)
764 continue;
766 s = NULL;
767 s_len = 0;
769 switch (i) {
770 case CONFIG_IPSEC_GATEWAY:
771 printf("Enter IPSec gateway address: ");
772 break;
773 case CONFIG_IPSEC_ID:
774 printf("Enter IPSec ID for %s: ", config[CONFIG_IPSEC_GATEWAY]);
775 break;
776 case CONFIG_IPSEC_SECRET:
777 printf("Enter IPSec secret for %s@%s: ",
778 config[CONFIG_IPSEC_ID], config[CONFIG_IPSEC_GATEWAY]);
779 break;
780 case CONFIG_XAUTH_USERNAME:
781 printf("Enter username for %s: ", config[CONFIG_IPSEC_GATEWAY]);
782 break;
783 case CONFIG_XAUTH_PASSWORD:
784 printf("Enter password for %s@%s: ",
785 config[CONFIG_XAUTH_USERNAME],
786 config[CONFIG_IPSEC_GATEWAY]);
787 break;
788 default:
789 continue;
791 fflush(stdout);
792 switch (i) {
793 case CONFIG_IPSEC_SECRET:
794 case CONFIG_XAUTH_PASSWORD:
795 s = strdup(getpass(""));
796 break;
797 case CONFIG_IPSEC_GATEWAY:
798 case CONFIG_IPSEC_ID:
799 case CONFIG_XAUTH_USERNAME:
800 getline(&s, &s_len, stdin);
802 if (s != NULL && strlen(s) > 0 && s[strlen(s) - 1] == '\n')
803 s[strlen(s) - 1] = 0;
804 config[i] = s;
807 if (print_config) {
808 fprintf(stderr, "vpnc.conf:\n\n");
809 for (i = 0; config_names[i].name != NULL; i++) {
810 if (config[config_names[i].nm] == NULL)
811 continue;
812 printf("%s%s\n", config_names[i].name,
813 config_names[i].needsArgument ?
814 config[config_names[i].nm] : "");
816 exit(0);
819 if (!config[CONFIG_IPSEC_GATEWAY])
820 error(1, 0, "missing IPSec gatway address");
821 if (!config[CONFIG_IPSEC_ID])
822 error(1, 0, "missing IPSec ID");
823 if (!config[CONFIG_IPSEC_SECRET])
824 error(1, 0, "missing IPSec secret");
825 if (!config[CONFIG_XAUTH_USERNAME])
826 error(1, 0, "missing Xauth username");
827 if (!config[CONFIG_XAUTH_PASSWORD] && !config[CONFIG_XAUTH_INTERACTIVE])
828 error(1, 0, "missing Xauth password");
829 if (get_dh_group_ike() == NULL)
830 error(1, 0, "IKE DH Group \"%s\" unsupported\n", config[CONFIG_IKE_DH]);
831 if (get_dh_group_ipsec(-1) == NULL)
832 error(1, 0, "Perfect Forward Secrecy \"%s\" unsupported\n",
833 config[CONFIG_IPSEC_PFS]);
834 if (get_dh_group_ike()->ike_sa_id == 0)
835 error(1, 0, "IKE DH Group must not be nopfs\n");
837 return;