Пример #1
0
static int ip2addr(const char *ip, unsigned short port, ACL_SOCKADDR *saddr)
{
	memset(saddr, 0, sizeof(ACL_SOCKADDR));

	if (acl_valid_ipv4_hostaddr(ip, 0)) {
		saddr->sa.sa_family = AF_INET;
		saddr->in.sin_port  = htons(port);

		if (inet_pton(AF_INET, ip, &saddr->in.sin_addr) == 1) {
			return 1;
		}
		acl_msg_error("%s(%d): invalid ip=%s",
			__FUNCTION__, __LINE__, ip);
	}
#ifdef AF_INET6
	else if (acl_valid_ipv6_hostaddr(ip, 0)) {
		saddr->sa.sa_family  = AF_INET6;
		saddr->in6.sin6_port = htons(port);
		if (inet_pton(AF_INET6, ip, &saddr->in6.sin6_addr) == 1) {
			return 1;
		}
		acl_msg_error("%s(%d): invalid ip=%s",
			__FUNCTION__, __LINE__, ip);
	}
#endif

	return 0;
}
Пример #2
0
size_t acl_sane_pton(const char *src, struct sockaddr *dst)
{
	int af;

	if (acl_valid_ipv4_hostaddr(src, 0)) {
		af = AF_INET;
	} else if (acl_valid_ipv6_hostaddr(src, 0)) {
		af = AF_INET6;
	} else if (acl_valid_unix(src)) {
		af = AF_UNIX;
	} else {
		return 0;
	}

	return acl_inet_pton(af, src, dst);
}
Пример #3
0
int acl_valid_hostaddr(const char *addr, int gripe)
{
	const char *myname = "acl_valid_hostaddr";

	/*
	 * Trivial cases first.
	 */
	if (*addr == 0) {
		if (gripe)
			acl_msg_warn("%s: empty address", myname);
		return (0);
	}

	/*
	 * Protocol-dependent processing next.
	 */
	if (strchr(addr, ':') != 0)
		return (acl_valid_ipv6_hostaddr(addr, gripe));
	else
		return (acl_valid_ipv4_hostaddr(addr, gripe));
}
Пример #4
0
int acl_valid_ipv6_hostaddr(const char *addr, int gripe)
{
	const char *myname = "acl_valid_ipv6_hostaddr";
	int     null_field = 0;
	int     field = 0;
	const unsigned char *cp = (const unsigned char *) addr;
	int     len = 0;

	/*
	 * FIX 200501 The IPv6 patch validated syntax with getaddrinfo(), but I
	 * am not confident that everyone's system library routines are robust
	 * enough, like buffer overflow free. Remember, the valid_hostmumble()
	 * routines are meant to protect Postfix against malformed information
	 * in data received from the network.
	 * 
	 * We require eight-field hex addresses of the form 0:1:2:3:4:5:6:7,
	 * 0:1:2:3:4:5:6a.6b.7c.7d, or some :: compressed version of the same.
	 * 
	 * Note: the character position is advanced inside the loop. I have added
	 * comments to show why we can't get stuck.
	 */
	for (;;) {
		switch (*cp) {
		case 0:
			/* Terminate the loop. */
			if (field < 2) {
				if (gripe)
					acl_msg_warn("%s: too few `:' in IPv6"
						" address: %.100s",
						myname, addr);
				return (0);
			} else if (len == 0 && null_field != field - 1) {
				if (gripe)
					acl_msg_warn("%s: bad null last field"
						" in IPv6 address: %.100s",
						myname, addr);
				return (0);
			} else
				return (1);
		case '.':
			/* Terminate the loop. */
			if (field < 2 || field > 6) {
				if (gripe)
					acl_msg_warn("%s: malformed IPv4-in-IPv6"
						" address: %.100s",
						myname, addr);
				return (0);
			} 
			/* NOT: acl_valid_hostaddr(). Avoid recursion. */
			return (acl_valid_ipv4_hostaddr((const char *) cp - len, gripe));
		case ':':
		/* advance by exactly 1 character position or terminate. */
			if (field == 0 && len == 0 && ACL_ISALNUM(cp[1])) {
				if (gripe)
					acl_msg_warn("%s: bad null first field"
						" in IPv6 address: %.100s",
						myname, addr);
				return (0);
			}
			field++;
			if (field > 7) {
				if (gripe)
					acl_msg_warn("%s: too many `:' in"
						" IPv6 address: %.100s",
						myname, addr);
				return (0);
			}
			cp++;
			len = 0;
			if (*cp == ':') {
				if (null_field > 0) {
					if (gripe)
						acl_msg_warn("%s: too many `::'"
							" in IPv6 address: %.100s",
							myname, addr);
					return (0);
				}
				null_field = field;
			} 
			break;
		default:
			/* Advance by at least 1 character position or terminate. */
			len = (int) strspn((const char *) cp, "0123456789abcdefABCDEF");
			if (len /* - strspn((char *) cp, "0") */ > 4) {
				if (gripe)
					acl_msg_warn("%s: malformed IPv6 address: %.100s",
							myname, addr);
				return (0);
			}
			if (len <= 0) {
				if (gripe)
					acl_msg_warn("%s: invalid character"
						" %d(decimal) in IPv6 address: %.100s",
						myname, *cp, addr);
				return (0);
			}
			cp += len;
			break;
		}
	}
}
Пример #5
0
int acl_is_ipv4(const char *ip)
{       
	return acl_valid_ipv4_hostaddr(ip, 0);
}