Пример #1
0
int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2)
{
	if (((struct sockaddr*)s1)->sa_family == AF_INET) {
		return memcmp(SA_IN_P(s1), SA_IN_P(s2), sizeof(struct in_addr));
	} else { /* inet6 */
		return memcmp(SA_IN6_P(s1), SA_IN6_P(s2), sizeof(struct in6_addr));
	}
}
Пример #2
0
/* Test the IP banning functionality */
static
unsigned check_if_banned_str(main_server_st *s, const char *ip)
{
	struct sockaddr_storage addr;
	int ret;

	if (strchr(ip, ':') != 0) {
		ret = inet_pton(AF_INET6, ip, SA_IN6_P(&addr));
		addr.ss_family = AF_INET6;
	} else {
		ret = inet_pton(AF_INET, ip, SA_IN_P(&addr));
		addr.ss_family = AF_INET;
	}

	if (ret != 1) {
		fprintf(stderr, "cannot convert IP: %s\n", ip);
		exit(1);
	}
	return check_if_banned(s, &addr, addr.ss_family==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6));
}
Пример #3
0
static void
add_utmp_entry(main_server_st *s, struct proc_st* proc)
{
#ifdef HAVE_LIBUTIL
	struct utmpx entry;
	struct timespec tv;
	
	if (s->config->use_utmp == 0)
		return;

	memset(&entry, 0, sizeof(entry));
	entry.ut_type = USER_PROCESS;
	entry.ut_pid = proc->pid;
	snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", proc->tun_lease.name);
	snprintf(entry.ut_user, sizeof(entry.ut_user), "%s", proc->username);
#ifdef __linux__
	if (proc->remote_addr_len == sizeof(struct sockaddr_in))
		memcpy(entry.ut_addr_v6, SA_IN_P(&proc->remote_addr), sizeof(struct in_addr));
	else
		memcpy(entry.ut_addr_v6, SA_IN6_P(&proc->remote_addr), sizeof(struct in6_addr));
#endif

	gettime(&tv);
	entry.ut_tv.tv_sec = tv.tv_sec;
	entry.ut_tv.tv_usec = tv.tv_nsec / 1000;
	getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, entry.ut_host, sizeof(entry.ut_host), NULL, 0, NI_NUMERICHOST);

	setutxent();
	pututxline(&entry);
	endutxent();

#if defined(WTMPX_FILE)
	updwtmpx(WTMPX_FILE, &entry);
#endif   
	
	return;
#endif
}
Пример #4
0
static
int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
{

	struct sockaddr_storage tmp, mask, network, rnd;
	unsigned i;
	unsigned max_loops = MAX_IP_TRIES;
	int ret;
	const char* c_network, *c_netmask;
	char buf[64];
	
	if (proc->config.ipv4_network && proc->config.ipv4_netmask) {
		c_network = proc->config.ipv4_network;
		c_netmask = proc->config.ipv4_netmask;
	} else {
		c_network = s->config->network.ipv4;
		c_netmask = s->config->network.ipv4_netmask;
	}

	if (c_network && c_netmask) {
		ret =
		    inet_pton(AF_INET, c_network, SA_IN_P(&network));

		if (ret != 1) {
			mslog(s, NULL, LOG_ERR, "error reading IP: %s", c_network);
			return -1;
		}

		ret =
		    inet_pton(AF_INET, c_netmask, SA_IN_P(&mask));
	
		if (ret != 1) {
			mslog(s, NULL, LOG_ERR, "error reading mask: %s", c_netmask);
			return -1;
		}

		proc->ipv4 = calloc(1, sizeof(*proc->ipv4));
		if (proc->ipv4 == NULL)
			return ERR_MEM;

		/* mask the network (just in case it is wrong) */
		for (i=0;i<sizeof(struct in_addr);i++)
			SA_IN_U8_P(&network)[i] &= (SA_IN_U8_P(&mask)[i]);
        	((struct sockaddr_in*)&network)->sin_family = AF_INET;
        	((struct sockaddr_in*)&network)->sin_port = 0;

        	memcpy(&tmp, &network, sizeof(tmp));
       		((struct sockaddr_in*)&tmp)->sin_family = AF_INET;
       		((struct sockaddr_in*)&tmp)->sin_port = 0;

		memset(&rnd, 0, sizeof(rnd));
		((struct sockaddr_in*)&rnd)->sin_family = AF_INET;
		((struct sockaddr_in*)&rnd)->sin_port = 0;

		do {
			if (max_loops == 0) {
				mslog(s, proc, LOG_ERR, "could not figure out a valid IPv4 IP.");
				ret = ERR_NO_IP;
				goto fail;
			}
			if (max_loops == MAX_IP_TRIES) {
				uint32_t t = hash_any(proc->username, strlen(proc->username), 0);
				memcpy(SA_IN_U8_P(&rnd), &t, 4);
			} else
				gnutls_rnd(GNUTLS_RND_NONCE, SA_IN_U8_P(&rnd), sizeof(struct in_addr));
			max_loops--;

        		if (SA_IN_U8_P(&rnd)[3] == 255) /* broadcast */
	        		bignum_add(SA_IN_U8_P(&rnd), sizeof(struct in_addr), 1);

			/* Mask the random number with the netmask */
        		for (i=0;i<sizeof(struct in_addr);i++) {
        			SA_IN_U8_P(&rnd)[i] &= ~(SA_IN_U8_P(&mask)[i]);
			}

			SA_IN_U8_P(&rnd)[sizeof(struct in_addr)-1] &= 0xFE;

			/* Now add the IP to the masked random number */
        		for (i=0;i<sizeof(struct in_addr);i++)
        			SA_IN_U8_P(&rnd)[i] |= (SA_IN_U8_P(&network)[i]);

 			/* check if it exists in the hash table */
			if (ip_lease_exists(s, &rnd, sizeof(struct sockaddr_in)) != 0) {
				mslog(s, proc, LOG_DEBUG, "cannot assign remote IP %s to '%s'; it is in use.", 
				      human_addr((void*)&rnd, sizeof(struct sockaddr_in), buf, sizeof(buf)), 
				      proc->username);
				continue;
			}

			memcpy(&proc->ipv4->lip, &rnd, sizeof(struct sockaddr_in));
        		proc->ipv4->lip_len = sizeof(struct sockaddr_in);

        		/* RIP = LIP + 1 */
        		memcpy(&tmp, &proc->ipv4->lip, sizeof(struct sockaddr_in));
        		bignum_add(SA_IN_U8_P(&tmp), sizeof(struct in_addr), 1);

 			/* check if it exists in the hash table */
			if (ip_lease_exists(s, &tmp, sizeof(struct sockaddr_in)) != 0) {
				mslog(s, proc, LOG_DEBUG, "cannot assign remote IP %s to '%s'; it is in use.", 
				      human_addr((void*)&tmp, sizeof(struct sockaddr_in), buf, sizeof(buf)), 
				      proc->username);
				continue;
			}

        		memcpy(&proc->ipv4->rip, &tmp, sizeof(struct sockaddr_in));
        		proc->ipv4->rip_len = sizeof(struct sockaddr_in);

        		/* mask the last IP with the netmask */
        		for (i=0;i<sizeof(struct in_addr);i++)
        			SA_IN_U8_P(&tmp)[i] &= (SA_IN_U8_P(&mask)[i]);

        		/* the result should match the network */
        		if (memcmp(SA_IN_U8_P(&network), SA_IN_U8_P(&tmp), sizeof(struct in_addr)) != 0) {
        			continue;
        		}

			mslog(s, proc, LOG_DEBUG, "selected IP for '%s': %s", proc->username,
			      human_addr((void*)&proc->ipv4->lip, proc->ipv4->lip_len, buf, sizeof(buf)));
        		
        		if (icmp_ping4(s, (void*)&proc->ipv4->lip, (void*)&proc->ipv4->rip) == 0)
        			break;
                } while(1);
	}

	return 0;

fail:
	free(proc->ipv4);
	proc->ipv4 = NULL;

	return ret;
}
Пример #5
0
static
int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
{

	struct sockaddr_storage tmp, mask, network, rnd;
	unsigned i;
	unsigned max_loops = MAX_IP_TRIES;
	int ret;
	const char* c_network, *c_netmask;
	char buf[64];

	/* Our IP accounting */
	if (proc->config.ipv4_network && proc->config.ipv4_netmask) {
		c_network = proc->config.ipv4_network;
		c_netmask = proc->config.ipv4_netmask;
	} else {
		c_network = s->config->network.ipv4;
		c_netmask = s->config->network.ipv4_netmask;
	}

	if (c_network == NULL || c_netmask == NULL) {
		mslog(s, NULL, LOG_DEBUG, "there is no IPv4 network assigned");
		return 0;
	}

	ret =
	    inet_pton(AF_INET, c_network, SA_IN_P(&network));
	if (ret != 1) {
		mslog(s, NULL, LOG_ERR, "error reading IP: %s", c_network);
		return -1;
	}

	ret =
	    inet_pton(AF_INET, c_netmask, SA_IN_P(&mask));
	if (ret != 1) {
		mslog(s, NULL, LOG_ERR, "error reading mask: %s", c_netmask);
		return -1;
	}

	/* mask the network (just in case it is wrong) */
	for (i=0;i<sizeof(struct in_addr);i++)
		SA_IN_U8_P(&network)[i] &= (SA_IN_U8_P(&mask)[i]);
       	((struct sockaddr_in*)&network)->sin_family = AF_INET;
       	((struct sockaddr_in*)&network)->sin_port = 0;

	if (proc->config.explicit_ipv4) {
		/* if an explicit IP is given for that client, then
		 * do implicit IP accounting. Require the address
		 * to be odd, so we use the next even address as PtP. */
		ret =
		    inet_pton(AF_INET, proc->config.explicit_ipv4, SA_IN_P(&tmp));

		if (ret != 1) {
			mslog(s, NULL, LOG_ERR, "error reading explicit IP: %s", proc->config.explicit_ipv4);
			return -1;
		}

		proc->ipv4 = talloc_zero(proc, struct ip_lease_st);
		if (proc->ipv4 == NULL)
			return ERR_MEM;

        	((struct sockaddr_in*)&tmp)->sin_family = AF_INET;
        	((struct sockaddr_in*)&tmp)->sin_port = 0;
		memcpy(&proc->ipv4->rip, &tmp, sizeof(struct sockaddr_in));
       		proc->ipv4->rip_len = sizeof(struct sockaddr_in);

		if (is_ipv4_ok(s, &proc->ipv4->rip, &network, &mask) == 0) {
			mslog(s, proc, LOG_DEBUG, "cannot assign explicit IP %s; it is in use or invalid", 
			      human_addr((void*)&tmp, sizeof(struct sockaddr_in), buf, sizeof(buf)));
			ret = ERR_NO_IP;
			goto fail;
		}

		/* LIP = network address + 1 */
		memcpy(&proc->ipv4->lip, &network, sizeof(struct sockaddr_in));
		proc->ipv4->lip_len = sizeof(struct sockaddr_in);
		SA_IN_U8_P(&proc->ipv4->lip)[3] |= 1;

		if (ip_cmp(&proc->ipv4->lip, &proc->ipv4->rip) == 0) {
			mslog(s, NULL, LOG_ERR, "cannot assign explicit IP %s; network: %s", proc->config.explicit_ipv4, c_network);
			ret = ERR_NO_IP;
			goto fail;
		}

		return 0;
	}