Exemplo n.º 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));
	}
}
Exemplo n.º 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));
}
Exemplo n.º 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
}
Exemplo n.º 4
0
static
int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
{

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

	if (proc->config.ipv6_network && proc->config.ipv6_netmask) {
		c_network = proc->config.ipv6_network;
		c_netmask = proc->config.ipv6_netmask;
	} else {
		c_network = s->config->network.ipv6;
		c_netmask = s->config->network.ipv6_netmask;
	}

	if (c_network && c_netmask) {
		ret =
		    inet_pton(AF_INET6, c_network, SA_IN6_P(&network));

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

		ret =
		    inet_pton(AF_INET6, c_netmask, SA_IN6_P(&mask));
	
		if (ret != 1) {
			mslog(s, NULL, LOG_ERR, "error reading mask: %s", c_netmask);
			return -1;
		}
		
		proc->ipv6 = calloc(1, sizeof(*proc->ipv6));
		if (proc->ipv6 == NULL)
			return ERR_MEM;

		/* mask the network */
		for (i=0;i<sizeof(struct in6_addr);i++)
			SA_IN6_U8_P(&network)[i] &= (SA_IN6_U8_P(&mask)[i]);
		((struct sockaddr_in6*)&network)->sin6_family = AF_INET6;
		((struct sockaddr_in6*)&network)->sin6_port = 0;

       		memcpy(&tmp, &network, sizeof(tmp));
        	((struct sockaddr_in6*)&tmp)->sin6_family = AF_INET6;
        	((struct sockaddr_in6*)&tmp)->sin6_port = AF_INET6;

        	((struct sockaddr_in6*)&rnd)->sin6_family = AF_INET6;
        	((struct sockaddr_in6*)&rnd)->sin6_port = AF_INET6;

		do {
			if (max_loops == 0) {
				mslog(s, NULL, LOG_ERR, "could not figure out a valid IPv6 IP.");
				ret = ERR_NO_IP;
				goto fail;
			}
			
			if (max_loops == MAX_IP_TRIES) {
				uint32_t t = hash_any(proc->username, strlen(proc->username), 0);
				memset(SA_IN6_U8_P(&rnd), 0, sizeof(struct in6_addr));
				memcpy(SA_IN6_U8_P(&rnd)+sizeof(struct in6_addr)-5, &t, 4);
			} else
				gnutls_rnd(GNUTLS_RND_NONCE, SA_IN6_U8_P(&rnd), sizeof(struct in6_addr));
			max_loops--;
			
			/* Mask the random number with the netmask */
        		for (i=0;i<sizeof(struct in6_addr);i++)
        			SA_IN6_U8_P(&rnd)[i] &= ~(SA_IN6_U8_P(&mask)[i]);

			SA_IN6_U8_P(&rnd)[sizeof(struct in6_addr)-1] &= 0xFE;

			/* Now add the network to the masked random number */
        		for (i=0;i<sizeof(struct in6_addr);i++)
        			SA_IN6_U8_P(&rnd)[i] |= (SA_IN6_U8_P(&network)[i]);
        			
 			/* check if it exists in the hash table */
			if (ip_lease_exists(s, &rnd, sizeof(struct sockaddr_in6)) != 0) {
				mslog(s, proc, LOG_DEBUG, "cannot assign local IP %s to '%s'; it is in use.", 
				      human_addr((void*)&rnd, sizeof(struct sockaddr_in6), buf, sizeof(buf)), 
				      proc->username);
				continue;
			}

        		proc->ipv6->lip_len = sizeof(struct sockaddr_in6);
        		memcpy(&proc->ipv6->lip, &rnd, proc->ipv6->lip_len);

        		/* RIP = LIP + 1 */
        		memcpy(&tmp, &proc->ipv6->lip, proc->ipv6->rip_len);

	        	bignum_add(SA_IN6_U8_P(&tmp), sizeof(struct in6_addr), 1);

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

        		proc->ipv6->rip_len = sizeof(struct sockaddr_in6);
        		memcpy(&proc->ipv6->rip, &tmp, proc->ipv6->rip_len);

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

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

			mslog(s, proc, LOG_DEBUG, "selected IP for '%s': %s", proc->username,
			      human_addr((void*)&proc->ipv6->lip, proc->ipv6->lip_len, buf, sizeof(buf)));

	        	if (icmp_ping6(s, (void*)&proc->ipv6->lip, (void*)&proc->ipv6->rip) == 0)
	        		break;
                } while(1);
	}

	return 0;
fail:
	free(proc->ipv6);
	proc->ipv6 = NULL;

	return ret;

}