From 75848790a1a85452293319239df9c040750ce2ab Mon Sep 17 00:00:00 2001 From: "massar@UNIX-AG.UNI-KL.DE" Date: Sun, 30 May 2004 15:42:39 +0000 Subject: [PATCH] split out option parsing to config.c fixed byte order of hex_dump output git-svn-id: https://svn.unix-ag.uni-kl.de/vpnc/trunk@17 315857ad-0bdb-0310-b42e-dec37551a5f0 --- Makefile | 9 +- config.c | 547 +++++++++++++++++++++++++++++++++++++++++++++++++++++ vpnc.h => config.h | 44 ++++- isakmp-pkt.c | 74 ++++---- tunip.c | 1 + vpnc.c | 512 ++----------------------------------------------- vpnc.h | 18 +- 7 files changed, 659 insertions(+), 546 deletions(-) create mode 100644 config.c copy vpnc.h => config.h (55%) diff --git a/Makefile b/Makefile index d79e504..4a42464 100644 --- a/Makefile +++ b/Makefile @@ -40,12 +40,13 @@ LDFLAGS += -lnsl -lresolv -lsocket SYSDEP=sysdep-svr4.o endif -vpnc : vpnc.o isakmp-pkt.o tunip.o $(SYSDEP) dh.o math_group.o +vpnc : vpnc.o isakmp-pkt.o tunip.o config.o $(SYSDEP) dh.o math_group.o $(CC) -o $@ $^ $(LDFLAGS) -vpnc.o : isakmp.h isakmp-pkt.h dh.h sysdep.h math_group.h vpnc.h VERSION -isakmp-pkt.o : isakmp.h isakmp-pkt.h vpnc.h -tunip.o : sysdep.h vpnc.h +vpnc.o : isakmp.h isakmp-pkt.h dh.h sysdep.h math_group.h config.h VERSION +isakmp-pkt.o : isakmp.h isakmp-pkt.h config.h +tunip.o : sysdep.h vpnc.h config.h +config.o : vpnc.h config.h VERSION dh.o : dh.h math_group.h math_group.o : math_group.h diff --git a/config.c b/config.c new file mode 100644 index 0000000..afa79db --- /dev/null +++ b/config.c @@ -0,0 +1,547 @@ +/* IPSec VPN client compatible with Cisco equipment. + Copyright (C) 2004 Maurice Massar + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#include "sysdep.h" +#include "config.h" +#include "vpnc.h" + +/* +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "isakmp-pkt.h" +#include "math_group.h" +#include "dh.h" +*/ + +const char *config[LAST_CONFIG]; + +int opt_debug = 0; +int opt_nd; +int opt_1des; + +void hex_dump(const char *str, const void *data, ssize_t len) +{ + size_t i; + const uint8_t *p = data; + + if (opt_debug < 3) + return; + + switch (len) { + case UINT8: + printf("%s: %02x\n", str, *(uint8_t *)p); + return; + case UINT16: + printf("%s: %04x\n", str, *(uint16_t *)p); + return; + case UINT32: + printf("%s: %08x\n", str, *(uint32_t *)p); + return; + } + + printf("%s:%c", str, (len <= 32) ? ' ' : '\n'); + for (i = 0; i < (size_t)len; i++) { + if (i && !(i % 32)) + printf("\n"); + else if (i && !(i % 4)) + printf(" "); + printf("%02x", p[i]); + } + printf("\n"); +} + +static const char *config_def_description(void) +{ + return "default value for this option"; +} + +static const char *config_def_ike_dh(void) +{ + return "dh2"; +} + +static const char *config_def_pfs(void) +{ + return "server"; +} + +static const char *config_def_local_port(void) +{ + return "500"; +} + +static const char *config_def_app_version(void) +{ + struct utsname uts; + char *version; + + uname(&uts); + asprintf(&version, "Cisco Systems VPN Client %s:%s", VERSION, uts.sysname); + return version; +} + +static const struct config_names_s { + enum config_enum nm; + const int needsArgument; + const int lvl; + const char *option; + const char *name; + const char *type; + const char *desc; + const char *(*get_def) (void); +} config_names[] = { + /* Note: broken config file parser does NOT support option + * names where one is a prefix of another option. Needs just a bit work to + * fix the parser to care about ' ' or '\t' after the wanted + * option... */ + { + CONFIG_NONE, 0, 0, + "commandline option,", + "configfile variable, ", + "argument type", + "description", + config_def_description + }, { + CONFIG_IPSEC_GATEWAY, 1, 0, + "--gateway", + "IPSec gateway ", + "", + "IP/name of your IPSec gateway", + NULL + }, { + CONFIG_IPSEC_ID, 1, 0, + "--id", + "IPSec ID ", + "", + "your group name", + NULL + }, { + CONFIG_IPSEC_SECRET, 1, 0, + NULL, + "IPSec secret ", + "", + "your group password (cleartext, no support for obfuscated strings)", + NULL + }, { + CONFIG_XAUTH_USERNAME, 1, 0, + "--username", + "Xauth username ", + "", + "your username", + NULL + }, { + CONFIG_XAUTH_PASSWORD, 1, 0, + NULL, + "Xauth password ", + "", + "your password (cleartext, no support for obfuscated strings)", + NULL + }, { + CONFIG_DOMAIN, 1, 1, + "--domain", + "Domain ", + "", + "(NT-) Domain name for authentication", + NULL + }, { + CONFIG_XAUTH_INTERACTIVE, 0, 1, + "--xauth-inter", + "Xauth interactive", + NULL, + "enable interactive extended authentication (for challange response auth)", + NULL + }, { + CONFIG_CONFIG_SCRIPT, 1, 1, + "--script", + "Config Script ", + "", + "command is executed using system() to configure the interface,\n" + "routing and so on. Device name, IP, etc. are passed using enviroment\n" + "variables, see README. This script is executed right after ISAKMP is\n" + "done, but befor tunneling is enabled.\n", + sysdep_config_script + }, { + CONFIG_IKE_DH, 1, 1, + "--dh", + "IKE DH Group ", + "", + "name of the IKE DH Group", + config_def_ike_dh + }, { + CONFIG_IPSEC_PFS, 1, 1, + "--pfs", + "Perfect Forward Secrecy ", + "", + "Diffie-Hellman group to use for PFS", + config_def_pfs + }, { + CONFIG_ENABLE_1DES, 0, 1, + "--enable-1des", + "Enable Single DES", + NULL, + "enables weak single DES encryption", + NULL + }, { + CONFIG_VERSION, 1, 1, + "--application-version", + "Application version ", + "", + "Application Version to report", + config_def_app_version + }, { + CONFIG_IF_NAME, 1, 1, + "--ifname", + "Interface name ", + "", + "visible name of the TUN interface", + NULL + }, { + CONFIG_DEBUG, 1, 1, + "--debug", + "Debug ", + "<0/1/2/3/99>", + "Show verbose debug messages", + NULL + }, { + CONFIG_ND, 0, 1, + "--no-detach", + "No Detach", + NULL, + "Don't detach from the console after login", + NULL + }, { + CONFIG_PID_FILE, 1, 1, + "--pid-file", + "Pidfile ", + "", + "store the pid of background process in ", + NULL + }, { + CONFIG_LOCAL_PORT, 1, 1, + "--local-port", + "Local Port ", + "<0-65535>", + "local ISAKMP port number to use (0 == use random port)", + config_def_local_port + }, { + CONFIG_NON_INTERACTIVE, 0, 1, + "--non-inter", + "Noninteractive", + NULL, + "Don't ask anything, exit on missing options", + NULL + }, { + 0, 0, 0, NULL, NULL, NULL, NULL, NULL + } +}; + +static void read_config_file(char *name, const char **configs, int missingok) +{ + FILE *f; + char *line = NULL; + ssize_t line_length = 0; + int linenum = 0; + + f = fopen(name, "r"); + if (missingok && f == NULL && errno == ENOENT) + return; + if (f == NULL) + error(1, errno, "couldn't open `%s'", name); + for (;;) { + ssize_t llen; + int i; + + llen = getline(&line, &line_length, f); + if (llen == -1 && feof(f)) + break; + if (llen == -1) + error(1, errno, "reading `%s'", name); + if (line[llen - 1] == '\n') + line[llen - 1] = 0; + linenum++; + for (i = 0; config_names[i].name != NULL; i++) { + if (config_names[i].nm == CONFIG_NONE) + continue; + if (strncasecmp(config_names[i].name, line, + strlen(config_names[i].name)) == 0) { + // boolean implementation, using harmles pointer targets as true + if (!config_names[i].needsArgument) { + configs[config_names[i].nm] = config_names[i].name; + break; + } + if (configs[config_names[i].nm] == NULL) + configs[config_names[i].nm] = + strdup(line + strlen(config_names[i].name)); + if (configs[config_names[i].nm] == NULL) + error(1, errno, "can't allocate memory"); + break; + } + } + if (config_names[i].name == NULL && line[0] != '#' && line[0] != 0) + error(0, 0, "warning: unknown configuration directive in %s at line %d", + name, linenum); + } +} + +static void print_desc(const char *pre, const char *text) +{ + const char *p, *q; + + for (p = text, q = strchr(p, '\n'); q; p = q+1, q = strchr(p, '\n')) + printf("%s%.*s\n", pre, q-p, p); + + if (*p != '\0') + printf("%s%s\n", pre, p); +} + +static void print_usage(char *argv0, int long_help) +{ + int c; + + printf("Usage: %s [--version] [--print-config] [--help] [--long-help] [options] [config file]\n\n", + argv0); + printf("Legend:\n"); + for (c = 0; config_names[c].name != NULL; c++) { + if (config_names[c].lvl > long_help) + continue; + + printf(" %s %s\n" + " %s%s\n", + (config_names[c].option == NULL ? "(configfile only option)" : + config_names[c].option), + ((config_names[c].type == NULL || config_names[c].option == NULL) ? + "" : config_names[c].type), + config_names[c].name, + (config_names[c].type == NULL ? "" : config_names[c].type)); + print_desc(" ", config_names[c].desc); + + if (config_names[c].get_def != NULL) + printf(" Default: %s\n", config_names[c].get_def()); + + printf("\n"); + } + printf("Report bugs to vpnc@unix-ag.uni-kl.de\n"); +} + +static void print_version(void) +{ + unsigned int i; + + printf("vpnc version " VERSION "\n"); + printf("Copyright (C) 2002-2004 Geoffrey Keating, Maurice Massar\n"); + printf("vpnc comes with NO WARRANTY, to the extent permitted by law.\n" + "You may redistribute copies of vpnc under the terms of the GNU General\n" + "Public License. For more information about these matters, see the files\n" + "named COPYING.\n"); + printf("\n"); + + printf("Supported DH-Groups:"); + for (i = 0; supp_dh_group[i].name != NULL; i++) + printf(" %s", supp_dh_group[i].name); + printf("\n"); + + printf("Supported Hash-Methods:"); + for (i = 0; supp_hash[i].name != NULL; i++) + printf(" %s", supp_hash[i].name); + printf("\n"); + + printf("Supported Encryptions:"); + for (i = 0; supp_crypt[i].name != NULL; i++) + printf(" %s", supp_crypt[i].name); + printf("\n"); +} + +void do_config(int argc, char **argv) +{ + char *s; + int i, c, known, s_len; + int print_config = 0; + + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + read_config_file(argv[i], config, 0); + continue; + } + + known = 0; + + for (c = 0; config_names[c].name != NULL && !known; c++) { + if (config_names[c].option == NULL + || config_names[c].nm == CONFIG_NONE + || strncmp(argv[i], config_names[c].option, + strlen(config_names[c].option)) != 0) + continue; + + s = NULL; + + known = 1; + if (argv[i][strlen(config_names[c].option)] == '=') + s = argv[i] + strlen(config_names[c].option) + 1; + else if (argv[i][strlen(config_names[c].option)] == 0) { + if (config_names[c].needsArgument) { + if (i + 1 < argc) + s = argv[++i]; + else + known = 0; + } else + s = argv[i]; /* no arg, fill in something */ + } else + known = 0; + if (known) + config[config_names[c].nm] = s; + } + + if (!known && strcmp(argv[i], "--version") == 0) { + print_version(); + exit(0); + } + if (!known && strcmp(argv[i], "--print-config") == 0) { + print_config = 1; + known = 1; + } + if (!known && strcmp(argv[i], "--help") == 0) { + print_usage(argv[0], 0); + exit(0); + } + if (!known && strcmp(argv[i], "--long-help") == 0) { + print_usage(argv[0], 1); + exit(0); + } + if (!known) { + printf("%s: unknown option %s\n\n", argv[0], argv[i]); + + print_usage(argv[0], 1); + exit(1); + } + } + + read_config_file("/etc/vpnc/default.conf", config, 1); + read_config_file("/etc/vpnc.conf", config, 1); + + if (!print_config) + for (i = 0; config_names[i].name != NULL; i++) + if (!config[config_names[i].nm] && i != CONFIG_NONE + && config_names[i].get_def != NULL) + config[config_names[i].nm] = config_names[i].get_def(); + + opt_debug = (config[CONFIG_DEBUG]) ? atoi(config[CONFIG_DEBUG]) : 0; + opt_nd = (config[CONFIG_ND]) ? 1 : 0; + opt_1des = (config[CONFIG_ENABLE_1DES]) ? 1 : 0; + + if (opt_debug >= 99) { + printf("WARNING! active debug level is >= 99, output includes username and password (hex encoded)\n"); + fprintf(stderr, + "WARNING! active debug level is >= 99, output includes username and password (hex encoded)\n"); + } + + for (i = 0; i < LAST_CONFIG; i++) { + if (config[i] != NULL || config[CONFIG_NON_INTERACTIVE] != NULL) + continue; + + s = NULL; + s_len = 0; + + switch (i) { + case CONFIG_IPSEC_GATEWAY: + printf("Enter IPSec gateway address: "); + break; + case CONFIG_IPSEC_ID: + printf("Enter IPSec ID for %s: ", config[CONFIG_IPSEC_GATEWAY]); + break; + case CONFIG_IPSEC_SECRET: + printf("Enter IPSec secret for %s@%s: ", + config[CONFIG_IPSEC_ID], config[CONFIG_IPSEC_GATEWAY]); + break; + case CONFIG_XAUTH_USERNAME: + printf("Enter username for %s: ", config[CONFIG_IPSEC_GATEWAY]); + break; + case CONFIG_XAUTH_PASSWORD: + printf("Enter password for %s@%s: ", + config[CONFIG_XAUTH_USERNAME], + config[CONFIG_IPSEC_GATEWAY]); + break; + } + fflush(stdout); + switch (i) { + case CONFIG_IPSEC_SECRET: + case CONFIG_XAUTH_PASSWORD: + s = strdup(getpass("")); + break; + case CONFIG_IPSEC_GATEWAY: + case CONFIG_IPSEC_ID: + case CONFIG_XAUTH_USERNAME: + getline(&s, &s_len, stdin); + } + if (s != NULL && s[strlen(s) - 1] == '\n') + s[strlen(s) - 1] = 0; + config[i] = s; + } + + if (print_config) { + fprintf(stderr, "vpnc.conf:\n\n"); + for (i = 0; config_names[i].name != NULL; i++) { + if (config[config_names[i].nm] == NULL) + continue; + printf("%s%s\n", config_names[i].name, + config_names[i].needsArgument ? + config[config_names[i].nm] : ""); + } + exit(0); + } + + if (!config[CONFIG_IPSEC_GATEWAY]) + error(1, 0, "missing IPSec gatway address"); + if (!config[CONFIG_IPSEC_ID]) + error(1, 0, "missing IPSec ID"); + if (!config[CONFIG_IPSEC_SECRET]) + error(1, 0, "missing IPSec secret"); + if (!config[CONFIG_XAUTH_USERNAME]) + error(1, 0, "missing Xauth username"); + if (!config[CONFIG_XAUTH_PASSWORD]) + error(1, 0, "missing Xauth password"); + if (get_dh_group_ike() == NULL) + error(1, 0, "IKE DH Group \"%s\" unsupported\n", config[CONFIG_IKE_DH]); + if (get_dh_group_ipsec(-1) == NULL) + error(1, 0, "Perfect Forward Secrecy \"%s\" unsupported\n", + config[CONFIG_IPSEC_PFS]); + if (get_dh_group_ike()->ike_sa_id == 0) + error(1, 0, "IKE DH Group must not be nopfs\n"); + + return; +} diff --git a/vpnc.h b/config.h similarity index 55% copy from vpnc.h copy to config.h index ad6d471..191c7c8 100644 --- a/vpnc.h +++ b/config.h @@ -1,5 +1,5 @@ /* IPSec VPN client compatible with Cisco equipment. - Copyright (C) 2002, 2003 Geoffrey Keating and Maurice Massar + Copyright (C) 2004 Maurice Massar This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,15 +16,47 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __VPNC_H__ -#define __VPNC_H__ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +enum config_enum { + CONFIG_NONE, + CONFIG_CONFIG_SCRIPT, + CONFIG_DEBUG, + CONFIG_DOMAIN, + CONFIG_ENABLE_1DES, + CONFIG_ND, + CONFIG_NON_INTERACTIVE, + CONFIG_PID_FILE, + CONFIG_LOCAL_PORT, + CONFIG_VERSION, + CONFIG_IF_NAME, + CONFIG_IKE_DH, + CONFIG_IPSEC_PFS, + CONFIG_IPSEC_GATEWAY, + CONFIG_IPSEC_ID, + CONFIG_IPSEC_SECRET, + CONFIG_XAUTH_USERNAME, + CONFIG_XAUTH_PASSWORD, + CONFIG_XAUTH_INTERACTIVE, + LAST_CONFIG +}; + +enum hex_dump_enum { + UINT8 = -1, + UINT16 = -2, + UINT32 = -4 +}; + +extern const char *config[LAST_CONFIG]; extern int opt_debug; extern int opt_nd; -extern int tun_fd; -extern char tun_name[]; -extern void hex_dump(const char *str, const void *data, size_t len); +extern int opt_1des; #define DEBUG(lvl, a) do {if (opt_debug >= (lvl)) {a;}} while (0) +extern void hex_dump(const char *str, const void *data, ssize_t len); +extern void do_config(int argc, char **argv); + #endif diff --git a/isakmp-pkt.c b/isakmp-pkt.c index c68ddac..b66c588 100644 --- a/isakmp-pkt.c +++ b/isakmp-pkt.c @@ -22,9 +22,9 @@ #include #include -#include "isakmp-pkt.h" -#include "vpnc.h" #include "sysdep.h" +#include "config.h" +#include "isakmp-pkt.h" void *xallocc(size_t x) { @@ -419,7 +419,7 @@ static struct isakmp_attribute *parse_isakmp_attributes(const uint8_t ** data_p, length = fetch2(); if (type & 0x8000) { r->type = type & ~0x8000; - hex_dump("t.attributes.type", &r->type, 2); + hex_dump("t.attributes.type", &r->type, UINT16); r->af = isakmp_attr_16; r->u.attr_16 = length; if ((ISAKMP_XAUTH_ATTRIB_TYPE <= r->type) @@ -427,17 +427,17 @@ static struct isakmp_attribute *parse_isakmp_attributes(const uint8_t ** data_p, && (opt_debug < 99)) DEBUG(3, printf("(not dumping xauth data)\n")); else - hex_dump("t.attributes.u.attr_16", &r->u.attr_16, 2); + hex_dump("t.attributes.u.attr_16", &r->u.attr_16, UINT16); } else { r->type = type; - hex_dump("t.attributes.type", &r->type, 2); + hex_dump("t.attributes.type", &r->type, UINT16); r->af = isakmp_attr_lots; r->u.lots.length = length; if ((ISAKMP_XAUTH_ATTRIB_TYPE <= r->type) && (r->type <= ISAKMP_XAUTH_ATTRIB_ANSWER) && (opt_debug < 99)) DEBUG(3, printf("(not dumping xauth data length)\n")); else - hex_dump("t.attributes.u.lots.length", &r->u.lots.length, 2); + hex_dump("t.attributes.u.lots.length", &r->u.lots.length, UINT16); if (data_len < length) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; @@ -468,7 +468,7 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, 4, 12, 8, 8, 4, 8, 5, 5, 4, 4, 4, 12, 12, 4, 8 }; - hex_dump("PARSING PAYLOAD type", &type, sizeof(type)); + hex_dump("PARSING PAYLOAD type", &type, UINT8); if (type == 0) return NULL; if (type > ISAKMP_PAYLOAD_MODECFG_ATTR) { @@ -482,13 +482,13 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, r = new_isakmp_payload(type); next_type = fetch1(); - hex_dump("next_type", &next_type, sizeof(next_type)); + hex_dump("next_type", &next_type, UINT8); if (fetch1() != 0) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } length = fetch2(); - hex_dump("length", &length, sizeof(length)); + hex_dump("length", &length, UINT16); if (length > data_len + 4 || length < min_payload_len[type]) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; @@ -497,13 +497,13 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, switch (type) { case ISAKMP_PAYLOAD_SA: r->u.sa.doi = fetch4(); - hex_dump("sa.doi", &r->u.sa.doi, sizeof(r->u.sa.doi)); + hex_dump("sa.doi", &r->u.sa.doi, UINT32); if (r->u.sa.doi != ISAKMP_DOI_IPSEC) { *reject = ISAKMP_N_DOI_NOT_SUPPORTED; return r; } r->u.sa.situation = fetch4(); - hex_dump("sa.situation", &r->u.sa.situation, sizeof(r->u.sa.situation)); + hex_dump("sa.situation", &r->u.sa.situation, UINT32); if (r->u.sa.situation != ISAKMP_IPSEC_SIT_IDENTITY_ONLY) { *reject = ISAKMP_N_SITUATION_NOT_SUPPORTED; return r; @@ -527,13 +527,13 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, struct isakmp_payload *xform; r->u.p.number = fetch1(); - hex_dump("p.number", &r->u.p.number, sizeof(r->u.p.number)); + hex_dump("p.number", &r->u.p.number, UINT8); r->u.p.prot_id = fetch1(); - hex_dump("p.prot_id", &r->u.p.prot_id, sizeof(r->u.p.prot_id)); + hex_dump("p.prot_id", &r->u.p.prot_id, UINT8); r->u.p.spi_size = fetch1(); - hex_dump("p.spi_size", &r->u.p.spi_size, sizeof(r->u.p.spi_size)); + hex_dump("p.spi_size", &r->u.p.spi_size, UINT8); num_xform = fetch1(); - hex_dump("length", &num_xform, sizeof(num_xform)); + hex_dump("length", &num_xform, UINT8); if (data_len < r->u.p.spi_size) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; @@ -564,9 +564,9 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, return r; } r->u.t.number = fetch1(); - hex_dump("t.number", &r->u.t.number, sizeof(r->u.t.number)); + hex_dump("t.number", &r->u.t.number, UINT8); r->u.t.id = fetch1(); - hex_dump("t.id", &r->u.t.id, sizeof(r->u.t.id)); + hex_dump("t.id", &r->u.t.id, UINT8); if (fetch2() != 0) { *reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX; return r; @@ -588,9 +588,9 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, break; case ISAKMP_PAYLOAD_ID: r->u.id.type = fetch1(); - hex_dump("id.type", &r->u.id.type, sizeof(r->u.id.type)); + hex_dump("id.type", &r->u.id.type, UINT8); r->u.id.protocol = fetch1(); - hex_dump("id.protocol", &r->u.id.protocol, sizeof(r->u.id.protocol)); + hex_dump("id.protocol", &r->u.id.protocol, UINT8); r->u.id.port = fetch2(); hex_dump("id.port", &r->u.id.port, sizeof(r->u.id.port)); r->u.id.length = length - 8; @@ -601,20 +601,20 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, case ISAKMP_PAYLOAD_CERT: case ISAKMP_PAYLOAD_CR: r->u.cert.encoding = fetch1(); - hex_dump("cert.encoding", &r->u.cert.encoding, 1); + hex_dump("cert.encoding", &r->u.cert.encoding, UINT8); r->u.cert.length = length - 5; fetchn(r->u.cert.data, r->u.cert.length); hex_dump("cert.data", r->u.cert.data, r->u.cert.length); break; case ISAKMP_PAYLOAD_N: r->u.n.doi = fetch4(); - hex_dump("n.doi", &r->u.n.doi, 4); + hex_dump("n.doi", &r->u.n.doi, UINT32); r->u.n.protocol = fetch1(); - hex_dump("n.protocol", &r->u.n.protocol, 1); + hex_dump("n.protocol", &r->u.n.protocol, UINT8); r->u.n.spi_length = fetch1(); - hex_dump("n.spi_length", &r->u.n.spi_length, 1); + hex_dump("n.spi_length", &r->u.n.spi_length, UINT8); r->u.n.type = fetch2(); - hex_dump("n.type", &r->u.n.type, 2); + hex_dump("n.type", &r->u.n.type, UINT16); if (r->u.n.spi_length + 12u > length) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; @@ -628,14 +628,14 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, hex_dump("n.data", r->u.n.data, r->u.n.data_length); break; case ISAKMP_PAYLOAD_D: - r->u.n.doi = fetch4(); - hex_dump("n.doi", &r->u.n.doi, 1); + r->u.n.doi = fetch4(); /*FIXME: huuuh? */ + hex_dump("n.doi", &r->u.n.doi, UINT32); r->u.n.protocol = fetch1(); - hex_dump("n.protocol", &r->u.n.protocol, 1); + hex_dump("n.protocol", &r->u.n.protocol, UINT8); r->u.n.spi_length = fetch1(); - hex_dump("n.spi_length", &r->u.n.spi_length, 1); + hex_dump("n.spi_length", &r->u.n.spi_length, UINT8); r->u.d.num_spi = fetch2(); - hex_dump("d.num_spi", &r->u.d.num_spi, 2); + hex_dump("d.num_spi", &r->u.d.num_spi, UINT16); if (r->u.d.num_spi * r->u.n.spi_length + 12u != length) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; @@ -652,13 +652,13 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, break; case ISAKMP_PAYLOAD_MODECFG_ATTR: r->u.modecfg.type = fetch1(); - hex_dump("modecfg.type", &r->u.modecfg.type, 1); + hex_dump("modecfg.type", &r->u.modecfg.type, UINT8); if (fetch1() != 0) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } r->u.t.id = fetch2(); - hex_dump("t.id", &r->u.t.id, 2); + hex_dump("t.id", &r->u.t.id, UINT16); length -= 8; r->u.t.attributes = parse_isakmp_attributes(&data, length, reject); data_len -= olength - 8; @@ -669,7 +669,7 @@ static struct isakmp_payload *parse_isakmp_payload(uint8_t type, } *data_p = data; *data_len_p = data_len; - hex_dump("DONE PARSING PAYLOAD type", &type, sizeof(type)); + hex_dump("DONE PARSING PAYLOAD type", &type, UINT8); r->next = parse_isakmp_payload(next_type, data_p, data_len_p, reject); return r; } @@ -692,10 +692,10 @@ struct isakmp_packet *parse_isakmp_packet(const uint8_t * data, size_t data_len, fetchn(r->r_cookie, ISAKMP_COOKIE_LENGTH); hex_dump("r_cookie", r->r_cookie, ISAKMP_COOKIE_LENGTH); payload = fetch1(); - hex_dump("payload", &payload, sizeof(payload)); + hex_dump("payload", &payload, UINT8); r->isakmp_version = fetch1(); - hex_dump("isakmp_version", &r->isakmp_version, sizeof(r->isakmp_version)); + hex_dump("isakmp_version", &r->isakmp_version, UINT8); if (r->isakmp_version > ISAKMP_VERSION) { if ((r->isakmp_version & 0xF0) >= (ISAKMP_VERSION & 0xF0)) reason = ISAKMP_N_INVALID_MAJOR_VERSION; @@ -705,9 +705,9 @@ struct isakmp_packet *parse_isakmp_packet(const uint8_t * data, size_t data_len, } r->exchange_type = fetch1(); - hex_dump("exchange_type", &r->exchange_type, sizeof(r->exchange_type)); + hex_dump("exchange_type", &r->exchange_type, UINT8); r->flags = fetch1(); - hex_dump("flags", &r->flags, sizeof(r->flags)); + hex_dump("flags", &r->flags, UINT8); r->message_id = fetch4(); hex_dump("message_id", &r->message_id, sizeof(r->message_id)); @@ -715,7 +715,7 @@ struct isakmp_packet *parse_isakmp_packet(const uint8_t * data, size_t data_len, reason = ISAKMP_N_UNEQUAL_PAYLOAD_LENGTHS; goto error; } - hex_dump("len", &o_data_len, sizeof(o_data_len)); + hex_dump("len", &o_data_len, UINT32); r->payload = parse_isakmp_payload(payload, &data, &data_len, &reason); if (reason != 0) diff --git a/tunip.c b/tunip.c index aa57f55..30dbcea 100644 --- a/tunip.c +++ b/tunip.c @@ -71,6 +71,7 @@ #include #include "sysdep.h" +#include "config.h" #include "vpnc.h" #define max(a,b) ((a)>(b)?(a):(b)) diff --git a/vpnc.c b/vpnc.c index 46e1f23..4a1c814 100644 --- a/vpnc.c +++ b/vpnc.c @@ -36,8 +36,9 @@ #include -#include "isakmp-pkt.h" #include "sysdep.h" +#include "config.h" +#include "isakmp-pkt.h" #include "math_group.h" #include "dh.h" #include "vpnc.h" @@ -52,35 +53,6 @@ extern void vpnc_doit(unsigned long tous_spi, uint8_t * kill_packet_p, size_t kill_packet_size_p, struct sockaddr *kill_dest_p, const char *pidfile); -enum config_enum { - CONFIG_NONE, - CONFIG_CONFIG_SCRIPT, - CONFIG_DEBUG, - CONFIG_DOMAIN, - CONFIG_ENABLE_1DES, - CONFIG_ND, - CONFIG_NON_INTERACTIVE, - CONFIG_PID_FILE, - CONFIG_LOCAL_PORT, - CONFIG_VERSION, - CONFIG_IF_NAME, - CONFIG_IKE_DH, - CONFIG_IPSEC_PFS, - CONFIG_IPSEC_GATEWAY, - CONFIG_IPSEC_ID, - CONFIG_IPSEC_SECRET, - CONFIG_XAUTH_USERNAME, - CONFIG_XAUTH_PASSWORD, - CONFIG_XAUTH_INTERACTIVE, - LAST_CONFIG -}; - -static const char *config[LAST_CONFIG]; - -int opt_debug = 0; -int opt_nd; -int opt_1des; - enum supp_algo_key { SUPP_ALGO_NAME, SUPP_ALGO_MY_ID, @@ -94,23 +66,19 @@ enum algo_group { SUPP_ALGO_CRYPT }; -typedef struct { - const char *name; - int my_id, ike_sa_id, ipsec_sa_id; - int keylen; -} supported_algo_t; - supported_algo_t supp_dh_group[] = { {"nopfs", 0, 0, 0, 0}, {"dh1", OAKLEY_GRP_1, IKE_GROUP_MODP_768, IKE_GROUP_MODP_768, 0}, {"dh2", OAKLEY_GRP_2, IKE_GROUP_MODP_1024, IKE_GROUP_MODP_1024, 0}, {"dh5", OAKLEY_GRP_5, IKE_GROUP_MODP_1536, IKE_GROUP_MODP_1536, 0}, /*{ "dh7", OAKLEY_GRP_7, IKE_GROUP_EC2N_163K, IKE_GROUP_EC2N_163K, 0 } note: code missing */ + {NULL, 0, 0, 0, 0} }; supported_algo_t supp_hash[] = { {"md5", GCRY_MD_MD5, IKE_HASH_MD5, IPSEC_AUTH_HMAC_MD5, 0}, - {"sha1", GCRY_MD_SHA1, IKE_HASH_SHA, IPSEC_AUTH_HMAC_SHA, 0} + {"sha1", GCRY_MD_SHA1, IKE_HASH_SHA, IPSEC_AUTH_HMAC_SHA, 0}, + {NULL, 0, 0, 0, 0} }; supported_algo_t supp_crypt[] = { @@ -119,13 +87,14 @@ supported_algo_t supp_crypt[] = { {"aes128", GCRY_CIPHER_AES128, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 128}, {"aes192", GCRY_CIPHER_AES192, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 192}, {"aes256", GCRY_CIPHER_AES256, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 256}, + {NULL, 0, 0, 0, 0} }; const supported_algo_t *get_algo(enum algo_group what, enum supp_algo_key key, int id, const char *name, int keylen) { supported_algo_t *sa = NULL; - int i = 0, cnt = 0, val = 0; + int i = 0, val = 0; const char *valname = NULL; assert(what <= SUPP_ALGO_CRYPT); @@ -134,19 +103,16 @@ const supported_algo_t *get_algo(enum algo_group what, enum supp_algo_key key, i switch (what) { case SUPP_ALGO_DH_GROUP: sa = supp_dh_group; - cnt = sizeof(supp_dh_group) / sizeof(supp_dh_group[0]); break; case SUPP_ALGO_HASH: sa = supp_hash; - cnt = sizeof(supp_hash) / sizeof(supp_hash[0]); break; case SUPP_ALGO_CRYPT: sa = supp_crypt; - cnt = sizeof(supp_crypt) / sizeof(supp_crypt[0]); break; } - for (i = 0; i < cnt; i++) { + for (i = 0; sa[i].name != NULL; i++) { switch (key) { case SUPP_ALGO_NAME: valname = sa[i].name; @@ -192,24 +158,6 @@ static __inline__ int min(int a, int b) return (a < b) ? a : b; } -void hex_dump(const char *str, const void *data, size_t len) -{ - size_t i; - const uint8_t *p = data; - - if (opt_debug >= 3) { - printf("%s:%c", str, (len <= 32) ? ' ' : '\n'); - for (i = 0; i < len; i++) { - if (i && !(i % 32)) - printf("\n"); - else if (i && !(i % 4)) - printf(" "); - printf("%02x", p[i]); - } - printf("\n"); - } -} - static int make_socket(uint16_t port) { int sock; @@ -295,7 +243,7 @@ static int recv_ignore_dup(void *recvbuf, size_t recvbufsize, uint8_t reply_exty return -1; } - hex_dump("exchange_type", ((uint8_t *) recvbuf) + ISAKMP_EXCHANGE_TYPE_O, 1); + hex_dump("exchange_type", ((uint8_t *) recvbuf) + ISAKMP_EXCHANGE_TYPE_O, UINT8); if (reply_extype && (((uint8_t *) recvbuf)[ISAKMP_EXCHANGE_TYPE_O] != reply_extype)) { DEBUG(2, printf("want extype %d, got %d, ignoring\n", reply_extype, ((uint8_t *) recvbuf)[ISAKMP_EXCHANGE_TYPE_O])); @@ -403,11 +351,11 @@ struct isakmp_payload *make_our_sa_ike(void) r->u.sa.situation = ISAKMP_IPSEC_SIT_IDENTITY_ONLY; r->u.sa.proposals = new_isakmp_payload(ISAKMP_PAYLOAD_P); r->u.sa.proposals->u.p.prot_id = ISAKMP_IPSEC_PROTO_ISAKMP; - for (crypt = 0; crypt < sizeof(supp_crypt) / sizeof(supp_crypt[0]); crypt++) { + for (crypt = 0; supp_crypt[crypt].name != NULL; crypt++) { if ((supp_crypt[crypt].my_id == GCRY_CIPHER_DES) && (opt_1des == 0)) continue; keylen = supp_crypt[crypt].keylen; - for (hash = 0; hash < sizeof(supp_hash) / sizeof(supp_hash[0]); hash++) { + for (hash = 0; supp_hash[hash].name != NULL; hash++) { tn = t; t = new_isakmp_payload(ISAKMP_PAYLOAD_T); t->u.t.id = ISAKMP_IPSEC_KEY_IKE; @@ -1626,11 +1574,11 @@ struct isakmp_payload *make_our_sa_ipsec(struct sa_block *s) /* The sadb_sa_spi field is already in network order. */ memcpy(r->u.sa.proposals->u.p.spi, &s->tous_esp_spi, 4); r->u.sa.proposals->u.p.prot_id = ISAKMP_IPSEC_PROTO_IPSEC_ESP; - for (crypt = 0; crypt < sizeof(supp_crypt) / sizeof(supp_crypt[0]); crypt++) { + for (crypt = 0; supp_crypt[crypt].name != NULL; crypt++) { if ((supp_crypt[crypt].my_id == GCRY_CIPHER_DES) && (opt_1des == 0)) continue; keylen = supp_crypt[crypt].keylen; - for (hash = 0; hash < sizeof(supp_hash) / sizeof(supp_hash[0]); hash++) { + for (hash = 0; supp_hash[hash].name != NULL; hash++) { pn = p; p = new_isakmp_payload(ISAKMP_PAYLOAD_P); p->u.p.spi_size = 4; @@ -1949,444 +1897,20 @@ static void setup_link(struct sa_block *s) } } -const char *config_def_description(void) -{ - return "default value for this option"; -} - -const char *config_def_ike_dh(void) -{ - return "dh2"; -} - -const char *config_def_pfs(void) -{ - return "server"; -} - -const char *config_def_local_port(void) -{ - return "500"; -} - -const char *config_def_app_version(void) -{ - struct utsname uts; - char *version; - - uname(&uts); - asprintf(&version, "Cisco Systems VPN Client %s:%s", VERSION, uts.sysname); - return version; -} - -static const struct config_names_s { - enum config_enum nm; - const int needsArgument; - const char *option; - const char *name; - const char *type; - const char *desc; - const char *(*get_def) (void); -} config_names[] = { - /* Note: broken config file parser does NOT support option - * names where one is a prefix of another option. Needs just a bit work to - * fix the parser to care about ' ' or '\t' after the wanted - * option... */ - { - CONFIG_NONE, 0, - "commandline option,", - "configfile variable, ", - "argument type", - "description", - config_def_description - }, { - CONFIG_IPSEC_GATEWAY, 1, - "--gateway", - "IPSec gateway ", - "", - "IP/name of your IPSec gateway", - NULL - }, { - CONFIG_IPSEC_ID, 1, - "--id", - "IPSec ID ", - "", - "your group name", - NULL - }, { - CONFIG_IPSEC_SECRET, 1, - NULL, - "IPSec secret ", - "", - "your group password (cleartext, no support for obfuscated strings)", - NULL - }, { - CONFIG_XAUTH_USERNAME, 1, - "--username", - "Xauth username ", - "", - "your username", - NULL - }, { - CONFIG_XAUTH_PASSWORD, 1, - NULL, - "Xauth password ", - "", - "your password (cleartext, no support for obfuscated strings)", - NULL - }, { - CONFIG_DOMAIN, 1, - "--domain", - "Domain ", - "", - "(NT-) Domain name for authentication", - NULL - }, { - CONFIG_XAUTH_INTERACTIVE, 0, - "--xauth-inter", - "Xauth interactive", - NULL, - "enable interactive extended authentication (for challange response auth)", - NULL - }, { - CONFIG_CONFIG_SCRIPT, 1, - "--script", - "Config Script ", - "", - "command is executed using system() to configure the interface,\n" - "routing and so on. Device name, IP, etc. are passed using enviroment\n" - "variables, see README. This script is executed right after ISAKMP is\n" - "done, but befor tunneling is enabled.\n", - sysdep_config_script - }, { - CONFIG_IKE_DH, 1, - "--dh", - "IKE DH Group ", - "", - "name of the IKE DH Group", - config_def_ike_dh - }, { - CONFIG_IPSEC_PFS, 1, - "--pfs", - "Perfect Forward Secrecy ", - "", - "Diffie-Hellman group to use for PFS", - config_def_pfs - }, { - CONFIG_ENABLE_1DES, 0, - "--enable-1des", - "Enable Single DES", - NULL, - "enables weak single DES encryption", - NULL - }, { - CONFIG_VERSION, 1, - "--application-version", - "Application version ", - "", - "Application Version to report", - config_def_app_version - }, { - CONFIG_IF_NAME, 1, - "--ifname", - "Interface name ", - "", - "visible name of the TUN interface", - NULL - }, { - CONFIG_DEBUG, 1, - "--debug", - "Debug ", - "<0/1/2/3/99>", - "Show verbose debug messages", - NULL - }, { - CONFIG_ND, 0, - "--no-detach", - "No Detach", - NULL, - "Don't detach from the console after login", - NULL - }, { - CONFIG_PID_FILE, 1, - "--pid-file", - "Pidfile ", - "", - "store the pid of background process in ", - NULL - }, { - CONFIG_LOCAL_PORT, 1, - "--local-port", - "Local Port ", - "<0-65535>", - "local ISAKMP port number to use (0 == use random port)", - config_def_local_port - }, { - CONFIG_NON_INTERACTIVE, 0, - "--non-inter", - "Noninteractive", - NULL, - "Don't ask anything, exit on missing options", - NULL - }, { - 0, 0, NULL, NULL, NULL, NULL, NULL - } -}; - -void read_config_file(char *name, const char **configs, int missingok) -{ - FILE *f; - char *line = NULL; - ssize_t line_length = 0; - int linenum = 0; - - f = fopen(name, "r"); - if (missingok && f == NULL && errno == ENOENT) - return; - if (f == NULL) - error(1, errno, "couldn't open `%s'", name); - for (;;) { - ssize_t llen; - int i; - - llen = getline(&line, &line_length, f); - if (llen == -1 && feof(f)) - break; - if (llen == -1) - error(1, errno, "reading `%s'", name); - if (line[llen - 1] == '\n') - line[llen - 1] = 0; - linenum++; - for (i = 0; config_names[i].name != NULL; i++) { - if (config_names[i].nm == CONFIG_NONE) - continue; - if (strncasecmp(config_names[i].name, line, - strlen(config_names[i].name)) == 0) { - // boolean implementation, using harmles pointer targets as true - if (!config_names[i].needsArgument) { - configs[config_names[i].nm] = config_names[i].name; - break; - } - if (configs[config_names[i].nm] == NULL) - configs[config_names[i].nm] = - strdup(line + strlen(config_names[i].name)); - if (configs[config_names[i].nm] == NULL) - error(1, errno, "can't allocate memory"); - break; - } - } - if (config_names[i].name == NULL && line[0] != '#' && line[0] != 0) - error(0, 0, "warning: unknown configuration directive in %s at line %d", - name, linenum); - } -} - -void print_desc(const char *pre, const char *text) -{ - const char *p, *q; - - for (p = text, q = strchr(p, '\n'); q; p = q+1, q = strchr(p, '\n')) - printf("%s%.*s\n", pre, q-p, p); - - if (*p != '\0') - printf("%s%s\n", pre, p); -} - -void print_usage(char *argv0) -{ - int c; - - printf("Usage: %s [--version] [--print-config] [--help] [options] [config file]\n\n", - argv0); - printf("Legend:\n"); - for (c = 0; config_names[c].name != NULL; c++) { - printf(" %s %s\n" - " %s%s\n", - (config_names[c].option == NULL ? "(configfile only option)" : - config_names[c].option), - ((config_names[c].type == NULL || config_names[c].option == NULL) ? - "" : config_names[c].type), - config_names[c].name, - (config_names[c].type == NULL ? "" : config_names[c].type)); - print_desc(" ", config_names[c].desc); - if (config_names[c].get_def != NULL) - printf(" Default: %s\n", config_names[c].get_def()); - printf("\n"); - } - printf("Report bugs to vpnc@unix-ag.uni-kl.de\n"); -} - int main(int argc, char **argv) { struct sa_block oursa; - int i, do_load_balance; - int print_config = 0; + int do_load_balance; const uint8_t hex_test[] = { 0, 1, 2, 3 }; test_pack_unpack(); - gcry_check_version("1.1.12"); + gcry_check_version("1.1.90"); gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0); group_init(); - hex_dump("hex_test", hex_test, sizeof(hex_test)); - - for (i = 1; i < argc; i++) - if (argv[i][0] == '-') { - int c; - int known = 0; - - for (c = 0; config_names[c].name != NULL && !known; c++) - if (config_names[c].option != NULL - && config_names[c].nm != CONFIG_NONE - && strncmp(argv[i], config_names[c].option, - strlen(config_names[c].option)) == 0) { - char *s = NULL; - - known = 1; - if (argv[i][strlen(config_names[c].option)] == '=') - s = strdup(argv[i] + - strlen(config_names[c].option) + 1); - else if (argv[i][strlen(config_names[c].option)] == 0) { - if (config_names[c].needsArgument) { - if (i + 1 < argc) - s = argv[++i]; - else - known = 0; - } else - s = argv[i]; /* no arg, fill in something */ - } else - known = 0; - if (known) - config[config_names[c].nm] = s; - } - - if (!known && strcmp(argv[i], "--version") == 0) { - unsigned int i; - - printf("vpnc version " VERSION "\n"); - printf("Copyright (C) 2002, 2003 Geoffrey Keating, Maurice Massar\n"); - printf("%s", - "vpnc comes with NO WARRANTY, to the extent permitted by law.\n" - "You may redistribute copies of vpnc under the terms of the GNU General\n" - "Public License. For more information about these matters, see the files\n" - "named COPYING.\n"); - printf("\n"); - printf("Supported DH-Groups:"); - for (i = 0; i < sizeof(supp_dh_group) / sizeof(supp_dh_group[0]); - i++) - printf(" %s", supp_dh_group[i].name); - printf("\n"); - printf("Supported Hash-Methods:"); - for (i = 0; i < sizeof(supp_hash) / sizeof(supp_hash[0]); i++) - printf(" %s", supp_hash[i].name); - printf("\n"); - printf("Supported Encryptions:"); - for (i = 0; i < sizeof(supp_crypt) / sizeof(supp_crypt[0]); i++) - printf(" %s", supp_crypt[i].name); - printf("\n"); - exit(0); - } - if (!known && strcmp(argv[i], "--print-config") == 0) { - print_config = 1; - known = 1; - break; - } - if (!known) { - if (strcmp(argv[i], "--help") != 0) - printf("%s: unknown option %s\n\n", argv[0], argv[i]); - - print_usage(argv[0]), exit(1); - } - } else - read_config_file(argv[i], config, 0); - - read_config_file("/etc/vpnc/default.conf", config, 1); - read_config_file("/etc/vpnc.conf", config, 1); - - if (!print_config) - for (i = 0; config_names[i].name != NULL; i++) - if (!config[config_names[i].nm] && i != CONFIG_NONE - && config_names[i].get_def != NULL) - config[config_names[i].nm] = config_names[i].get_def(); - - opt_debug = (config[CONFIG_DEBUG]) ? atoi(config[CONFIG_DEBUG]) : 0; - opt_nd = (config[CONFIG_ND]) ? 1 : 0; - opt_1des = (config[CONFIG_ENABLE_1DES]) ? 1 : 0; - - if (opt_debug >= 99) { - printf("WARNING! active debug level is >= 99, output includes username and password (hex encoded)\n"); - fprintf(stderr, - "WARNING! active debug level is >= 99, output includes username and password (hex encoded)\n"); - } - - for (i = 0; i < LAST_CONFIG; i++) - if ((config[i] == NULL) && (config[CONFIG_NON_INTERACTIVE] == NULL)) { - char *s = NULL; - size_t s_len = 0; - - switch (i) { - case CONFIG_IPSEC_GATEWAY: - printf("Enter IPSec gateway address: "); - break; - case CONFIG_IPSEC_ID: - printf("Enter IPSec ID for %s: ", config[CONFIG_IPSEC_GATEWAY]); - break; - case CONFIG_IPSEC_SECRET: - printf("Enter IPSec secret for %s@%s: ", - config[CONFIG_IPSEC_ID], config[CONFIG_IPSEC_GATEWAY]); - break; - case CONFIG_XAUTH_USERNAME: - printf("Enter username for %s: ", config[CONFIG_IPSEC_GATEWAY]); - break; - case CONFIG_XAUTH_PASSWORD: - printf("Enter password for %s@%s: ", - config[CONFIG_XAUTH_USERNAME], - config[CONFIG_IPSEC_GATEWAY]); - break; - } - fflush(stdout); - switch (i) { - case CONFIG_IPSEC_SECRET: - case CONFIG_XAUTH_PASSWORD: - s = strdup(getpass("")); - break; - case CONFIG_IPSEC_GATEWAY: - case CONFIG_IPSEC_ID: - case CONFIG_XAUTH_USERNAME: - getline(&s, &s_len, stdin); - } - if (s != NULL && s[strlen(s) - 1] == '\n') - s[strlen(s) - 1] = 0; - config[i] = s; - } - - if (print_config) { - fprintf(stderr, "vpnc.conf:\n\n"); - for (i = 0; config_names[i].name != NULL; i++) - if (config[config_names[i].nm] != NULL) - printf("%s%s\n", config_names[i].name, - (config_names[i].needsArgument) ? config[config_names[i]. - nm] : ""); - exit(0); - } - - if (!config[CONFIG_IPSEC_GATEWAY]) - error(1, 0, "missing IPSec gatway address"); - if (!config[CONFIG_IPSEC_ID]) - error(1, 0, "missing IPSec ID"); - if (!config[CONFIG_IPSEC_SECRET]) - error(1, 0, "missing IPSec secret"); - if (!config[CONFIG_XAUTH_USERNAME]) - error(1, 0, "missing Xauth username"); - if (!config[CONFIG_XAUTH_PASSWORD]) - error(1, 0, "missing Xauth password"); - if (get_dh_group_ike() == NULL) - error(1, 0, "IKE DH Group \"%s\" unsupported\n", config[CONFIG_IKE_DH]); - if (get_dh_group_ipsec(-1) == NULL) - error(1, 0, "Perfect Forward Secrecy \"%s\" unsupported\n", - config[CONFIG_IPSEC_PFS]); - if (get_dh_group_ike()->ike_sa_id == 0) - error(1, 0, "IKE DH Group must not be nopfs\n"); + do_config(argc, argv); + + hex_dump("hex_test", hex_test, sizeof(hex_test)); DEBUG(2, printf("S1\n")); dest_addr = init_sockaddr(config[CONFIG_IPSEC_GATEWAY], 500); diff --git a/vpnc.h b/vpnc.h index ad6d471..d462d10 100644 --- a/vpnc.h +++ b/vpnc.h @@ -1,5 +1,5 @@ /* IPSec VPN client compatible with Cisco equipment. - Copyright (C) 2002, 2003 Geoffrey Keating and Maurice Massar + Copyright (C) 2002, 2003, 2004 Geoffrey Keating and Maurice Massar This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,12 +19,20 @@ #ifndef __VPNC_H__ #define __VPNC_H__ -extern int opt_debug; -extern int opt_nd; +typedef struct { + const char *name; + int my_id, ike_sa_id, ipsec_sa_id; + int keylen; +} supported_algo_t; + +extern supported_algo_t supp_dh_group[]; +extern supported_algo_t supp_hash[]; +extern supported_algo_t supp_crypt[]; + extern int tun_fd; extern char tun_name[]; -extern void hex_dump(const char *str, const void *data, size_t len); -#define DEBUG(lvl, a) do {if (opt_debug >= (lvl)) {a;}} while (0) +extern const supported_algo_t *get_dh_group_ike(void); +extern const supported_algo_t *get_dh_group_ipsec(int server_setting); #endif -- 2.11.4.GIT