diff options
Diffstat (limited to 'src/racoon/racoonctl.c')
-rw-r--r-- | src/racoon/racoonctl.c | 1654 |
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; -} |