aboutsummaryrefslogtreecommitdiff
path: root/src/racoon/racoonctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/racoon/racoonctl.c')
-rw-r--r--src/racoon/racoonctl.c1654
1 files changed, 0 insertions, 1654 deletions
diff --git a/src/racoon/racoonctl.c b/src/racoon/racoonctl.c
deleted file mode 100644
index 1dd26f0..0000000
--- a/src/racoon/racoonctl.c
+++ /dev/null
@@ -1,1654 +0,0 @@
-/* $NetBSD: racoonctl.c,v 1.7.6.2 2009/04/20 13:32:57 tteras Exp $ */
-
-/* Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/pfkeyv2.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-#include <netdb.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <err.h>
-#include <sys/ioctl.h>
-#include <resolv.h>
-
-#include "var.h"
-#include "vmbuf.h"
-#include "misc.h"
-#include "gcmalloc.h"
-
-#include "racoonctl.h"
-#include "admin.h"
-#include "schedule.h"
-#include "handler.h"
-#include "sockmisc.h"
-#include "vmbuf.h"
-#include "plog.h"
-#include "isakmp_var.h"
-#include "isakmp.h"
-#include "isakmp_xauth.h"
-#include "isakmp_cfg.h"
-#include "isakmp_unity.h"
-#include "ipsec_doi.h"
-#include "evt.h"
-
-char *adminsock_path = ADMINSOCK_PATH;
-
-static void usage __P((void));
-static vchar_t *get_combuf __P((int, char **));
-static int handle_recv __P((vchar_t *));
-static vchar_t *f_reload __P((int, char **));
-static vchar_t *f_getsched __P((int, char **));
-static vchar_t *f_getsa __P((int, char **));
-static vchar_t *f_flushsa __P((int, char **));
-static vchar_t *f_deletesa __P((int, char **));
-static vchar_t *f_exchangesa __P((int, char **));
-static vchar_t *f_vpnc __P((int, char **));
-static vchar_t *f_vpnd __P((int, char **));
-static vchar_t *f_getevt __P((int, char **));
-#ifdef ENABLE_HYBRID
-static vchar_t *f_logoutusr __P((int, char **));
-#endif
-
-struct cmd_tag {
- vchar_t *(*func) __P((int, char **));
- int cmd;
- char *str;
-} cmdtab[] = {
- { f_reload, ADMIN_RELOAD_CONF, "reload-config" },
- { f_reload, ADMIN_RELOAD_CONF, "rc" },
- { f_getsched, ADMIN_SHOW_SCHED, "show-schedule" },
- { f_getsched, ADMIN_SHOW_SCHED, "sc" },
- { f_getsa, ADMIN_SHOW_SA, "show-sa" },
- { f_getsa, ADMIN_SHOW_SA, "ss" },
- { f_flushsa, ADMIN_FLUSH_SA, "flush-sa" },
- { f_flushsa, ADMIN_FLUSH_SA, "fs" },
- { f_deletesa, ADMIN_DELETE_SA, "delete-sa" },
- { f_deletesa, ADMIN_DELETE_SA, "ds" },
- { f_exchangesa, ADMIN_ESTABLISH_SA, "establish-sa" },
- { f_exchangesa, ADMIN_ESTABLISH_SA, "es" },
- { f_vpnc, ADMIN_ESTABLISH_SA, "vpn-connect" },
- { f_vpnc, ADMIN_ESTABLISH_SA, "vc" },
- { f_vpnd, ADMIN_DELETE_ALL_SA_DST,"vpn-disconnect" },
- { f_vpnd, ADMIN_DELETE_ALL_SA_DST,"vd" },
- { f_getevt, ADMIN_SHOW_EVT, "show-event" },
- { f_getevt, ADMIN_SHOW_EVT, "se" },
-#ifdef ENABLE_HYBRID
- { f_logoutusr, ADMIN_LOGOUT_USER, "logout-user" },
- { f_logoutusr, ADMIN_LOGOUT_USER, "lu" },
-#endif
- { NULL, 0, NULL },
-};
-
-struct evtmsg {
- int type;
- char *msg;
- enum { UNSPEC, ERROR, INFO } level;
-} evtmsg[] = {
- { EVTT_PHASE1_UP, "Phase 1 established", INFO },
- { EVTT_PHASE1_DOWN, "Phase 1 deleted", INFO },
- { EVTT_XAUTH_SUCCESS, "Xauth exchange passed", INFO },
- { EVTT_ISAKMP_CFG_DONE, "ISAKMP mode config done", INFO },
- { EVTT_PHASE2_UP, "Phase 2 established", INFO },
- { EVTT_PHASE2_DOWN, "Phase 2 deleted", INFO },
- { EVTT_DPD_TIMEOUT, "Peer not reachable anymore", ERROR },
- { EVTT_PEER_NO_RESPONSE, "Peer not responding", ERROR },
- { EVTT_PEER_DELETE, "Peer terminated security association", ERROR },
- { EVTT_RACOON_QUIT, "Raccon terminated", ERROR },
- { EVTT_OVERFLOW, "Event queue overflow", ERROR },
- { EVTT_XAUTH_FAILED, "Xauth exchange failed", ERROR },
- { EVTT_PEERPH1AUTH_FAILED, "Peer failed phase 1 authentication "
- "(certificate problem?)", ERROR },
- { EVTT_PEERPH1_NOPROP, "Peer failed phase 1 initiation "
- "(proposal problem?)", ERROR },
- { 0, NULL, UNSPEC },
- { EVTT_NO_ISAKMP_CFG, "No need for ISAKMP mode config ", INFO },
-};
-
-static int get_proto __P((char *));
-static vchar_t *get_index __P((int, char **));
-static int get_family __P((char *));
-static vchar_t *get_comindexes __P((int, int, char **));
-static int get_comindex __P((char *, char **, char **, char **));
-static int get_ulproto __P((char *));
-
-struct proto_tag {
- int proto;
- char *str;
-} prototab[] = {
- { ADMIN_PROTO_ISAKMP, "isakmp" },
- { ADMIN_PROTO_IPSEC, "ipsec" },
- { ADMIN_PROTO_AH, "ah" },
- { ADMIN_PROTO_ESP, "esp" },
- { ADMIN_PROTO_INTERNAL, "internal" },
- { 0, NULL },
-};
-
-struct ulproto_tag {
- int ul_proto;
- char *str;
-} ulprototab[] = {
- { 0, "any" },
- { IPPROTO_ICMP, "icmp" },
- { IPPROTO_TCP, "tcp" },
- { IPPROTO_UDP, "udp" },
- { 0, NULL },
-};
-
-int so;
-
-static char _addr1_[NI_MAXHOST], _addr2_[NI_MAXHOST];
-
-char *pname;
-int long_format = 0;
-
-#define EVTF_NONE 0x0000 /* Ignore any events */
-#define EVTF_LOOP 0x0001 /* Loop awaiting for new events */
-#define EVTF_CFG_STOP 0x0002 /* Stop after ISAKMP mode config */
-#define EVTF_CFG 0x0004 /* Print ISAKMP mode config info */
-#define EVTF_ALL 0x0008 /* Print any events */
-#define EVTF_PURGE 0x0010 /* Print all available events */
-#define EVTF_PH1DOWN_STOP 0x0020 /* Stop when phase 1 SA gets down */
-#define EVTF_PH1DOWN 0x0040 /* Print that phase 1 SA got down */
-#define EVTF_ERR 0x0080 /* Print any error */
-#define EVTF_ERR_STOP 0x0100 /* Stop on any error */
-
-int evt_filter = EVTF_NONE;
-time_t evt_start;
-
-void dump_isakmp_sa __P((char *, int));
-void dump_internal __P((char *, int));
-char *pindex_isakmp __P((isakmp_index *));
-void print_schedule __P((caddr_t, int));
-void print_evt __P((caddr_t, int));
-void print_cfg __P((caddr_t, int));
-void print_err __P((caddr_t, int));
-void print_ph1down __P((caddr_t, int));
-void print_ph1up __P((caddr_t, int));
-int evt_poll __P((void));
-char * fixed_addr __P((char *, char *, int));
-
-static void
-usage()
-{
- printf(
-"Usage:\n"
-" %s reload-config\n"
-" %s [-l [-l]] show-sa [protocol]\n"
-" %s flush-sa [protocol]\n"
-" %s delete-sa <saopts>\n"
-" %s establish-sa [-u identity] <saopts>\n"
-" %s vpn-connect [-u identity] vpn_gateway\n"
-" %s vpn-disconnect vpn_gateway\n"
-"\n"
-" <protocol>: \"isakmp\", \"esp\" or \"ah\".\n"
-" In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n"
-"\n"
-" <saopts>: \"isakmp\" <family> <src> <dst>\n"
-" : {\"esp\",\"ah\"} <family> <src/prefixlen/port> <dst/prefixlen/port>\n"
-" <ul_proto>\n"
-" <family>: \"inet\" or \"inet6\"\n"
-" <ul_proto>: \"icmp\", \"tcp\", \"udp\" or \"any\"\n",
- pname, pname, pname, pname, pname, pname, pname);
-}
-
-/*
- * Check for proper racoonctl interface
- */
-#if ((RACOONCTL_INTERFACE_MAJOR != 1) || (RACOONCTL_INTERFACE < 20041230))
-#error "Incompatible racoonctl interface"
-#endif
-
-int
-main(ac, av)
- int ac;
- char **av;
-{
- vchar_t *combuf;
- int c;
-
- pname = *av;
-
- /*
- * Check for proper racoonctl interface
- */
- if ((racoonctl_interface_major != RACOONCTL_INTERFACE_MAJOR) ||
- (racoonctl_interface < RACOONCTL_INTERFACE))
- errx(1, "Incompatible racoonctl interface");
-
-#ifdef __linux__
- /*
- * Disable GNU extensions that will prevent racoonct vc -u login
- * from working (GNU getopt(3) does not like options after vc)
- */
- setenv("POSIXLY_CORRECT", "1", 0);
-#endif
- while ((c = getopt(ac, av, "lds:")) != -1) {
- switch(c) {
- case 'l':
- long_format++;
- break;
-
- case 'd':
- loglevel++;
- break;
-
- case 's':
- adminsock_path = optarg;
- break;
-
- default:
- usage();
- exit(0);
- }
- }
-
- ac -= optind;
- av += optind;
-
- combuf = get_combuf(ac, av);
- if (!combuf)
- err(1, "kmpstat");
-
- if (loglevel)
- racoon_hexdump(combuf, ((struct admin_com *)combuf)->ac_len);
-
- com_init();
-
- if (com_send(combuf) != 0)
- goto bad;
-
- vfree(combuf);
-
- if (com_recv(&combuf) != 0)
- goto bad;
- if (handle_recv(combuf) != 0)
- goto bad;
-
- vfree(combuf);
-
- if (evt_filter != EVTF_NONE)
- if (evt_poll() != 0)
- goto bad;
-
- exit(0);
-
- bad:
- exit(1);
-}
-
-int
-evt_poll(void) {
- struct timeval tv;
- vchar_t *recvbuf;
- vchar_t *sendbuf;
-
- if ((sendbuf = f_getevt(0, NULL)) == NULL)
- errx(1, "Cannot make combuf");
-
-
- while (evt_filter & (EVTF_LOOP|EVTF_PURGE)) {
- /* handle_recv closes the socket time, so open it each time */
- com_init();
-
- if (com_send(sendbuf) != 0)
- errx(1, "Cannot send combuf");
-
- if (com_recv(&recvbuf) == 0) {
- handle_recv(recvbuf);
- vfree(recvbuf);
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 10;
- (void)select(0, NULL, NULL, NULL, &tv);
- }
-
- vfree(sendbuf);
- return 0;
-}
-
-/* %%% */
-/*
- * return command buffer.
- */
-static vchar_t *
-get_combuf(ac, av)
- int ac;
- char **av;
-{
- struct cmd_tag *cp;
-
- if (ac == 0) {
- usage();
- exit(0);
- }
-
- /* checking the string of command. */
- for (cp = &cmdtab[0]; cp->str; cp++) {
- if (strcmp(*av, cp->str) == 0) {
- break;
- }
- }
- if (!cp->str) {
- printf("Invalid command [%s]\n", *av);
- errno = EINVAL;
- return NULL;
- }
-
- ac--;
- av++;
- return (cp->func)(ac, av);
-}
-
-static vchar_t *
-f_reload(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf;
- struct admin_com *head;
-
- buf = vmalloc(sizeof(*head));
- if (buf == NULL)
- errx(1, "not enough core");
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l;
- head->ac_cmd = ADMIN_RELOAD_CONF;
- head->ac_errno = 0;
- head->ac_proto = 0;
-
- return buf;
-}
-
-static vchar_t *
-f_getevt(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf;
- struct admin_com *head;
-
- /*
- * There are 3 ways of getting here
- * 1) racoonctl vc => evt_filter = (EVTF_LOOP|EVTF_CFG| ... )
- * 2) racoonctl es => evt_filter = EVTF_NONE
- * 3) racoonctl es -l => evt_filter = EVTF_LOOP
- * Catch the second case: show-event is here to purge all
- */
- if (evt_filter == EVTF_NONE)
- evt_filter = (EVTF_ALL|EVTF_PURGE);
-
- if ((ac >= 1) && (strcmp(av[0], "-l") == 0))
- evt_filter |= EVTF_LOOP;
-
- if (ac >= 2)
- errx(1, "too many arguments");
-
- buf = vmalloc(sizeof(*head));
- if (buf == NULL)
- errx(1, "not enough core");
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l;
- head->ac_cmd = ADMIN_SHOW_EVT;
- head->ac_errno = 0;
- head->ac_proto = 0;
-
- return buf;
-}
-
-static vchar_t *
-f_getsched(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf;
- struct admin_com *head;
-
- buf = vmalloc(sizeof(*head));
- if (buf == NULL)
- errx(1, "not enough core");
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l;
- head->ac_cmd = ADMIN_SHOW_SCHED;
- head->ac_errno = 0;
- head->ac_proto = 0;
-
- return buf;
-}
-
-static vchar_t *
-f_getsa(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf;
- struct admin_com *head;
- int proto;
-
- /* need protocol */
- if (ac != 1)
- errx(1, "insufficient arguments");
- proto = get_proto(*av);
- if (proto == -1)
- errx(1, "unknown protocol %s", *av);
-
- buf = vmalloc(sizeof(*head));
- if (buf == NULL)
- errx(1, "not enough core");
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l;
- head->ac_cmd = ADMIN_SHOW_SA;
- head->ac_errno = 0;
- head->ac_proto = proto;
-
- return buf;
-}
-
-static vchar_t *
-f_flushsa(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf;
- struct admin_com *head;
- int proto;
-
- /* need protocol */
- if (ac != 1)
- errx(1, "insufficient arguments");
- proto = get_proto(*av);
- if (proto == -1)
- errx(1, "unknown protocol %s", *av);
-
- buf = vmalloc(sizeof(*head));
- if (buf == NULL)
- errx(1, "not enough core");
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l;
- head->ac_cmd = ADMIN_FLUSH_SA;
- head->ac_errno = 0;
- head->ac_proto = proto;
-
- return buf;
-}
-
-static vchar_t *
-f_deletesa(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf, *index;
- struct admin_com *head;
- int proto;
-
- /* need protocol */
- if (ac < 1)
- errx(1, "insufficient arguments");
- proto = get_proto(*av);
- if (proto == -1)
- errx(1, "unknown protocol %s", *av);
-
- /* get index(es) */
- av++;
- ac--;
- switch (proto) {
- case ADMIN_PROTO_ISAKMP:
- index = get_index(ac, av);
- if (index == NULL)
- return NULL;
- break;
- case ADMIN_PROTO_AH:
- case ADMIN_PROTO_ESP:
- index = get_index(ac, av);
- if (index == NULL)
- return NULL;
- break;
- default:
- errno = EPROTONOSUPPORT;
- return NULL;
- }
-
- buf = vmalloc(sizeof(*head) + index->l);
- if (buf == NULL)
- goto out;
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l + index->l;
- head->ac_cmd = ADMIN_DELETE_SA;
- head->ac_errno = 0;
- head->ac_proto = proto;
-
- memcpy(buf->v+sizeof(*head), index->v, index->l);
-
-out:
- if (index != NULL)
- vfree(index);
-
- return buf;
-}
-
-static vchar_t *
-f_deleteallsadst(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf, *index;
- struct admin_com *head;
- int proto;
-
- /* need protocol */
- if (ac < 1)
- errx(1, "insufficient arguments");
- proto = get_proto(*av);
- if (proto == -1)
- errx(1, "unknown protocol %s", *av);
-
- /* get index(es) */
- av++;
- ac--;
- switch (proto) {
- case ADMIN_PROTO_ISAKMP:
- index = get_index(ac, av);
- if (index == NULL)
- return NULL;
- break;
- case ADMIN_PROTO_AH:
- case ADMIN_PROTO_ESP:
- index = get_index(ac, av);
- if (index == NULL)
- return NULL;
- break;
- default:
- errno = EPROTONOSUPPORT;
- return NULL;
- }
-
- buf = vmalloc(sizeof(*head) + index->l);
- if (buf == NULL)
- goto out;
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l + index->l;
- head->ac_cmd = ADMIN_DELETE_ALL_SA_DST;
- head->ac_errno = 0;
- head->ac_proto = proto;
-
- memcpy(buf->v+sizeof(*head), index->v, index->l);
-
-out:
- if (index != NULL)
- vfree(index);
-
- return buf;
-}
-
-static vchar_t *
-f_exchangesa(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf, *index;
- struct admin_com *head;
- int proto;
- int cmd = ADMIN_ESTABLISH_SA;
- size_t com_len = 0;
- char *id = NULL;
- char *key = NULL;
- struct admin_com_psk *acp;
-
- if (ac < 1)
- errx(1, "insufficient arguments");
-
- /* Optional -u identity */
- if (strcmp(av[0], "-u") == 0) {
- if (ac < 2)
- errx(1, "-u require an argument");
-
- id = av[1];
- if ((key = getpass("Password: ")) == NULL)
- errx(1, "getpass() failed: %s", strerror(errno));
-
- com_len += sizeof(*acp) + strlen(id) + 1 + strlen(key) + 1;
- cmd = ADMIN_ESTABLISH_SA_PSK;
-
- av += 2;
- ac -= 2;
- }
-
- /* need protocol */
- if (ac < 1)
- errx(1, "insufficient arguments");
- if ((proto = get_proto(*av)) == -1)
- errx(1, "unknown protocol %s", *av);
-
- /* get index(es) */
- av++;
- ac--;
- switch (proto) {
- case ADMIN_PROTO_ISAKMP:
- index = get_index(ac, av);
- if (index == NULL)
- return NULL;
- break;
- case ADMIN_PROTO_AH:
- case ADMIN_PROTO_ESP:
- index = get_index(ac, av);
- if (index == NULL)
- return NULL;
- break;
- default:
- errno = EPROTONOSUPPORT;
- return NULL;
- }
-
- com_len += sizeof(*head) + index->l;
- if ((buf = vmalloc(com_len)) == NULL)
- errx(1, "Cannot allocate buffer");
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l;
- head->ac_cmd = cmd;
- head->ac_errno = 0;
- head->ac_proto = proto;
-
- memcpy(buf->v+sizeof(*head), index->v, index->l);
-
- if (id && key) {
- char *data;
- acp = (struct admin_com_psk *)
- (buf->v + sizeof(*head) + index->l);
-
- acp->id_type = IDTYPE_USERFQDN;
- acp->id_len = strlen(id) + 1;
- acp->key_len = strlen(key) + 1;
-
- data = (char *)(acp + 1);
- strcpy(data, id);
-
- data = (char *)(data + acp->id_len);
- strcpy(data, key);
- }
-
- vfree(index);
-
- return buf;
-}
-
-static vchar_t *
-f_vpnc(ac, av)
- int ac;
- char **av;
-{
- char *nav[] = {NULL, NULL, NULL, NULL, NULL, NULL};
- int nac = 0;
- char *isakmp = "isakmp";
- char *inet = "inet";
- char *srcaddr;
- struct addrinfo hints, *res;
- struct sockaddr *src;
- char *idx;
-
- if (ac < 1)
- errx(1, "insufficient arguments");
-
- evt_filter = (EVTF_LOOP|EVTF_CFG|EVTF_CFG_STOP|EVTF_ERR|EVTF_ERR_STOP);
- time(&evt_start);
-
- /* Optional -u identity */
- if (strcmp(av[0], "-u") == 0) {
- if (ac < 2)
- errx(1, "-u require an argument");
-
- nav[nac++] = av[0];
- nav[nac++] = av[1];
-
- ac -= 2;
- av += 2;
- }
-
- if (ac < 1)
- errx(1, "VPN gateway required");
- if (ac > 1)
- warnx("Extra arguments");
-
- /*
- * Find the source address
- */
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- if (getaddrinfo(av[0], "4500", &hints, &res) != 0)
- errx(1, "Cannot resolve destination address");
-
- if ((src = getlocaladdr(res->ai_addr)) == NULL)
- errx(1, "cannot find source address");
-
- if ((srcaddr = saddr2str(src)) == NULL)
- errx(1, "cannot read source address");
-
- /* We get "ip[port]" strip the port */
- if ((idx = index(srcaddr, '[')) == NULL)
- errx(1, "unexpected source address format");
- *idx = '\0';
-
- nav[nac++] = isakmp;
- nav[nac++] = inet;
- nav[nac++] = srcaddr;
- nav[nac++] = av[0];
-
- return f_exchangesa(nac, nav);
-}
-
-static vchar_t *
-f_vpnd(ac, av)
- int ac;
- char **av;
-{
- char *nav[] = {NULL, NULL, NULL, NULL};
- int nac = 0;
- char *isakmp = "isakmp";
- char *inet = "inet";
- char *anyaddr = "0.0.0.0";
- char *idx;
-
- if (ac < 1)
- errx(1, "VPN gateway required");
- if (ac > 1)
- warnx("Extra arguments");
-
- evt_filter =
- (EVTF_PH1DOWN|EVTF_PH1DOWN_STOP|EVTF_LOOP|EVTF_ERR|EVTF_ERR_STOP);
-
- nav[nac++] = isakmp;
- nav[nac++] = inet;
- nav[nac++] = anyaddr;
- nav[nac++] = av[0];
-
- return f_deleteallsadst(nac, nav);
-}
-
-#ifdef ENABLE_HYBRID
-static vchar_t *
-f_logoutusr(ac, av)
- int ac;
- char **av;
-{
- vchar_t *buf;
- struct admin_com *head;
- char *user;
- size_t userlen;
-
- /* need username */
- if (ac < 1)
- errx(1, "insufficient arguments");
- user = av[0];
- userlen = strlen(user);
- if ((user == NULL) || (userlen > LOGINLEN))
- errx(1, "bad login (too long?)");
-
- buf = vmalloc(sizeof(*head) + userlen);
- if (buf == NULL)
- return NULL;
-
- head = (struct admin_com *)buf->v;
- head->ac_len = buf->l;
- head->ac_cmd = ADMIN_LOGOUT_USER;
- head->ac_errno = 0;
- head->ac_proto = 0;
-
- strncpy((char *)(head + 1), user, userlen);
-
- return buf;
-}
-#endif /* ENABLE_HYBRID */
-
-
-static int
-get_proto(str)
- char *str;
-{
- struct proto_tag *cp;
-
- if (str == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- /* checking the string of command. */
- for (cp = &prototab[0]; cp->str; cp++) {
- if (strcmp(str, cp->str) == 0)
- return cp->proto;
- }
-
- errno = EINVAL;
- return -1;
-}
-
-static vchar_t *
-get_index(ac, av)
- int ac;
- char **av;
-{
- int family;
-
- if (ac != 3 && ac != 4) {
- errno = EINVAL;
- return NULL;
- }
-
- /* checking the string of family */
- family = get_family(*av);
- if (family == -1)
- return NULL;
- av++;
- ac--;
-
- return get_comindexes(family, ac, av);
-}
-
-static int
-get_family(str)
- char *str;
-{
- if (strcmp("inet", str) == 0)
- return AF_INET;
-#ifdef INET6
- else if (strcmp("inet6", str) == 0)
- return AF_INET6;
-#endif
- errno = EAFNOSUPPORT;
- return -1;
-}
-
-static vchar_t *
-get_comindexes(family, ac, av)
- int family;
- int ac;
- char **av;
-{
- vchar_t *buf;
- struct admin_com_indexes *ci;
- char *p_name = NULL, *p_port = NULL;
- char *p_prefs = NULL, *p_prefd = NULL;
- struct sockaddr *src = NULL, *dst = NULL;
- int ulproto;
-
- if (ac != 2 && ac != 3) {
- errno = EINVAL;
- return NULL;
- }
-
- if (get_comindex(*av, &p_name, &p_port, &p_prefs) == -1)
- goto bad;
- src = get_sockaddr(family, p_name, p_port);
- if (p_name) {
- racoon_free(p_name);
- p_name = NULL;
- }
- if (p_port) {
- racoon_free(p_port);
- p_port = NULL;
- }
- if (src == NULL)
- goto bad;
- av++;
- ac--;
- if (get_comindex(*av, &p_name, &p_port, &p_prefd) == -1)
- goto bad;
- dst = get_sockaddr(family, p_name, p_port);
- if (p_name) {
- racoon_free(p_name);
- p_name = NULL;
- }
- if (p_port) {
- racoon_free(p_port);
- p_port = NULL;
- }
- if (dst == NULL)
- goto bad;
-
- buf = vmalloc(sizeof(*ci));
- if (buf == NULL)
- goto bad;
-
- av++;
- ac--;
- if(ac){
- ulproto = get_ulproto(*av);
- if (ulproto == -1)
- goto bad;
- }else
- ulproto=0;
-
- ci = (struct admin_com_indexes *)buf->v;
- if(p_prefs)
- ci->prefs = (u_int8_t)atoi(p_prefs); /* XXX should be handled error. */
- else
- ci->prefs = 32;
- if(p_prefd)
- ci->prefd = (u_int8_t)atoi(p_prefd); /* XXX should be handled error. */
- else
- ci->prefd = 32;
- ci->ul_proto = ulproto;
- memcpy(&ci->src, src, sysdep_sa_len(src));
- memcpy(&ci->dst, dst, sysdep_sa_len(dst));
-
- if (p_name)
- racoon_free(p_name);
-
- return buf;
-
- bad:
- if (p_name)
- racoon_free(p_name);
- if (p_port)
- racoon_free(p_port);
- if (p_prefs)
- racoon_free(p_prefs);
- if (p_prefd)
- racoon_free(p_prefd);
- return NULL;
-}
-
-static int
-get_comindex(str, name, port, pref)
- char *str, **name, **port, **pref;
-{
- char *p;
-
- *name = *port = *pref = NULL;
-
- *name = racoon_strdup(str);
- STRDUP_FATAL(*name);
- p = strpbrk(*name, "/[");
- if (p != NULL) {
- if (*(p + 1) == '\0')
- goto bad;
- if (*p == '/') {
- *p = '\0';
- *pref = racoon_strdup(p + 1);
- STRDUP_FATAL(*pref);
- p = strchr(*pref, '[');
- if (p != NULL) {
- if (*(p + 1) == '\0')
- goto bad;
- *p = '\0';
- *port = racoon_strdup(p + 1);
- STRDUP_FATAL(*port);
- p = strchr(*pref, ']');
- if (p == NULL)
- goto bad;
- *p = '\0';
- }
- } else if (*p == '[') {
- if (*pref == NULL)
- goto bad;
- *p = '\0';
- *port = racoon_strdup(p + 1);
- STRDUP_FATAL(*port);
- p = strchr(*pref, ']');
- if (p == NULL)
- goto bad;
- *p = '\0';
- } else {
- /* XXX */
- }
- }
-
- return 0;
-
- bad:
-
- if (*name)
- racoon_free(*name);
- if (*port)
- racoon_free(*port);
- if (*pref)
- racoon_free(*pref);
- *name = *port = *pref = NULL;
- return -1;
-}
-
-static int
-get_ulproto(str)
- char *str;
-{
- struct ulproto_tag *cp;
-
- if(str == NULL){
- errno = EINVAL;
- return -1;
- }
-
- /* checking the string of upper layer protocol. */
- for (cp = &ulprototab[0]; cp->str; cp++) {
- if (strcmp(str, cp->str) == 0)
- return cp->ul_proto;
- }
-
- errno = EINVAL;
- return -1;
-}
-
-/* %%% */
-void
-dump_isakmp_sa(buf, len)
- char *buf;
- int len;
-{
- struct ph1dump *pd;
- struct tm *tm;
- char tbuf[56];
- caddr_t p = NULL;
-
-/* isakmp status header */
-/* short header;
- 1234567890123456789012 0000000000000000:0000000000000000 000000000000
-*/
-char *header1 =
-"Destination Cookies Created";
-
-/* semi long header;
- 1234567890123456789012 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
-*/
-char *header2 =
-"Destination Cookies ST S V E Created Phase2";
-
-/* long header;
- 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
-*/
-char *header3 =
-"Source Destination Cookies ST S V E Created Phase2";
-
-/* phase status header */
-/* short format;
- side stats source address destination address
- xxx xxxxx 1234567890123456789012 1234567890123456789012
-*/
-
- static char *estr[] = { "", "B", "M", "U", "A", "I", };
-
- switch (long_format) {
- case 0:
- printf("%s\n", header1);
- break;
- case 1:
- printf("%s\n", header2);
- break;
- case 2:
- default:
- printf("%s\n", header3);
- break;
- }
-
- if (len % sizeof(*pd))
- printf("invalid length %d\n", len);
- len /= sizeof(*pd);
-
- pd = (struct ph1dump *)buf;
-
- while (len-- > 0) {
- /* source address */
- if (long_format >= 2) {
- GETNAMEINFO((struct sockaddr *)&pd->local, _addr1_, _addr2_);
- switch (long_format) {
- case 0:
- break;
- case 1:
- p = fixed_addr(_addr1_, _addr2_, 22);
- break;
- case 2:
- default:
- p = fixed_addr(_addr1_, _addr2_, 45);
- break;
- }
- printf("%s ", p);
- }
-
- /* destination address */
- GETNAMEINFO((struct sockaddr *)&pd->remote, _addr1_, _addr2_);
- switch (long_format) {
- case 0:
- case 1:
- p = fixed_addr(_addr1_, _addr2_, 22);
- break;
- case 2:
- default:
- p = fixed_addr(_addr1_, _addr2_, 45);
- break;
- }
- printf("%s ", p);
-
- printf("%s ", pindex_isakmp(&pd->index));
-
- /* statuc, side and version */
- if (long_format >= 1) {
- printf("%2d %c %2x ",
- pd->status,
- pd->side == INITIATOR ? 'I' : 'R',
- pd->version);
- if (ARRAYLEN(estr) > pd->etype)
- printf("%s ", estr[pd->etype]);
- }
-
- /* created date */
- if (pd->created) {
- tm = localtime(&pd->created);
- strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);
- } else
- snprintf(tbuf, sizeof(tbuf), " ");
- printf("%s ", tbuf);
-
- /* counter of phase 2 */
- if (long_format >= 1)
- printf("%6d ", pd->ph2cnt);
-
- printf("\n");
-
- pd++;
- }
-
- return;
-}
-
-/* %%% */
-void
-dump_internal(buf, tlen)
- char *buf;
- int tlen;
-{
- struct ph2handle *iph2;
- struct sockaddr *addr;
-
-/*
-short header;
- source address destination address
- 1234567890123456789012 1234567890123456789012
-*/
-char *short_h1 =
-"Source Destination ";
-
-/*
-long header;
- source address destination address
- 123456789012345678901234567890123456789012345 123456789012345678901234567890123456789012345
- 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000
-*/
-char *long_h1 =
-"Source Destination ";
-
- printf("%s\n", long_format ? long_h1 : short_h1);
-
- while (tlen > 0) {
- iph2 = (struct ph2handle *)buf;
- addr = (struct sockaddr *)(++iph2);
-
- GETNAMEINFO(addr, _addr1_, _addr2_);
- printf("%s ", long_format ?
- fixed_addr(_addr1_, _addr2_, 45)
- : fixed_addr(_addr1_, _addr2_, 22));
- addr++;
- tlen -= sysdep_sa_len(addr);
-
- GETNAMEINFO(addr, _addr1_, _addr2_);
- printf("%s ", long_format ?
- fixed_addr(_addr1_, _addr2_, 45)
- : fixed_addr(_addr1_, _addr2_, 22));
- addr++;
- tlen -= sysdep_sa_len(addr);
-
- printf("\n");
- }
-
- return;
-}
-
-/* %%% */
-char *
-pindex_isakmp(index)
- isakmp_index *index;
-{
- static char buf[64];
- u_char *p;
- int i, j;
-
- memset(buf, 0, sizeof(buf));
-
- /* copy index */
- p = (u_char *)index;
- for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
- snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
- j += 2;
- switch (i) {
- case 7:
-#if 0
- case 15:
-#endif
- buf[j++] = ':';
- }
- }
-
- return buf;
-}
-
-/* print schedule */
-char *str_sched_stat[] = {
-"off",
-"on",
-"dead",
-};
-
-char *str_sched_id[] = {
-"PH1resend",
-"PH1lifetime",
-"PH2resend",
-"PSTacquire",
-"PSTlifetime",
-};
-
-void
-print_schedule(buf, len)
- caddr_t buf;
- int len;
-{
- struct scheddump *sc = (struct scheddump *)buf;
- struct tm *tm;
- char tbuf[56];
-
- if (len % sizeof(*sc))
- printf("invalid length %d\n", len);
- len /= sizeof(*sc);
-
- /* 00000000 00000000 00000000 xxx........*/
- printf("index tick xtime created\n");
-
- while (len-- > 0) {
- tm = localtime(&sc->created);
- strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);
-
- printf("%-8ld %-8ld %-8ld %s\n",
- sc->id,
- (long)sc->tick,
- (long)sc->xtime,
- tbuf);
- sc++;
- }
-
- return;
-}
-
-
-void
-print_evt(buf, len)
- caddr_t buf;
- int len;
-{
- struct evtdump *evtdump = (struct evtdump *)buf;
- int i;
- char *srcstr;
- char *dststr;
-
- for (i = 0; evtmsg[i].msg; i++)
- if (evtmsg[i].type == evtdump->type)
- break;
-
- if (evtmsg[i].msg == NULL)
- printf("Event %d: ", evtdump->type);
- else
- printf("%s : ", evtmsg[i].msg);
-
- if ((srcstr = saddr2str((struct sockaddr *)&evtdump->src)) == NULL)
- printf("unknown");
- else
- printf("%s", srcstr);
- printf(" -> ");
- if ((dststr = saddr2str((struct sockaddr *)&evtdump->dst)) == NULL)
- printf("unknown");
- else
- printf("%s", dststr);
- printf("\n");
-
- return;
-}
-
-void
-print_err(buf, len)
- caddr_t buf;
- int len;
-{
- struct evtdump *evtdump = (struct evtdump *)buf;
- int i;
-
-
- for (i = 0; evtmsg[i].msg; i++)
- if (evtmsg[i].type == evtdump->type)
- break;
-
- if (evtmsg[i].level != ERROR)
- return;
-
- if (evtmsg[i].msg == NULL)
- printf("Error: Event %d\n", evtdump->type);
- else
- printf("Error: %s\n", evtmsg[i].msg);
-
- if (evt_filter & EVTF_ERR_STOP)
- evt_filter &= ~EVTF_LOOP;
-
- return;
-}
-
-/*
- * Print a message when phase 1 SA goes down
- */
-void
-print_ph1down(buf, len)
- caddr_t buf;
- int len;
-{
- struct evtdump *evtdump = (struct evtdump *)buf;
-
- if (evtdump->type != EVTT_PHASE1_DOWN)
- return;
-
- printf("VPN connexion terminated\n");
-
- if (evt_filter & EVTF_PH1DOWN_STOP)
- evt_filter &= ~EVTF_LOOP;
-
- return;
-}
-
-/*
- * Print ISAKMP mode config info (IP and banner)
- */
-void
-print_cfg(buf, len)
- caddr_t buf;
- int len;
-{
- struct evtdump *evtdump = (struct evtdump *)buf;
- struct isakmp_data *attr;
- char *banner = NULL;
- struct in_addr addr4;
-
- memset(&addr4, 0, sizeof(addr4));
-
- if (evtdump->type != EVTT_ISAKMP_CFG_DONE &&
- evtdump->type != EVTT_NO_ISAKMP_CFG)
- return;
-
- len -= sizeof(*evtdump);
- attr = (struct isakmp_data *)(evtdump + 1);
-
- while (len > 0) {
- if (len < sizeof(*attr)) {
- printf("short attribute too short\n");
- break;
- }
-
- if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
- /* Short attribute, skip */
- len -= sizeof(*attr);
- attr++;
- } else { /* Long attribute */
- char *n;
-
- if (len < (sizeof(*attr) + ntohs(attr->lorv))) {
- printf("long attribute too long\n");
- break;
- }
-
- switch (ntohs(attr->type) & ~ISAKMP_GEN_MASK) {
- case INTERNAL_IP4_ADDRESS:
- if (ntohs(attr->lorv) < sizeof(addr4)) {
- printf("addr4 attribute too short\n");
- break;
- }
- memcpy(&addr4, attr + 1, sizeof(addr4));
- break;
-
- case UNITY_BANNER:
- banner = racoon_malloc(ntohs(attr->lorv) + 1);
- if (banner == NULL) {
- printf("malloc failed\n");
- break;
- }
- memcpy(banner, attr + 1, ntohs(attr->lorv));
- banner[ntohs(attr->lorv)] = '\0';
- break;
-
- default:
- break;
- }
-
- len -= (sizeof(*attr) + ntohs(attr->lorv));
- n = (char *)attr;
- attr = (struct isakmp_data *)
- (n + sizeof(*attr) + ntohs(attr->lorv));
- }
- }
-
- if (evtdump->type == EVTT_ISAKMP_CFG_DONE)
- printf("Bound to address %s\n", inet_ntoa(addr4));
- else
- printf("VPN connexion established\n");
-
- if (banner) {
- struct winsize win;
- int col = 0;
- int i;
-
- if (ioctl(1, TIOCGWINSZ, &win) != 1)
- col = win.ws_col;
-
- for (i = 0; i < col; i++)
- printf("%c", '=');
- printf("\n%s\n", banner);
- for (i = 0; i < col; i++)
- printf("%c", '=');
- printf("\n");
- racoon_free(banner);
- }
-
- if (evt_filter & EVTF_CFG_STOP)
- evt_filter &= ~EVTF_LOOP;
-
- return;
-}
-
-
-char *
-fixed_addr(addr, port, len)
- char *addr, *port;
- int len;
-{
- static char _addr_buf_[BUFSIZ];
- char *p;
- int plen, i;
-
- /* initialize */
- memset(_addr_buf_, ' ', sizeof(_addr_buf_));
-
- plen = strlen(port);
- if (len < plen + 1)
- return NULL;
-
- p = _addr_buf_;
- for (i = 0; i < len - plen - 1 && addr[i] != '\0'; /*noting*/)
- *p++ = addr[i++];
- *p++ = '.';
-
- for (i = 0; i < plen && port[i] != '\0'; /*noting*/)
- *p++ = port[i++];
-
- _addr_buf_[len] = '\0';
-
- return _addr_buf_;
-}
-
-static int
-handle_recv(combuf)
- vchar_t *combuf;
-{
- struct admin_com h, *com;
- caddr_t buf;
- int len;
-
- com = (struct admin_com *)combuf->v;
- len = com->ac_len - sizeof(*com);
- buf = combuf->v + sizeof(*com);
-
- switch (com->ac_cmd) {
- case ADMIN_SHOW_SCHED:
- print_schedule(buf, len);
- break;
-
- case ADMIN_SHOW_EVT: {
- struct evtdump *evtdump;
-
- /* We got no event */
- if (len == 0) {
- /* If we were purging the queue, it is now done */
- if (evt_filter & EVTF_PURGE)
- evt_filter &= ~EVTF_PURGE;
- break;
- }
-
- if (len < sizeof(struct evtdump))
- errx(1, "Short buffer\n");
-
- /* Toss outdated events */
- evtdump = (struct evtdump *)buf;
- if (evtdump->timestamp < evt_start)
- break;
-
- if (evt_filter & EVTF_ALL)
- print_evt(buf, len);
- if (evt_filter & EVTF_ERR)
- print_err(buf, len);
- if (evt_filter & EVTF_CFG)
- print_cfg(buf, len);
- if (evt_filter & EVTF_PH1DOWN)
- print_ph1down(buf, len);
- break;
- }
-
- case ADMIN_SHOW_SA:
- {
- switch (com->ac_proto) {
- case ADMIN_PROTO_ISAKMP:
- dump_isakmp_sa(buf, len);
- break;
- case ADMIN_PROTO_IPSEC:
- case ADMIN_PROTO_AH:
- case ADMIN_PROTO_ESP:
- {
- struct sadb_msg *msg = (struct sadb_msg *)buf;
-
- switch (msg->sadb_msg_errno) {
- case ENOENT:
- switch (msg->sadb_msg_type) {
- case SADB_DELETE:
- case SADB_GET:
- printf("No entry.\n");
- break;
- case SADB_DUMP:
- printf("No SAD entries.\n");
- break;
- }
- break;
- case 0:
- while (1) {
- pfkey_sadump(msg);
- if (msg->sadb_msg_seq == 0)
- break;
- msg = (struct sadb_msg *)((caddr_t)msg +
- PFKEY_UNUNIT64(msg->sadb_msg_len));
- }
- break;
- default:
- printf("%s.\n", strerror(msg->sadb_msg_errno));
- }
- }
- break;
- case ADMIN_PROTO_INTERNAL:
- dump_internal(buf, len);
- break;
- default:
- printf("Invalid proto [%d]\n", com->ac_proto);
- }
-
- }
- break;
-
- default:
- /* IGNORE */
- break;
- }
-
- close(so);
- return 0;
-
- bad:
- close(so);
- return -1;
-}