Exemple #1
0
int hip_setup_hit_sp_pair(hip_hit_t *src_hit, hip_hit_t *dst_hit,
			  struct in6_addr *src_addr,
			  struct in6_addr *dst_addr, u8 proto,
			  int use_full_prefix, int update)
{
	int so, len, err = 0;
	u_int prefs, prefd;
	u8 prefix = (use_full_prefix) ? 128 : HIP_HIT_PREFIX_LEN;
	int cmd = update ? SADB_X_SPDUPDATE : SADB_X_SPDADD;

	HIP_DEBUG("\n");
	HIP_IFEL(((so = pfkey_open()) < 0), -1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	HIP_DEBUG("Adding a pair of SP\n");

	HIP_IFEBL((hip_pfkey_policy_modify(so, dst_hit, prefix, src_hit, 
					   prefix, src_addr, dst_addr, 
					   proto, cmd, IPSEC_DIR_INBOUND)<0),
		  -1, pfkey_close(so), "ERROR in %s the inbound policy\n", update ? "updating" : "adding");

	HIP_IFEL(((so = pfkey_open()) < 0), -1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	HIP_IFEBL((hip_pfkey_policy_modify(so, src_hit, prefix, dst_hit, 
					   prefix, dst_addr, src_addr,
					   proto, cmd, IPSEC_DIR_OUTBOUND)<0),
		  -1, pfkey_close(so), "ERROR in %s the outbound policy\n", update ? "updating" : "adding");
	return 0;
out_err:
	return err;
}
Exemple #2
0
static int
verifypriority(struct sadb_msg *m)
{
	caddr_t mhp[SADB_EXT_MAX + 1];
	struct sadb_x_policy *xpl;

	/* check pfkey message. */
	if (pfkey_align(m, mhp)) {
		printf("(%s\n", ipsec_strerror());
		return 0;
	}
	if (pfkey_check(mhp)) {
		printf("%s\n", ipsec_strerror());
		return 0;
	}

	xpl = (struct sadb_x_policy *) mhp[SADB_X_EXT_POLICY];

	if (xpl == NULL) {
		printf("no X_POLICY extension.\n");
		return 0;
	}

	/* now make sure they match */
	if (last_priority != xpl->sadb_x_policy_priority)
		return 0;

	return 1;
}
Exemple #3
0
int hip_pfkey_policy_modify(int so, hip_hit_t *src_hit, u_int prefs, 
			    hip_hit_t *dst_hit, u_int prefd,
			    struct in6_addr *src_addr, struct in6_addr *dst_addr,
			    u8 proto, int cmd, int direction)
{
	int err = 0;
	struct sockaddr_storage ss_addr, dd_addr, ss_hit, dd_hit;
	struct sockaddr *s_saddr, *s_shit;
	struct sockaddr *d_saddr, *d_shit;
	caddr_t policy = NULL;
	int policylen = 0;
	int len = 0;
	u_int mode;
	HIP_DEBUG("\n");
	// Sanity check
	HIP_IFEL((src_hit == NULL || dst_hit == NULL), -1, "Invalid hit's\n");

	if (src_addr) { // could happen with the delete
		s_saddr = (struct sockaddr*) &ss_addr;
		get_sock_addr_from_in6(s_saddr, src_addr);
	}

	if (dst_addr) { // could happen with the delete
		d_saddr = (struct sockaddr*) &dd_addr;
		get_sock_addr_from_in6(d_saddr, dst_addr);
	}

	s_shit = (struct sockaddr*) &ss_hit;
	get_sock_addr_from_in6(s_shit, src_hit);
	d_shit = (struct sockaddr*) &dd_hit;
	get_sock_addr_from_in6(d_shit, dst_hit);
	if (proto)
		mode = HIP_IPSEC_DEFAULT_MODE;
	else
		mode = IPSEC_MODE_TRANSPORT;

	HIP_IFEL((getsadbpolicy(&policy, &policylen, direction, s_saddr, d_saddr, mode, cmd)<0),
		 -1, "Error in building the policy\n");

	if (cmd == SADB_X_SPDUPDATE) {
		HIP_IFEL((len = pfkey_send_spdupdate(so, s_shit, prefs, d_shit, prefd,
						  proto, policy, policylen, 0)<0), -1,
			 "libipsec failed send_x4 (%s)\n", ipsec_strerror());
	} else if (cmd == SADB_X_SPDADD) {
		HIP_IFEL((len = pfkey_send_spdadd(so, s_shit, prefs, d_shit, prefd,
						  proto, policy, policylen, 0)<0), -1,
			 "libipsec failed send_x4 (%s)\n", ipsec_strerror());
	} else {  // SADB_X_SPDDELETE
		HIP_IFEL((len = pfkey_send_spddelete(so, s_shit, prefs, d_shit, prefd,
						  proto, policy, policylen, 0)<0), -1,
			 "libipsec failed send_x4 (%s)\n", ipsec_strerror());
	}

	return len;
out_err:
	return err;
}
Exemple #4
0
void hip_delete_sa(u32 spi, struct in6_addr *peer_addr, struct in6_addr *dst_addr,
		   int direction, hip_ha_t *entry)
{
	int so, len, err = 0;
	struct sockaddr_storage ss_addr, dd_addr;
	struct sockaddr *saddr;
	struct sockaddr *daddr;
	in_port_t sport, dport;

	/* @todo: sport and dport should be used! */

	if (direction == HIP_SPI_DIRECTION_OUT)
	{
		sport = entry->local_udp_port;
		dport = entry->peer_udp_port;
		entry->outbound_sa_count--;
		if (entry->outbound_sa_count < 0) {
			HIP_ERROR("Warning: out sa count negative\n");
			entry->outbound_sa_count = 0;
		}
	}
	else
	{
		sport = entry->peer_udp_port;
		dport = entry->local_udp_port;
		entry->inbound_sa_count--;
		if (entry->inbound_sa_count < 0) {
			HIP_ERROR("Warning: in sa count negative\n");
			entry->inbound_sa_count = 0;
		}
	}

	saddr = (struct sockaddr*) &ss_addr;
	daddr = (struct sockaddr*) &dd_addr;

	HIP_DEBUG("\n");
	HIP_DEBUG("spi=0x%x\n", spi);
	HIP_DEBUG_IN6ADDR("peer_addr", peer_addr);
	HIP_DEBUG_IN6ADDR("dst_addr", dst_addr);
	// Sanity check
	HIP_IFEL((!peer_addr || !dst_addr), -1, "Addresses not valid when deleting SA's\n");

	HIP_IFEL(((so = pfkey_open()) < 0), -1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	get_sock_addr_from_in6(saddr, peer_addr);
	get_sock_addr_from_in6(daddr, dst_addr);

	HIP_IFEBL(((len = pfkey_send_delete(so, SADB_SATYPE_ESP,  HIP_IPSEC_DEFAULT_MODE, saddr, daddr, spi))<0), -1,
		  pfkey_close(so), "ERROR in deleting sa %s", ipsec_strerror());
out_err:
	return;
}
Exemple #5
0
int hip_flush_all_sa()
{
	int so, len, err = 0;
	HIP_DEBUG("\n");
	HIP_IFEL(((so = pfkey_open()) < 0), -1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	HIP_DEBUG("Flushing all SA's\n");
	HIP_IFEBL(((len = pfkey_send_flush(so, SADB_SATYPE_ESP))<0), -1,
		   pfkey_close(so), "ERROR in flushing policies %s\n", ipsec_strerror());
	return len;
out_err:
	return err;
}
Exemple #6
0
int hip_flush_all_policy()
{
	int so, len, err = 0;
	HIP_DEBUG("\n");
	HIP_IFEL(((so = pfkey_open()) < 0), -1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	HIP_DEBUG("FLushing all SP's\n");
	HIP_IFEBL(((len = pfkey_send_spdflush(so))<0), -1, 
		  pfkey_close(so), "ERROR in flushing policies %s\n", ipsec_strerror());
	HIP_DEBUG("FLushing all SP's was successful\n");
	return len;
out_err:
	HIP_ERROR("FLushing all SP's\n");
	return err;
}
Exemple #7
0
char *setpolicy(char *req)
{
	int len;
	char *buf;

	if ((len = ipsec_get_policylen(req)) < 0) {
		printf("ipsec_get_policylen: %s\n", ipsec_strerror());
		return NULL;
	}

	if ((buf = malloc(len)) == NULL) {
		perror("malloc");
		return NULL;
	}

	if ((len = ipsec_set_policy(buf, len, req)) < 0) {
		printf("ipsec_set_policy: %s\n", ipsec_strerror());
		free(buf);
		return NULL;
	}

	return buf;
}
Exemple #8
0
void hip_delete_hit_sp_pair(hip_hit_t *src_hit, hip_hit_t *dst_hit, u8 proto,
			    int use_full_prefix)
{
	int so, len, err = 0;
	u8 prefix = (use_full_prefix) ? 128 : HIP_HIT_PREFIX_LEN;

	HIP_DEBUG("\n");
	HIP_IFEL(((so = pfkey_open()) < 0), -1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	HIP_IFEBL((hip_pfkey_policy_modify(so, dst_hit, prefix, src_hit, 
					   prefix, NULL, NULL, 
					   proto, SADB_X_SPDDELETE, IPSEC_DIR_INBOUND)<0),
		  -1, pfkey_close(so), "ERROR in deleting the inbound policy\n");

	HIP_IFEL(((so = pfkey_open()) < 0), -1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	HIP_IFEBL((hip_pfkey_policy_modify(so, src_hit, prefix, dst_hit, 
					   prefix, NULL, NULL,
					   proto, SADB_X_SPDDELETE, IPSEC_DIR_OUTBOUND)<0),
		  -1, pfkey_close(so), "ERROR in deleting the outbound policy\n");
out_err:
	return;
}
Exemple #9
0
int test(char *policy, int family)
{
	int so, proto, optname;
	int len;
	char getbuf[1024];

	switch (family) {
	case PF_INET:
		proto = IPPROTO_IP;
		optname = IP_IPSEC_POLICY;
		break;
	case PF_INET6:
		proto = IPPROTO_IPV6;
		optname = IPV6_IPSEC_POLICY;
		break;
	}

	if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
		perror("socket");

	if (setsockopt(so, proto, optname, policy, PFKEY_EXTLEN(policy)) < 0)
		perror("setsockopt");

	len = sizeof(getbuf);
	memset(getbuf, 0, sizeof(getbuf));
	if (getsockopt(so, proto, optname, getbuf, &len) < 0)
		perror("getsockopt");

    {
	char *buf = NULL;

	printf("\tgetlen:%d\n", len);

	if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL)
		ipsec_strerror();
	else
		printf("\t[%s]\n", buf);

	free(buf);
    }

	close (so);
}
Exemple #10
0
static void
sock4_open(struct flags *flags
#ifdef IPSEC_POLICY_IPSEC
	   , char *policy
#endif /* IPSEC_POLICY_IPSEC */
	   )
{
#ifdef IPSEC
#ifndef IPSEC_POLICY_IPSEC
	int optval;
#endif
#endif

	if (with_v4dest == 0)
		return;
	if ((s4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
		syslog(LOG_ERR, "<%s> socket(v4): %s", __func__,
		       strerror(errno));
		exit(1);
	}

#if 0 /* XXX: not necessary ?? */
	/*
	 * join all routers multicast addresses.
	 */
	some_join_function();
#endif

#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
	if (flags->policy) {
		char *buf;
		buf = ipsec_set_policy(policy, strlen(policy));
		if (buf == NULL)
			errx(1, "%s", ipsec_strerror());
		/* XXX should handle in/out bound policy. */
		if (setsockopt(s4, IPPROTO_IP, IP_IPSEC_POLICY,
				buf, ipsec_get_policylen(buf)) < 0)
			err(1, "setsockopt(IP_IPSEC_POLICY)");
		free(buf);
	}
#else /* IPSEC_POLICY_IPSEC */
	if (flags->auth) {
		optval = IPSEC_LEVEL_REQUIRE;
		if (setsockopt(s4, IPPROTO_IP, IP_AUTH_TRANS_LEVEL,
			       &optval, sizeof(optval)) == -1) {
			syslog(LOG_ERR, "<%s> IP_AUTH_TRANS_LEVEL: %s",
			       __func__, strerror(errno));
			exit(1);
		}
	}
	if (flags->encrypt) {
		optval = IPSEC_LEVEL_REQUIRE;
		if (setsockopt(s4, IPPROTO_IP, IP_ESP_TRANS_LEVEL,
				&optval, sizeof(optval)) == -1) {
			syslog(LOG_ERR, "<%s> IP_ESP_TRANS_LEVEL: %s",
			       __func__, strerror(errno));
			exit(1);
		}
	}
#endif /* IPSEC_POLICY_IPSEC */
#endif /* IPSEC */

	return;
}
Exemple #11
0
static void
sock6_open(struct flags *flags
#ifdef IPSEC_POLICY_IPSEC
	   , char *policy
#endif /* IPSEC_POLICY_IPSEC */
	   )
{
	struct icmp6_filter filt;
	int on;
#ifdef IPSEC
#ifndef IPSEC_POLICY_IPSEC
	int optval;
#endif
#endif

	if (with_v6dest == 0)
		return;
	if (with_v6dest &&
	    (s6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
		syslog(LOG_ERR, "<%s> socket(v6): %s", __func__,
		       strerror(errno));
		exit(1);
	}

	/*
	 * join all routers multicast addresses.
	 */
#if 0 /* XXX: not necessary ?? */
	join_multi(LL_ALLROUTERS);
	join_multi(SL_ALLROUTERS);
#endif

	/* set icmpv6 filter */
	ICMP6_FILTER_SETBLOCKALL(&filt);
	ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt);
	if (setsockopt(s6, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
		       sizeof(filt)) < 0) {
		syslog(LOG_ERR, "<%s> IICMP6_FILTER: %s",
		       __func__, strerror(errno));
		exit(1);
	}

	/* specify to tell receiving interface */
	on = 1;
	if (setsockopt(s6, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
		       sizeof(on)) < 0) {
		syslog(LOG_ERR, "<%s> IPV6_RECVPKTINFO: %s",
		       __func__, strerror(errno));
		exit(1);
	}

#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
	if (flags->policy) {
		char *buf;
		buf = ipsec_set_policy(policy, strlen(policy));
		if (buf == NULL)
			errx(1, "%s", ipsec_strerror());
		/* XXX should handle in/out bound policy. */
		if (setsockopt(s6, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
				buf, ipsec_get_policylen(buf)) < 0)
			err(1, "setsockopt(IPV6_IPSEC_POLICY)");
		free(buf);
	}
#else /* IPSEC_POLICY_IPSEC */
	if (flags->auth) {
		optval = IPSEC_LEVEL_REQUIRE;
		if (setsockopt(s6, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
			       &optval, sizeof(optval)) == -1) {
			syslog(LOG_ERR, "<%s> IPV6_AUTH_TRANS_LEVEL: %s",
			       __func__, strerror(errno));
			exit(1);
		}
	}
	if (flags->encrypt) {
		optval = IPSEC_LEVEL_REQUIRE;
		if (setsockopt(s6, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
				&optval, sizeof(optval)) == -1) {
			syslog(LOG_ERR, "<%s> IPV6_ESP_TRANS_LEVEL: %s",
			       __func__, strerror(errno));
			exit(1);
		}
	}
#endif /* IPSEC_POLICY_IPSEC */
#endif /* IPSEC */

	return;
}
Exemple #12
0
/* start l2tpd listner */
static int
l2tpd_listener_start(l2tpd_listener *_this)
{
	l2tpd *_l2tpd;
	int    af, lvl, opt, sock, ival;
	char   hbuf[NI_MAXHOST + NI_MAXSERV + 16];

	_l2tpd = _this->self;
	sock = -1;
	af = _this->bind.sin6.sin6_family;
	lvl = (af == AF_INET)? IPPROTO_IP : IPPROTO_IPV6;

	if (_this->tun_name[0] == '\0')
		strlcpy(_this->tun_name, L2TPD_DEFAULT_LAYER2_LABEL,
		    sizeof(_this->tun_name));
	if ((sock = socket(_this->bind.sin6.sin6_family,
	    SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) < 0) {
		l2tpd_log(_l2tpd, LOG_ERR,
		    "socket() failed in %s(): %m", __func__);
		goto fail;
	}
#if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF)
	ival = 1;
	if (setsockopt(sock, IPPROTO_IP, IP_STRICT_RCVIF, &ival, sizeof(ival))
	    != 0)
		l2tpd_log(_l2tpd, LOG_WARNING,
		    "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__);
#endif
	ival = 1;
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &ival, sizeof(ival))
	    != 0) {
		l2tpd_log(_l2tpd, LOG_ERR,
		    "setsockopt(,,SO_REUSEPORT) failed in %s(): %m", __func__);
		goto fail;
	}
	if (bind(sock, (struct sockaddr *)&_this->bind,
	    _this->bind.sin6.sin6_len) != 0) {
		l2tpd_log(_l2tpd, LOG_ERR, "Binding %s/udp: %m",
		    addrport_tostring((struct sockaddr *)&_this->bind,
		    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)));
		goto fail;
	}
#ifdef USE_LIBSOCKUTIL
	if (setsockoptfromto(sock) != 0) {
		l2tpd_log(_l2tpd, LOG_ERR,
		    "setsockoptfromto() failed in %s(): %m", __func__);
		goto fail;
	}
#else
	opt = (af == AF_INET)? IP_RECVDSTADDR : IPV6_RECVPKTINFO;
	ival = 1;
	if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
		l2tpd_log(_l2tpd, LOG_ERR,
		    "setsockopt(,,IP{,V6}_RECVDSTADDR) failed in %s(): %m",
		    __func__);
		goto fail;
	}
#endif
#ifdef USE_SA_COOKIE
	if (af == AF_INET) {
		ival = 1;
		if (setsockopt(sock, IPPROTO_IP, IP_IPSECFLOWINFO, &ival,
		    sizeof(ival)) != 0) {
			l2tpd_log(_l2tpd, LOG_ERR,
			    "setsockopt(,,IP_IPSECFLOWINFO) failed in %s(): %m",
			    __func__);
			goto fail;
		}
	}
#endif
#ifdef IP_PIPEX
	opt = (af == AF_INET)? IP_PIPEX : IPV6_PIPEX;
	ival = 1;
	if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0)
		l2tpd_log(_l2tpd, LOG_WARNING,
		    "%s(): setsockopt(IP{,V6}_PIPEX) failed: %m", __func__);
#endif
	if (_this->conf->require_ipsec) {
#ifdef IP_IPSEC_POLICY
		caddr_t  ipsec_policy_in, ipsec_policy_out;

		opt = (af == AF_INET)? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
		/*
		 * Note: ipsec_set_policy() will assign the buffer for
		 * yacc parser stack, however it never free.
		 * it cause memory leak (-2000byte).
		 */
		if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN,
		    strlen(L2TPD_IPSEC_POLICY_IN))) == NULL) {
			l2tpd_log(_l2tpd, LOG_ERR,
			    "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed "
			    "at %s(): %s: %m", __func__, ipsec_strerror());
		} else if (setsockopt(sock, lvl, opt, ipsec_policy_in,
		    ipsec_get_policylen(ipsec_policy_in)) < 0) {
			l2tpd_log(_l2tpd, LOG_WARNING,
			    "setsockopt(,,IP_IPSEC_POLICY(in)) failed "
			    "in %s(): %m", __func__);
		}
		if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT,
		    strlen(L2TPD_IPSEC_POLICY_OUT))) == NULL) {
			l2tpd_log(_l2tpd, LOG_ERR,
			    "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed "
			    "at %s(): %s: %m", __func__, ipsec_strerror());
		}
		if (ipsec_policy_out != NULL &&
		    setsockopt(sock, lvl, opt, ipsec_policy_out,
		    ipsec_get_policylen(ipsec_policy_out)) < 0) {
			l2tpd_log(_l2tpd, LOG_WARNING,
			    "setsockopt(,,IP_IPSEC_POLICY(out)) failed "
			    "in %s(): %m", __func__);
		}
		free(ipsec_policy_in);
		free(ipsec_policy_out);
#elif defined(IP_ESP_TRANS_LEVEL)
		opt = (af == AF_INET)
		    ? IP_ESP_TRANS_LEVEL : IPV6_ESP_TRANS_LEVEL;
		ival = IPSEC_LEVEL_REQUIRE;
		if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
			l2tpd_log(_l2tpd, LOG_WARNING,
			    "setsockopt(,,IP{,V6}_ESP_TRANS_LEVEL(out)) failed "
			    "in %s(): %m", __func__);
		}
#else
#error IP_IPSEC_POLICY or IP_ESP_TRANS_LEVEL must be usable.
#endif
	}

	_this->sock = sock;

	event_set(&_this->ev_sock, _this->sock, EV_READ | EV_PERSIST,
	    l2tpd_io_event, _this);
	event_add(&_this->ev_sock, NULL);

	l2tpd_log(_l2tpd, LOG_INFO, "Listening %s/udp (L2TP LNS) [%s]",
	    addrport_tostring((struct sockaddr *)&_this->bind,
	    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->tun_name);

	return 0;
fail:
	if (sock >= 0)
		close(sock);

	return 1;
}
Exemple #13
0
void
pfkey_spdump(struct sadb_msg *m)
{
	char pbuf[NI_MAXSERV];
	caddr_t mhp[SADB_EXT_MAX + 1];
	struct sadb_address *m_saddr, *m_daddr;
	struct sadb_x_policy *m_xpl;
	struct sadb_lifetime *m_lft = NULL;
	struct sockaddr *sa;
	u_int16_t port;

	/* check pfkey message. */
	if (pfkey_align(m, mhp)) {
		printf("%s\n", ipsec_strerror());
		return;
	}
	if (pfkey_check(mhp)) {
		printf("%s\n", ipsec_strerror());
		return;
	}

	m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
	m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
	m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
	m_lft = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];

	/* source address */
	if (m_saddr == NULL) {
		printf("no ADDRESS_SRC extension.\n");
		return;
	}
	sa = (struct sockaddr *)(m_saddr + 1);
	switch (sa->sa_family) {
	case AF_INET:
	case AF_INET6:
		if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf),
		    NI_NUMERICSERV) != 0)
			port = 0;	/*XXX*/
		else
			port = atoi(pbuf);
		printf("%s%s ", str_ipaddr(sa),
			str_prefport(sa->sa_family,
			    m_saddr->sadb_address_prefixlen, port));
		break;
	default:
		printf("unknown-af ");
		break;
	}

	/* destination address */
	if (m_daddr == NULL) {
		printf("no ADDRESS_DST extension.\n");
		return;
	}
	sa = (struct sockaddr *)(m_daddr + 1);
	switch (sa->sa_family) {
	case AF_INET:
	case AF_INET6:
		if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf),
		    NI_NUMERICSERV) != 0)
			port = 0;	/*XXX*/
		else
			port = atoi(pbuf);
		printf("%s%s ", str_ipaddr(sa),
			str_prefport(sa->sa_family,
			    m_daddr->sadb_address_prefixlen, port));
		break;
	default:
		printf("unknown-af ");
		break;
	}

	/* upper layer protocol */
	if (m_saddr->sadb_address_proto != m_daddr->sadb_address_proto) {
		printf("upper layer protocol mismatched.\n");
		return;
	}
	if (m_saddr->sadb_address_proto == IPSEC_ULPROTO_ANY)
		printf("any");
	else
		GETMSGSTR(str_upper, m_saddr->sadb_address_proto);

	/* policy */
    {
	char *d_xpl;

	if (m_xpl == NULL) {
		printf("no X_POLICY extension.\n");
		return;
	}
	d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t");

	/* dump SPD */
	printf("\n\t%s\n", d_xpl);
	free(d_xpl);
    }

	/* lifetime */
	if (m_lft) {
		printf("\tlifetime:%lu validtime:%lu\n",
			(u_long)m_lft->sadb_lifetime_addtime,
			(u_long)m_lft->sadb_lifetime_usetime);
	}

	printf("\tspid=%ld seq=%ld pid=%ld\n",
		(u_long)m_xpl->sadb_x_policy_id,
		(u_long)m->sadb_msg_seq,
		(u_long)m->sadb_msg_pid);

	/* XXX TEST */
	printf("\trefcnt=%u\n", m->sadb_msg_reserved);

	return;
}
Exemple #14
0
/*
 * dump SADB_MSG formated.  For debugging, you should use kdebug_sadb().
 */
void
pfkey_sadump(struct sadb_msg *m)
{
	caddr_t mhp[SADB_EXT_MAX + 1];
	struct sadb_sa *m_sa;
	struct sadb_x_sa2 *m_sa2;
	struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts;
	struct sadb_address *m_saddr, *m_daddr;
	struct sadb_key *m_auth, *m_enc;

	/* check pfkey message. */
	if (pfkey_align(m, mhp)) {
		printf("%s\n", ipsec_strerror());
		return;
	}
	if (pfkey_check(mhp)) {
		printf("%s\n", ipsec_strerror());
		return;
	}

	m_sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
	m_sa2 = (struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2];
	m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
	m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
	m_lfts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT];
	m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
	m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
	m_auth = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH];
	m_enc = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT];

	/* source address */
	if (m_saddr == NULL) {
		printf("no ADDRESS_SRC extension.\n");
		return;
	}
	printf("%s ", str_ipaddr((struct sockaddr *)(m_saddr + 1)));

	/* destination address */
	if (m_daddr == NULL) {
		printf("no ADDRESS_DST extension.\n");
		return;
	}
	printf("%s ", str_ipaddr((struct sockaddr *)(m_daddr + 1)));

	/* SA type */
	if (m_sa == NULL) {
		printf("no SA extension.\n");
		return;
	}
	if (m_sa2 == NULL) {
		printf("no SA2 extension.\n");
		return;
	}
	printf("\n\t");

	GETMSGSTR(str_satype, m->sadb_msg_satype);

	printf("mode=");
	GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode);

	printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
		(u_int32_t)ntohl(m_sa->sadb_sa_spi),
		(u_int32_t)ntohl(m_sa->sadb_sa_spi),
		(u_int32_t)m_sa2->sadb_x_sa2_reqid,
		(u_int32_t)m_sa2->sadb_x_sa2_reqid);

	/* encryption key */
	if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
		printf("\tC: ");
		GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt);
	} else if (m->sadb_msg_satype == SADB_SATYPE_ESP) {
		if (m_enc != NULL) {
			printf("\tE: ");
			GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt);
			ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc),
				      m_enc->sadb_key_bits / 8);
			printf("\n");
		}
	}

	/* authentication key */
	if (m_auth != NULL) {
		printf("\tA: ");
		GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth);
		ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth),
		              m_auth->sadb_key_bits / 8);
		printf("\n");
	}

	/* replay windoe size & flags */
	printf("\tseq=0x%08x replay=%u flags=0x%08x ",
		m_sa2->sadb_x_sa2_sequence,
		m_sa->sadb_sa_replay,
		m_sa->sadb_sa_flags);

	/* state */
	printf("state=");
	GETMSGSTR(str_state, m_sa->sadb_sa_state);
	printf("\n");

	/* lifetime */
	if (m_lftc != NULL) {
		time_t tmp_time = time(0);

		printf("\tcreated: %s",
			str_time(m_lftc->sadb_lifetime_addtime));
		printf("\tcurrent: %s\n", str_time(tmp_time));
		printf("\tdiff: %lu(s)",
			(u_long)(m_lftc->sadb_lifetime_addtime == 0 ?
			0 : (tmp_time - m_lftc->sadb_lifetime_addtime)));

		printf("\thard: %lu(s)",
			(u_long)(m_lfth == NULL ?
			0 : m_lfth->sadb_lifetime_addtime));
		printf("\tsoft: %lu(s)\n",
			(u_long)(m_lfts == NULL ?
			0 : m_lfts->sadb_lifetime_addtime));

		printf("\tlast: %s",
			str_time(m_lftc->sadb_lifetime_usetime));
		printf("\thard: %lu(s)",
			(u_long)(m_lfth == NULL ?
			0 : m_lfth->sadb_lifetime_usetime));
		printf("\tsoft: %lu(s)\n",
			(u_long)(m_lfts == NULL ?
			0 : m_lfts->sadb_lifetime_usetime));

		str_lifetime_byte(m_lftc, "current");
		str_lifetime_byte(m_lfth, "hard");
		str_lifetime_byte(m_lfts, "soft");
		printf("\n");

		printf("\tallocated: %lu",
			(unsigned long)m_lftc->sadb_lifetime_allocations);
		printf("\thard: %lu",
			(u_long)(m_lfth == NULL ?
			0 : m_lfth->sadb_lifetime_allocations));
		printf("\tsoft: %lu\n",
			(u_long)(m_lfts == NULL ?
			0 : m_lfts->sadb_lifetime_allocations));
	}

	printf("\tsadb_seq=%lu pid=%lu ",
		(u_long)m->sadb_msg_seq,
		(u_long)m->sadb_msg_pid);

	/* XXX DEBUG */
	printf("refcnt=%u\n", m->sadb_msg_reserved);

	return;
}
Exemple #15
0
int
main(int argc, char **argv)
{
	FILE *fp = stdin;
	int c;

	if (argc == 1) {
		usage(0);
	}

	thiszone = gmt2local(0);

	while ((c = getopt(argc, argv, "acdf:HlnvxDFPphVrk?")) != -1) {
		switch (c) {
		case 'c':
			f_mode = MODE_STDIN;
#ifdef HAVE_READLINE
			/* disable filename completion */
			rl_bind_key('\t', rl_insert);
#endif
			break;
		case 'f':
			f_mode = MODE_SCRIPT;
			if (strcmp(optarg, "-") == 0) {
				fp = stdin;
			} else if ((fp = fopen(optarg, "r")) == NULL) {
				err(1, "Can't open `%s'", optarg);
			}
			break;
		case 'D':
			f_mode = MODE_CMDDUMP;
			break;
		case 'F':
			f_mode = MODE_CMDFLUSH;
			break;
		case 'a':
			f_all = 1;
			break;
		case 'l':
			f_forever = 1;
			break;
		case 'n':
			f_notreally = 1;
			break;
#ifdef __NetBSD__
		case 'h':
#endif
		case 'H':
			f_hexdump = 1;
			break;
		case 'x':
			f_mode = MODE_PROMISC;
			f_tflag++;
			break;
		case 'P':
			f_policy = 1;
			break;
		case 'p':
			f_withports = 1;
			break;
		case 'v':
			f_verbose = 1;
			break;
		case 'r':
#ifdef HAVE_POLICY_FWD
			f_rfcmode = 1;
#else
			rkwarn();
#endif
			break;
		case 'k':
#ifdef HAVE_POLICY_FWD
			f_rfcmode = 0;
#else
			rkwarn();
#endif
			break;
		case 'V':
			usage(1);
			break;
#ifndef __NetBSD__
		case 'h':
#endif
		case '?':
		default:
			usage(0);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc > 0) {
		while (argc--) {
			if (fileproc(*argv++) < 0) {
				err(1, "%s", argv[-1]);
			}
		}
		exit(0);
	}

	so = pfkey_open();
	if (so < 0) {
		perror("pfkey_open");
		exit(1);
	}

	switch (f_mode) {
	case MODE_CMDDUMP:
		sendkeyshort(f_policy ? SADB_X_SPDDUMP : SADB_DUMP);
		break;
	case MODE_CMDFLUSH:
		sendkeyshort(f_policy ? SADB_X_SPDFLUSH: SADB_FLUSH);
		break;
	case MODE_SCRIPT:
		if (get_supported() < 0) {
			errx(1, "%s", ipsec_strerror());
		}
		if (parse(&fp))
			exit(1);
		break;
	case MODE_STDIN:
		if (get_supported() < 0) {
			errx(1, "%s", ipsec_strerror());
		}
		stdin_loop();
		break;
	case MODE_PROMISC:
		promisc();
		/* NOTREACHED */
	default:
		usage(0);
	}

	exit(0);
}
Exemple #16
0
/* Security associations in the kernel with BEET are bounded to the outer
 * address, meaning IP addresses. As a result the parameters to be given
 * should be such an addresses and not the HITs.
 */
uint32_t hip_add_sa(struct in6_addr *saddr, struct in6_addr *daddr,
		    struct in6_addr *src_hit, struct in6_addr *dst_hit,
		    uint32_t spi, int ealg, struct hip_crypto_key *enckey,
		    struct hip_crypto_key *authkey,
		    int already_acquired, int direction, int update,
		    hip_ha_t *entry)
{

	int so, len, err = 0, e_keylen, a_keylen;
	int aalg = ealg;
	u_int wsize = 4;  /* XXX static size of window */
	struct sockaddr_storage ss_addr, dd_addr;
	struct sockaddr *s_saddr;
	struct sockaddr *d_saddr;
	uint32_t reqid = 0;
	u_int32_t seq = 0;
	u_int flags = 0; // always zero
	u_int64_t lifebyte = 0, lifetime = 0;
	//u_int8_t l_natt_type = HIP_UDP_ENCAP_ESPINUDP_NON_IKE;
	u_int8_t l_natt_type = HIP_UDP_ENCAP_ESPINUDP;
	// FIXME: this parameter maybe should be related to some esp parameters (according to racoon source code)
	u_int16_t l_natt_frag = 0;
	/* Mappings from HIP to PFKEY algo names */
	u_int e_types[] = {SADB_EALG_NULL, SADB_X_EALG_AESCBC, SADB_EALG_3DESCBC, SADB_EALG_3DESCBC,
			   SADB_X_EALG_BLOWFISHCBC, SADB_EALG_NULL, SADB_EALG_NULL};
	u_int a_algos[] = {SADB_AALG_NONE, SADB_AALG_SHA1HMAC, SADB_AALG_SHA1HMAC, SADB_AALG_MD5HMAC,
			   SADB_AALG_SHA1HMAC, SADB_AALG_SHA1HMAC, SADB_AALG_MD5HMAC};
	u_int e_type = e_types[ealg];
	u_int a_type = a_algos[aalg];
	in_port_t sport = entry->local_udp_port;
	in_port_t dport = entry->peer_udp_port;

	a_keylen = hip_auth_key_length_esp(ealg);
	e_keylen = hip_enc_key_length(ealg);

	get_random_bytes(&reqid, sizeof(uint32_t));
	get_random_bytes(&seq, sizeof(uint32_t));

	HIP_DEBUG("\n");
	HIP_DEBUG_HIT("src_hit", src_hit);
	HIP_DEBUG_HIT("dst_hit", dst_hit);
	HIP_DEBUG_IN6ADDR("saddr", saddr);
	HIP_DEBUG_IN6ADDR("daddr", daddr);
	HIP_IFEL((!saddr || !daddr), 1, "Addresses not valid when adding SA's\n");

	HIP_IFEL(((so = pfkey_open()) < 0), 1, "ERROR in opening pfkey socket: %s\n", ipsec_strerror());

	s_saddr = (struct sockaddr*) &ss_addr;
	d_saddr = (struct sockaddr*) &dd_addr;
	get_sock_addr_from_in6(s_saddr, saddr);
	get_sock_addr_from_in6(d_saddr, daddr);

	if (direction == HIP_SPI_DIRECTION_OUT)
	{
		entry->outbound_sa_count++;
	}
	else
	{
		entry->inbound_sa_count++;
	}


	// NOTE: port numbers remains in host representation
	if (update) {
		if (sport) {
			// pfkey_send_update_nat when update = 1 and sport != 0
			HIP_IFEBL(((len = pfkey_send_update_nat(so, SADB_SATYPE_ESP, HIP_IPSEC_DEFAULT_MODE, 
								s_saddr, d_saddr, spi, reqid, wsize,
								(void*) enckey, e_type, e_keylen, 
								a_type, a_keylen, flags,
								0, lifebyte, lifetime, 0, seq,
								l_natt_type, sport, dport, NULL,
								l_natt_frag)) < 0),
				  1, pfkey_close(so), "ERROR in updating sa for nat: %s\n", ipsec_strerror());
		} else {
			// pfkey_send_update when update = 1 and sport == 0
			HIP_IFEBL(((len = pfkey_send_update(so, SADB_SATYPE_ESP, HIP_IPSEC_DEFAULT_MODE,
							    s_saddr, d_saddr, spi, reqid, wsize,
							    (void*) enckey, e_type, e_keylen,
							    a_type, a_keylen, flags,
							    0, lifebyte, lifetime, 0, seq)) < 0),
				  1, pfkey_close(so), "ERROR in updating sa: %s\n", ipsec_strerror());
		}
	} else {
		if (sport) {
			// pfkey_send_add_nat when update = 0 and sport != 0 	
			HIP_IFEBL(((len = pfkey_send_add_nat(so, SADB_SATYPE_ESP, HIP_IPSEC_DEFAULT_MODE,
							     s_saddr, d_saddr, spi, reqid, wsize,
							     (void*) enckey, e_type, e_keylen, 
							     a_type, a_keylen, flags,
							     0, lifebyte, lifetime, 0, seq,
							     l_natt_type, sport, dport, NULL,
							     l_natt_frag)) < 0),
				  1, pfkey_close(so), "ERROR in adding sa for nat: %s\n", ipsec_strerror());
		} else {
			// pfkey_send_add when update = 0 and sport == 0
			HIP_IFEBL(((len = pfkey_send_add(so, SADB_SATYPE_ESP, HIP_IPSEC_DEFAULT_MODE,
							 s_saddr, d_saddr, spi, reqid, wsize,
							 (void*) enckey, e_type, e_keylen,
							 a_type, a_keylen, flags,
							 0, lifebyte, lifetime, 0, seq)) < 0),
				  1, pfkey_close(so), "ERROR in adding sa: %s\n", ipsec_strerror());
		}
	}

	return 0;

out_err:
	return err;
}