Exemple #1
0
static void smtpd_peer_from_pass_attr(SMTPD_STATE *state)
{
    HTABLE *attr = (HTABLE *) vstream_context(state->client);
    const char *cp;

    /*
     * Extract the client endpoint information from the attribute hash.
     */
    if ((cp = htable_find(attr, MAIL_ATTR_ACT_CLIENT_ADDR)) == 0)
	msg_fatal("missing client address from proxy");
    if (strrchr(cp, ':') != 0) {
	if (valid_ipv6_hostaddr(cp, DO_GRIPE) == 0)
	    msg_fatal("bad IPv6 client address syntax from proxy: %s", cp);
	state->addr = mystrdup(cp);
	state->rfc_addr = concatenate(IPV6_COL, cp, (char *) 0);
	state->addr_family = AF_INET6;
    } else {
	if (valid_ipv4_hostaddr(cp, DO_GRIPE) == 0)
	    msg_fatal("bad IPv4 client address syntax from proxy: %s", cp);
	state->addr = mystrdup(cp);
	state->rfc_addr = mystrdup(cp);
	state->addr_family = AF_INET;
    }
    if ((cp = htable_find(attr, MAIL_ATTR_ACT_CLIENT_PORT)) == 0)
	msg_fatal("missing client port from proxy");
    if (valid_hostport(cp, DO_GRIPE) == 0)
	msg_fatal("bad TCP client port number syntax from proxy: %s", cp);
    state->port = mystrdup(cp);

    /*
     * The Dovecot authentication server needs the server IP address.
     */
    if ((cp = htable_find(attr, MAIL_ATTR_ACT_SERVER_ADDR)) == 0)
	msg_fatal("missing server address from proxy");
    if (valid_hostaddr(cp, DO_GRIPE) == 0)
	msg_fatal("bad IPv6 server address syntax from proxy: %s", cp);
    state->dest_addr = mystrdup(cp);

    if ((cp = htable_find(attr, MAIL_ATTR_ACT_SERVER_PORT)) == 0)
	msg_fatal("missing server port from proxy");
    if (valid_hostport(cp, DO_GRIPE) == 0)
	msg_fatal("bad TCP server port number syntax from proxy: %s", cp);
    state->dest_port = mystrdup(cp);

    /*
     * Convert the client address from string to binary form.
     */
    smtpd_peer_hostaddr_to_sockaddr(state);
}
Exemple #2
0
int     valid_hostaddr(const char *addr, int gripe)
{
    const char *myname = "valid_hostaddr";

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

    /*
     * Protocol-dependent processing next.
     */
    if (strchr(addr, ':') != 0)
	return (valid_ipv6_hostaddr(addr, gripe));
    else
	return (valid_ipv4_hostaddr(addr, gripe));
}
Exemple #3
0
int     valid_hostname(const char *name, int gripe)
{
    const char *myname = "valid_hostname";
    const char *cp;
    int     label_length = 0;
    int     label_count = 0;
    int     non_numeric = 0;
    int     ch;

    /*
     * Trivial cases first.
     */
    if (*name == 0) {
	if (gripe)
	    msg_warn("%s: empty hostname", myname);
	return (0);
    }

    /*
     * Find bad characters or label lengths. Find adjacent delimiters.
     */
    for (cp = name; (ch = *(unsigned char *) cp) != 0; cp++) {
	if (ISALNUM(ch) || ch == '_') {		/* grr.. */
	    if (label_length == 0)
		label_count++;
	    label_length++;
	    if (label_length > VALID_LABEL_LEN) {
		if (gripe)
		    msg_warn("%s: hostname label too long: %.100s", myname, name);
		return (0);
	    }
	    if (!ISDIGIT(ch))
		non_numeric = 1;
	} else if (ch == '.') {
	    if (label_length == 0 || cp[1] == 0) {
		if (gripe)
		    msg_warn("%s: misplaced delimiter: %.100s", myname, name);
		return (0);
	    }
	    label_length = 0;
	} else if (ch == '-') {
	    non_numeric = 1;
	    label_length++;
	    if (label_length == 1 || cp[1] == 0 || cp[1] == '.') {
		if (gripe)
		    msg_warn("%s: misplaced hyphen: %.100s", myname, name);
		return (0);
	    }
	}
#ifdef SLOPPY_VALID_HOSTNAME
	else if (ch == ':' && valid_ipv6_hostaddr(name, DONT_GRIPE)) {
	    non_numeric = 0;
	    break;
	}
#endif
	else {
	    if (gripe)
		msg_warn("%s: invalid character %d(decimal): %.100s",
			 myname, ch, name);
	    return (0);
	}
    }

    if (non_numeric == 0) {
	if (gripe)
	    msg_warn("%s: numeric hostname: %.100s", myname, name);
#ifndef SLOPPY_VALID_HOSTNAME
	return (0);
#endif
    }
    if (cp - name > VALID_HOSTNAME_LEN) {
	if (gripe)
	    msg_warn("%s: bad length %d for %.100s...",
		     myname, (int) (cp - name), name);
	return (0);
    }
    return (1);
}