예제 #1
0
void
vfree(vchar_t *var)
{
	if (var == NULL)
		return;

	if (var->v)
		(void)racoon_free(var->v);

	(void)racoon_free(var);

	return;
}
예제 #2
0
void
lcconf_setchroot(char* chroot)
{
	if (lcconf->chroot) {
		racoon_free(lcconf->chroot);
		lcconf->chroot = NULL;
	}
	lcconf->chroot = chroot;
}
예제 #3
0
int
lcconf_setpath(char* path, unsigned int path_type)
{
	if (path_type >= LC_PATHTYPE_MAX)
		return -1;

	if (lcconf->pathinfo[path_type])
		racoon_free(lcconf->pathinfo[path_type]);

	lcconf->pathinfo[path_type] = path;

	return 0;
}
예제 #4
0
void
flushlcconf()
{
	int i;

	setdefault();
	myaddr_flush();

	for (i = 0; i < LC_PATHTYPE_MAX; i++) {
		if (lcconf->pathinfo[i]) {
			racoon_free(lcconf->pathinfo[i]);
			lcconf->pathinfo[i] = NULL;
		}
	}
}
예제 #5
0
/*
 * schedule handler
 * OUT:
 *	time to block until next event.
 *	if no entry, NULL returned.
 */
struct timeval *
schedular()
{
	time_t now, delta;
	struct sched *p, *next = NULL;

	if (slept_at || woke_at) {
		plog(LLV_DEBUG, LOCATION, NULL,
			 "ignoring schedular until power-mgmt event is handled.\n");
		return NULL;
	}

	now = current_time();

	for (p = TAILQ_FIRST(&sctree); p; p = next) {
		/* if the entry has been dead, remove it */
		if (p->dead)
			goto next_schedule;

		/* if the time hasn't come, proceed to the next entry */
		if (now < p->xtime) {
			next = TAILQ_NEXT(p, chain);
			continue;
		}

		/* mark it with dead. and call the function. */
		p->dead = 1;
		if (p->func != NULL && !terminated)
			(p->func)(p->param);

	   next_schedule:
		next = TAILQ_NEXT(p, chain);
		TAILQ_REMOVE(&sctree, p, chain);
		racoon_free(p);
	}

	p = TAILQ_FIRST(&sctree);
	if (p == NULL)
		return NULL;

	now = current_time();

	delta = p->xtime - now;
	timeout.tv_sec = delta < 0 ? 0 : delta;
	timeout.tv_usec = 0;

	return &timeout;
}
예제 #6
0
void
plogdump_asl (aslmsg msg, int pri, const char *fmt, ...)
{
	caddr_t buf;
	size_t buflen = 512;
    va_list	args;
	char   *level;

	switch (pri) {
	case ASL_LEVEL_INFO:
		level = ASL_STRING_INFO;
		break;

	case ASL_LEVEL_NOTICE:
		level = ASL_STRING_NOTICE;
		break;

	case ASL_LEVEL_WARNING:
		level = ASL_STRING_WARNING;
		break;

	case ASL_LEVEL_ERR:
		level = ASL_STRING_ERR;
		break;

	case ASL_LEVEL_DEBUG:
		level = ASL_STRING_DEBUG;
		break;

	default:
		return;
	}

	asl_set(msg, ASL_KEY_LEVEL, level);

	buf = racoon_malloc(buflen);
	if (buf) {
		buf[0] = '\0';
		va_start(args, fmt);
		vsnprintf(buf, buflen, fmt, args);
//		asl_set(msg, ASL_KEY_MESSAGE, buf);
		va_end(args);
		racoon_free(buf);
	}
}
예제 #7
0
void
flushlcconf()
{
	int i;

	setdefault();
	clear_myaddr(&lcconf->myaddrs);
	for (i = 0; i < LC_PATHTYPE_MAX; i++) {
		if (lcconf->pathinfo[i]) {
			racoon_free(lcconf->pathinfo[i]);
			lcconf->pathinfo[i] = NULL;
		}
	}
	for (i = 0; i < LC_IDENTTYPE_MAX; i++) {
		if (lcconf->ident[i])
			vfree(lcconf->ident[i]);
		lcconf->ident[i] = NULL;
	}
}
예제 #8
0
void
plogdump_func(int pri, void *data, size_t len, const char *fmt, ...)
{
	caddr_t buf;
	size_t buflen;
	int i, j;
    va_list	args;
	char fmt_buf[512];

	/*
	 * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes
	 * + 2 newline + '\0'
	 */
	buflen = (len * 2) + (len / 4) + (len / 32) + 3;
	buf = racoon_malloc(buflen);

	i = 0;
	j = 0;
	while (j < len) {
		if (j % 32 == 0)
			buf[i++] = '\n';
		else
		if (j % 4 == 0)
			buf[i++] = ' ';
		snprintf(&buf[i], buflen - i, "%02x",
			((unsigned char *)data)[j] & 0xff);
		i += 2;
		j++;
	}
	if (buflen - i >= 2) {
		buf[i++] = '\n';
		buf[i] = '\0';
	}

	fmt_buf[0] = '\n';
	va_start(args, fmt);
	vsnprintf(fmt_buf, sizeof(fmt_buf), fmt, args);
	va_end(args);

	plog(pri, "%s %s", fmt_buf, buf);

	racoon_free(buf);
}
예제 #9
0
struct timeval *
schedular()
{
	time_t now, delta;
	struct sched *p, *next = NULL;

	now = current_time();

        for (p = TAILQ_FIRST(&sctree); p; p = next) {
		/* if the entry has been daed, remove it */
		if (p->dead)
			goto next_schedule;

		/* if the time hasn't come, proceed to the next entry */
		if (now < p->xtime) {
			next = TAILQ_NEXT(p, chain);
			continue;
		}

		/* mark it with dead. and call the function. */
		p->dead = 1;
		if (p->func != NULL)
			(p->func)(p->param);

	   next_schedule:
		next = TAILQ_NEXT(p, chain);
		TAILQ_REMOVE(&sctree, p, chain);
		racoon_free(p);
	}

	p = TAILQ_FIRST(&sctree);
	if (p == NULL)
		return NULL;

	now = current_time();

	delta = p->xtime - now;
	timeout.tv_sec = delta < 0 ? 0 : delta;
	timeout.tv_usec = 0;

	return &timeout;
}
예제 #10
0
void
gssapi_free_state(struct ph1handle *iph1)
{
	struct gssapi_ph1_state *gps;
	OM_uint32 maj_stat, min_stat;

	gps = gssapi_get_state(iph1);

	if (gps == NULL)
		return;

	gssapi_set_state(iph1, NULL);

	if (gps->gss_cred != GSS_C_NO_CREDENTIAL) {
		maj_stat = gss_release_cred(&min_stat, &gps->gss_cred);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION,
			    "releasing credentials\n");
	}
	racoon_free(gps);
}
예제 #11
0
vchar_t *
vmalloc(size_t size)
{
	vchar_t *var;

	if ((var = (vchar_t *)racoon_malloc(sizeof(*var))) == NULL)
		return NULL;

	var->l = size;
	if (size == 0) {
		var->v = NULL;
	} else {
		var->v = (caddr_t)racoon_calloc(1, size);
		if (var->v == NULL) {
			(void)racoon_free(var);
			return NULL;
		}
	}

	return var;
}
예제 #12
0
static void
setdefault()
{
	lcconf->uid = 0;
	lcconf->gid = 0;

	{
		int i = 0;
		for (; i < LC_PATHTYPE_MAX; i++) {
			if (lcconf->pathinfo[i]) {
				racoon_free(lcconf->pathinfo[i]);
				lcconf->pathinfo[i] = NULL;
			}
		}
	}

	lcconf_setchroot(NULL); 

	lcconf->port_isakmp = PORT_ISAKMP;
	lcconf->port_isakmp_natt = PORT_ISAKMP_NATT;
	lcconf->default_af = AF_INET;
	lcconf->pad_random = LC_DEFAULT_PAD_RANDOM;
	lcconf->pad_randomlen = LC_DEFAULT_PAD_RANDOMLEN;
	lcconf->pad_maxsize = LC_DEFAULT_PAD_MAXSIZE;
	lcconf->pad_strict = LC_DEFAULT_PAD_STRICT;
	lcconf->pad_excltail = LC_DEFAULT_PAD_EXCLTAIL;
	lcconf->retry_counter = LC_DEFAULT_RETRY_COUNTER;
	lcconf->retry_interval = LC_DEFAULT_RETRY_INTERVAL;
	lcconf->count_persend = LC_DEFAULT_COUNT_PERSEND;
	lcconf->secret_size = LC_DEFAULT_SECRETSIZE;
	lcconf->retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1;
	lcconf->wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE;
	lcconf->strict_address = FALSE;
	lcconf->complex_bundle = TRUE; /*XXX FALSE;*/
	lcconf->gss_id_enc = LC_GSSENC_UTF16LE; /* Windows compatibility */
	lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL;
	lcconf->pfkey_buffer_size = LC_DEFAULT_PFKEY_BUFFER_SIZE;
}
예제 #13
0
int
admin_handler()
{
	int so2;
	struct sockaddr_storage from;
	socklen_t fromlen = sizeof(from);
	struct admin_com com;
	char *combuf = NULL;
	pid_t pid = -1;
	int len, error = -1;

	so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen);
	if (so2 < 0) {
		plog(LLV_ERROR, LOCATION, NULL,
			"failed to accept admin command: %s\n",
			strerror(errno));
		return -1;
	}

	/* get buffer length */
	while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) {
		if (errno == EINTR)
			continue;
		plog(LLV_ERROR, LOCATION, NULL,
			"failed to recv admin command: %s\n",
			strerror(errno));
		goto end;
	}

	/* sanity check */
	if (len < sizeof(com)) {
		plog(LLV_ERROR, LOCATION, NULL,
			"invalid header length of admin command\n");
		goto end;
	}

	/* get buffer to receive */
	if ((combuf = racoon_malloc(com.ac_len)) == 0) {
		plog(LLV_ERROR, LOCATION, NULL,
			"failed to alloc buffer for admin command\n");
		goto end;
	}

	/* get real data */
	while ((len = recv(so2, combuf, com.ac_len, 0)) < 0) {
		if (errno == EINTR)
			continue;
		plog(LLV_ERROR, LOCATION, NULL,
			"failed to recv admin command: %s\n",
			strerror(errno));
		goto end;
	}

	if (com.ac_cmd == ADMIN_RELOAD_CONF) {
		/* reload does not work at all! */
		signal_handler(SIGHUP);
		goto end;
	}

	error = admin_process(so2, combuf);

    end:
	(void)close(so2);
	if (combuf)
		racoon_free(combuf);

	/* exit if child's process. */
	if (pid == 0 && !f_foreground)
		exit(error);

	return error;
}
예제 #14
0
int                     
checklaunchd()                  
{               
	launch_data_t checkin_response = NULL; 
#ifdef LION_TEST
    launch_data_t checkin_request = NULL;
#endif
	launch_data_t sockets_dict, listening_fd_array;
	launch_data_t listening_fd;
	struct sockaddr_storage fdsockaddr;
	socklen_t fdsockaddrlen = sizeof(fdsockaddr);
	int socketct;
	int i;
	int listenerct;
	int returnval = 0;
	int fd;
	
	/* check in with launchd */
#ifdef LION_TEST
    if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
#else
	if ((checkin_response = launch_socket_service_check_in()) == NULL) {
#endif
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_socket_service_check_in.\n");
		goto done;
	}
#ifdef LION_TEST
    if ((checkin_response = launch_msg(checkin_request)) == NULL) {
        plog(ASL_LEVEL_ERR, "failed to launch_msg.\n");
        goto done;
    }
#endif
	if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
		plog(ASL_LEVEL_ERR, 
			 "launch_data_get_type error %d\n",
			 launch_data_get_errno(checkin_response));
		goto done;
	}
	if ( (sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS)) == NULL){
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_data_dict_lookup.\n");
		goto done;
	}
	if ( !(socketct = launch_data_dict_get_count(sockets_dict))){
		plog(ASL_LEVEL_ERR, 
			 "launch_data_dict_get_count returns no socket defined.\n");
		goto done;
	}
	
	if ( (listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners")) == NULL ){
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_data_dict_lookup.\n");
		goto done;
	}
	listenerct = launch_data_array_get_count(listening_fd_array);
	for (i = 0; i < listenerct; i++) {
		listening_fd = launch_data_array_get_index(listening_fd_array, i);
		fd = launch_data_get_fd( listening_fd );
		if ( getsockname( fd , (struct sockaddr *)&fdsockaddr, &fdsockaddrlen)){
			continue;
		}
		
		/* Is this the VPN control socket? */ 
		if ( fdsockaddr.ss_family == AF_UNIX && 
				(!(strcmp(vpncontrolsock_path, ((struct sockaddr_un *)&fdsockaddr)->sun_path))))
		{       
			plog(ASL_LEVEL_INFO, 
				 "found launchd socket.\n");
			returnval = fd;
			break;
		}
	}
	// TODO: check if we have any leaked fd
	if ( listenerct == i){
		plog(ASL_LEVEL_ERR, 
			 "failed to find launchd socket\n");               
		returnval = 0;
	}
	
done:   
	if (checkin_response)
		launch_data_free(checkin_response);
	return(returnval);
}

		
void
vpncontrol_handler(void *unused)
{
	struct sockaddr_storage from;
	socklen_t fromlen = sizeof(from);
    int sock;

	struct vpnctl_socket_elem *sock_elem;
	
    sock_elem = racoon_malloc(sizeof(struct vpnctl_socket_elem));
	if (sock_elem == NULL) {
		plog(ASL_LEVEL_ERR, 
			"memory error: %s\n", strerror(errno));
		return; //%%%%%% terminate
	}
	LIST_INIT(&sock_elem->bound_addresses);
    
	sock_elem->sock = accept(lcconf->sock_vpncontrol, (struct sockaddr *)&from, &fromlen);
	if (sock_elem->sock < 0) {
		plog(ASL_LEVEL_ERR, 
			"failed to accept vpn_control command: %s\n", strerror(errno));
		racoon_free(sock_elem);
		return; //%%%%% terminate
	}
	LIST_INSERT_HEAD(&lcconf->vpnctl_comm_socks, sock_elem, chain);
    
    sock_elem->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, sock_elem->sock, 0, dispatch_get_main_queue());
    if (sock_elem->source == NULL) {
		plog(ASL_LEVEL_ERR, "could not create comm socket source.");
		racoon_free(sock_elem);
		return; //%%%%% terminate
    }
    dispatch_source_set_event_handler(sock_elem->source, 
                                        ^{
                                                vpncontrol_comm_handler(sock_elem);
                                        });
    sock = sock_elem->sock;
	
    dispatch_source_t the_source = sock_elem->source;
    dispatch_source_set_cancel_handler(sock_elem->source,
                                       ^{
                                           close(sock);
                                           dispatch_release(the_source); /* Release the source on cancel */
                                       });
예제 #15
0
/*
 * handling to receive Notification payload
 */
static int
isakmp_info_recv_n(struct ph1handle *iph1, rc_vchar_t *msg)
{
	struct isakmp_pl_n *n = NULL;
	unsigned int type;
	rc_vchar_t *pbuf;
	struct isakmp_parse_t *pa, *pap;
	char *spi;

	if (!(pbuf = isakmp_parse(msg)))
		return -1;
	pa = (struct isakmp_parse_t *)pbuf->v;
	for (pap = pa; pap->type; pap++) {
		switch (pap->type) {
		case ISAKMP_NPTYPE_HASH:
			/* do something here */
			break;
		case ISAKMP_NPTYPE_NONCE:
			/* send to ack */
			break;
		case ISAKMP_NPTYPE_N:
			n = (struct isakmp_pl_n *)pap->ptr;
			break;
		default:
			rc_vfree(pbuf);
			return -1;
		}
	}
	rc_vfree(pbuf);
	if (!n)
		return -1;

	type = get_uint16(&n->type);

	switch (type) {
	case ISAKMP_NTYPE_CONNECTED:
	case ISAKMP_NTYPE_RESPONDER_LIFETIME:
	case ISAKMP_NTYPE_REPLAY_STATUS:
		/* do something */
		break;
	case ISAKMP_NTYPE_INITIAL_CONTACT:
		info_recv_initialcontact(iph1);
		break;
	case ISAKMP_NTYPE_R_U_THERE:
		isakmp_info_recv_r_u(iph1, (struct isakmp_pl_ru *)n,
				     ((struct isakmp *)msg->v)->msgid);
		break;
	case ISAKMP_NTYPE_R_U_THERE_ACK:
		isakmp_info_recv_r_u_ack(iph1, (struct isakmp_pl_ru *)n,
					 ((struct isakmp *)msg->v)->msgid);
		break;

	default:
	    {
		uint32_t msgid = ((struct isakmp *)msg->v)->msgid;
		struct ph2handle *iph2;

		/* XXX there is a potential of dos attack. */
		if (msgid == 0) {
			/* delete ph1 */
			plog(PLOG_PROTOERR, PLOGLOC, 0,
				"delete phase1 handle.\n");
			return -1;
		} else {
			iph2 = getph2bymsgid(iph1, msgid);
			if (iph2 == NULL) {
				plog(PLOG_PROTOERR, PLOGLOC, 0,
					"unknown notify message, "
					"no phase2 handle found.\n");
			} else {
				/* delete ph2 */
				unbindph12(iph2);
				remph2(iph2);
				delph2(iph2);
			}
		}
	    }
		break;
	}

	/* get spi and allocate */
	if (get_uint16(&n->h.len) < sizeof(*n) + n->spi_size) {
		plog(PLOG_PROTOERR, PLOGLOC, 0,
			"invalid spi_size in notification payload.\n");
		return -1;
	}
	spi = val2str((char *)(n + 1), n->spi_size);

	plog(PLOG_DEBUG, PLOGLOC, 0,
		"notification message %d:%s, "
		"doi=%d proto_id=%d spi=%s(size=%d).\n",
		type, s_isakmp_notify_msg(type),
		get_uint32(&n->doi), n->proto_id, spi, n->spi_size);

	racoon_free(spi);

	return(0);
}
예제 #16
0
/* get local address against the destination. */
struct sockaddr *
getlocaladdr(struct sockaddr *remote, struct sockaddr *hint, int lport)
{
	struct sockaddr *local;
	socklen_t local_len = sizeof(struct sockaddr_storage);
	int s;			/* for dummy connection */
	extern struct rcf_interface *rcf_interface_head;

	if (hint && hint->sa_family == remote->sa_family) {
		local = rcs_sadup(hint);
		goto got;
	}

	/* allocate buffer */
	if ((local = racoon_calloc(1, local_len)) == NULL) {
		plog(PLOG_INTERR, PLOGLOC, NULL,
		     "failed to get address buffer.\n");
		goto err;
	}

	/* get real interface received packet */
	if ((s = socket(remote->sa_family, SOCK_DGRAM, 0)) < 0) {
		plog(PLOG_INTERR, PLOGLOC, NULL,
		     "socket (%s)\n", strerror(errno));
		goto err;
	}
	if ((rcf_interface_head->application_bypass != RCT_BOOL_OFF) &&
	    (setsockopt_bypass(s, remote->sa_family) < 0)) {
		close(s);
		goto err;
	}
	if (connect(s, remote, SOCKADDR_LEN(remote)) < 0) {
		plog(PLOG_INTERR, PLOGLOC, NULL,
		     "connect (%s)\n", strerror(errno));
		close(s);
		goto err;
	}

	if (getsockname(s, local, &local_len) < 0) {
		plog(PLOG_INTERR, PLOGLOC, NULL,
		     "getsockname (%s)\n", strerror(errno));
		close(s);
		goto err;
	}

	close(s);

    got:
	/* specify local port */
	local->sa_family = remote->sa_family;
	switch (remote->sa_family) {
	case AF_INET:
		((struct sockaddr_in *)local)->sin_port = htons(lport);
		break;
#ifdef INET6
	case AF_INET6:
		((struct sockaddr_in6 *)local)->sin6_port = htons(lport);
		break;
#endif
	default:
		plog(PLOG_INTERR, PLOGLOC, NULL,
		     "getlocaladdr: unexpected address family (%d)\n",
		     remote->sa_family);
		goto err;
	}

	return local;

      err:
	if (local != NULL)
		racoon_free(local);
	return NULL;
}