Exemple #1
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 #2
0
static void
priv_netinet_ipsec_policy_entrust_af(int asroot, int injail, struct test *test,
    int af)
{
	int error, level, optname;

	switch (af) {
	case AF_INET:
		level = IPPROTO_IP;
		optname = IP_IPSEC_POLICY;
		break;
#ifdef INET6
	case AF_INET6:
		level = IPPROTO_IPV6;
		optname = IPV6_IPSEC_POLICY;
		break;
#endif
	default:
		warnx("%s: unexpected address family", __func__);
		return;
	}
	error = setsockopt(sd, level, optname,
	    entrustbuf, ipsec_get_policylen(entrustbuf));
	if (asroot && injail)
		expect("priv_netinet_ipsec_policy_entrust(asroot, injail)",
		    error, 0, 0); /* XXX ipsec_set_policy */
	if (asroot && !injail)
		expect("priv_netinet_ipsec_policy_entrust(asroot, !injail)",
		    error, 0, 0);
	if (!asroot && injail)
		expect("priv_netinet_ipsec_policy_entrust(!asroot, injail)",
		    error, 0, 0); /* XXX ipsec_set_policy */
	if (!asroot && !injail)
		expect("priv_netinet_ipsec_policy_entrust(!asroot, !injail)",
		    error, 0, 0); /* XXX ipsec_set_policy */
}
Exemple #3
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 #4
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 #5
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;
}