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
30 #include <sys/utsname.h>
38 #include "decrypt-utils.h"
40 const char *config
[LAST_CONFIG
];
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
, ...)
55 vfprintf(stderr
, format
, ap
);
56 fprintf(stderr
, "\n");
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
)
66 const uint8_t *p
= data
;
67 const char *decodedval
;
75 decodedval
= val_to_string(*(uint8_t *)p
, decode
);
76 printf("%s: %02x%s\n", str
, *(uint8_t *)p
, decodedval
);
79 decodedval
= val_to_string(*(uint16_t *)p
, decode
);
80 printf("%s: %04x%s\n", str
, *(uint16_t *)p
, decodedval
);
83 decodedval
= val_to_string(*(uint32_t *)p
, decode
);
84 printf("%s: %08x%s\n", str
, *(uint32_t *)p
, decodedval
);
88 printf("%s:%s", str
, (len
<= 16) ? " " : "\n ");
89 for (i
= 0; i
< (size_t)len
; i
++) {
92 else if (i
&& !(i
% 4))
99 static void config_deobfuscate(int obfuscated
, int clear
)
104 if (config
[obfuscated
] == NULL
)
107 if (config
[clear
] != NULL
) {
108 config
[obfuscated
] = NULL
;
109 error(0, 0, "warning: ignoring obfuscated password because cleartext password set");
113 ret
= hex2bin(config
[obfuscated
], &bin
, &len
);
115 error(1, 0, "error: deobfuscating of password failed (input not a hex string)");
118 ret
= deobfuscate(bin
, len
, config
+clear
, NULL
);
121 error(1, 0, "error: deobfuscating of password failed");
124 config
[obfuscated
] = NULL
;
128 static const char *config_def_ike_dh(void)
133 static const char *config_def_pfs(void)
138 static const char *config_def_local_addr(void)
143 static const char *config_def_local_port(void)
148 static const char *config_def_if_mode(void)
153 static const char *config_def_natt_mode(void)
158 static const char *config_def_udp_port(void)
163 static const char *config_def_dpd_idle(void)
168 static const char *config_ca_dir(void)
170 return "/etc/ssl/certs";
173 static const char *config_def_auth_mode(void)
178 static const char *config_def_app_version(void)
184 asprintf(&version
, "Cisco Systems VPN Client %s:%s", VERSION
, uts
.sysname
);
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)
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
{
210 const int needsArgument
;
216 const char *(*get_def
) (void);
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
223 CONFIG_IPSEC_GATEWAY
, 1, 0,
227 "IP/name of your IPSec gateway",
230 CONFIG_IPSEC_ID
, 1, 0,
237 CONFIG_IPSEC_SECRET
, 1, 0,
241 "your group password (cleartext)",
244 CONFIG_IPSEC_SECRET_OBF
, 1, 1,
246 "IPSec obfuscated secret ",
248 "your group password (obfuscated)",
251 CONFIG_XAUTH_USERNAME
, 1, 0,
258 CONFIG_XAUTH_PASSWORD
, 1, 0,
262 "your password (cleartext)",
265 CONFIG_XAUTH_PASSWORD_OBF
, 1, 1,
267 "Xauth obfuscated password ",
269 "your password (obfuscated)",
276 "(NT-) Domain name for authentication",
279 CONFIG_XAUTH_INTERACTIVE
, 0, 1,
283 "enable interactive extended authentication (for challenge response auth)",
290 "vendor of your IPSec gateway",
293 CONFIG_NATT_MODE
, 1, 1,
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",
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"
322 "name of the IKE DH Group",
325 CONFIG_IPSEC_PFS
, 1, 1,
327 "Perfect Forward Secrecy ",
328 "<nopfs/dh1/dh2/dh5/server>",
329 "Diffie-Hellman group to use for PFS",
332 CONFIG_ENABLE_1DES
, 0, 1,
336 "enables weak single DES encryption",
339 CONFIG_ENABLE_NO_ENCRYPTION
, 0, 1,
340 "--enable-no-encryption",
341 "Enable no encryption",
343 "enables using no encryption for data traffic (key exchanged must be encrypted)",
346 CONFIG_VERSION
, 1, 1,
347 "--application-version",
348 "Application version ",
350 "Application Version to report. Note: Default string is generated at runtime.",
351 config_def_app_version
353 CONFIG_IF_NAME
, 1, 1,
357 "visible name of the TUN/TAP interface",
360 CONFIG_IF_MODE
, 1, 1,
364 "mode of TUN/TAP interface:\n"
365 " * tun: virtual point to point interface (default)\n"
366 " * tap: virtual ethernet interface\n",
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",
385 "Don't detach from the console after login",
388 CONFIG_PID_FILE
, 1, 1,
392 "store the pid of background process in <filename>",
395 CONFIG_LOCAL_ADDR
, 1, 1,
399 "local IP to use for ISAKMP / ESP / ... (0.0.0.0 == automatically assign)",
400 config_def_local_addr
402 CONFIG_LOCAL_PORT
, 1, 1,
406 "local ISAKMP port number to use (0 == use random port)",
407 config_def_local_port
409 CONFIG_UDP_ENCAP_PORT
, 1, 1,
411 "Cisco UDP Encapsulation Port ",
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",
419 CONFIG_DPD_IDLE
, 1, 1,
421 "DPD idle timeout (our side) ",
423 "Send DPD packet after not receiving anything for <idle> seconds.\n"
424 "Use 0 to disable DPD completely (both ways).\n",
427 CONFIG_NON_INTERACTIVE
, 0, 1,
431 "Don't ask anything, exit on missing options",
434 CONFIG_AUTH_MODE
, 1, 1,
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",
444 CONFIG_CA_FILE
, 1, 1,
448 "filename and path to the CA-PEM-File",
455 "path of the trusted CA-Directory",
458 CONFIG_IPSEC_TARGET_NETWORK
, 1, 1,
460 "IPSEC target network ",
461 "<target network/netmask>",
462 "Target network in dotted decimal or CIDR notation\n",
463 config_def_target_network
465 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
469 static char *get_config_filename(const char *name
, int add_dot_conf
)
473 asprintf(&realname
, "%s%s%s", index(name
, '/') ? "" : "/etc/vpnc/", name
, add_dot_conf
? ".conf" : "");
477 static void read_config_file(const char *name
, const char **configs
, int missingok
)
481 size_t line_length
= 0;
485 if (!strcmp(name
, "-")) {
487 realname
= strdup("stdin");
489 realname
= get_config_filename(name
, 0);
490 f
= fopen(realname
, "r");
491 if (f
== NULL
&& errno
== ENOENT
) {
493 realname
= get_config_filename(name
, 1);
494 f
= fopen(realname
, "r");
496 if (missingok
&& f
== NULL
&& errno
== ENOENT
) {
501 error(1, errno
, "couldn't open `%s'", realname
);
507 llen
= getline(&line
, &line_length
, f
);
508 if (llen
== -1 && feof(f
))
511 error(1, errno
, "reading `%s'", realname
);
512 if (llen
> 0 && line
[llen
- 1] == '\n')
514 if (llen
> 0 && line
[llen
- 1] == '\r')
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
;
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");
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",
539 if (strcmp(name
, "-"))
543 static void print_desc(const char *pre
, const char *text
)
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
);
551 printf("%s%s\n", pre
, p
);
554 static void print_usage(char *argv0
, int print_level
)
558 printf("Usage: %s [--version] [--print-config] [--help] [--long-help] [options] [config files]\n\n",
560 printf("Options:\n");
561 for (c
= 0; config_names
[c
].name
!= NULL
; c
++) {
562 if (config_names
[c
].long_only
> print_level
)
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
));
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)
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"
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 */
605 printf("Supported DH-Groups:");
606 for (i
= 0; supp_dh_group
[i
].name
!= NULL
; i
++)
607 printf(" %s", supp_dh_group
[i
].name
);
610 printf("Supported Hash-Methods:");
611 for (i
= 0; supp_hash
[i
].name
!= NULL
; i
++)
612 printf(" %s", supp_hash
[i
].name
);
615 printf("Supported Encryptions:");
616 for (i
= 0; supp_crypt
[i
].name
!= NULL
; i
++)
617 printf(" %s", supp_crypt
[i
].name
);
620 printf("Supported Auth-Methods:");
621 for (i
= 0; supp_auth
[i
].name
!= NULL
; i
++)
622 printf(" %s", supp_auth
[i
].name
);
626 void do_config(int argc
, char **argv
)
630 int got_conffile
= 0, print_config
= 0;
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);
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)
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
) {
660 s
= argv
[i
]; /* no arg, fill in something */
664 config
[config_names
[c
].nm
] = s
;
667 if (!known
&& strcmp(argv
[i
], "--version") == 0) {
671 if (!known
&& strcmp(argv
[i
], "--print-config") == 0) {
675 if (!known
&& strcmp(argv
[i
], "--help") == 0) {
676 print_usage(argv
[0], 0);
679 if (!known
&& strcmp(argv
[i
], "--long-help") == 0) {
680 print_usage(argv
[0], 1);
684 printf("%s: unknown option %s\n\n", argv
[0], argv
[i
]);
686 print_usage(argv
[0], 1);
692 read_config_file("/etc/vpnc/default.conf", config
, 1);
693 read_config_file("/etc/vpnc.conf", config
, 1);
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
;
713 printf("%s: unknown authentication mode %s\nknown modes: psk cert hybrid\n", argv
[0], config
[CONFIG_AUTH_MODE
]);
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
;
728 printf("%s: unknown nat traversal mode %s\nknown modes: natt none force-natt cisco-udp\n", argv
[0], config
[CONFIG_NATT_MODE
]);
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
;
737 printf("%s: unknown interface mode %s\nknown modes: tun tap\n", argv
[0], config
[CONFIG_IF_MODE
]);
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
;
746 printf("%s: unknown vendor %s\nknown vendors: cisco netscreen\n", argv
[0], config
[CONFIG_VENDOR
]);
751 if (opt_debug
>= 99) {
752 printf("WARNING! active debug level is >= 99, output includes username and password (hex encoded)\n");
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
)
763 if (config
[CONFIG_XAUTH_INTERACTIVE
] && i
== CONFIG_XAUTH_PASSWORD
)
770 case CONFIG_IPSEC_GATEWAY
:
771 printf("Enter IPSec gateway address: ");
773 case CONFIG_IPSEC_ID
:
774 printf("Enter IPSec ID for %s: ", config
[CONFIG_IPSEC_GATEWAY
]);
776 case CONFIG_IPSEC_SECRET
:
777 printf("Enter IPSec secret for %s@%s: ",
778 config
[CONFIG_IPSEC_ID
], config
[CONFIG_IPSEC_GATEWAY
]);
780 case CONFIG_XAUTH_USERNAME
:
781 printf("Enter username for %s: ", config
[CONFIG_IPSEC_GATEWAY
]);
783 case CONFIG_XAUTH_PASSWORD
:
784 printf("Enter password for %s@%s: ",
785 config
[CONFIG_XAUTH_USERNAME
],
786 config
[CONFIG_IPSEC_GATEWAY
]);
793 case CONFIG_IPSEC_SECRET
:
794 case CONFIG_XAUTH_PASSWORD
:
795 s
= strdup(getpass(""));
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;
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
)
812 printf("%s%s\n", config_names
[i
].name
,
813 config_names
[i
].needsArgument
?
814 config
[config_names
[i
].nm
] : "");
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");