예제 #1
0
void    smtpd_peer_init(SMTPD_STATE *state)
{

    /*
     * Initialize.
     */
    if (proto_info == 0)
	proto_info = inet_proto_info();

    /*
     * Prepare for partial initialization after error.
     */
    memset((void *) &(state->sockaddr), 0, sizeof(state->sockaddr));
    state->sockaddr_len = 0;
    state->name = 0;
    state->reverse_name = 0;
    state->addr = 0;
    state->namaddr = 0;
    state->rfc_addr = 0;
    state->port = 0;
    state->dest_addr = 0;
    state->dest_port = 0;

    /*
     * Determine the remote SMTP client address and port.
     * 
     * XXX In stand-alone mode, don't assume that the peer will be a local
     * process. That could introduce a gaping hole when the SMTP daemon is
     * hooked up to the network via inetd or some other super-server.
     */
    if (vstream_context(state->client) != 0) {
	smtpd_peer_from_pass_attr(state);
	if (*var_smtpd_uproxy_proto != 0)
	    msg_warn("ignoring non-empty %s setting behind postscreen",
		     VAR_SMTPD_UPROXY_PROTO);
    } else if (SMTPD_STAND_ALONE(state) || *var_smtpd_uproxy_proto == 0) {
	smtpd_peer_from_default(state);
    } else {
	smtpd_peer_from_proxy(state);
    }

    /*
     * Determine the remote SMTP client hostname. Note: some of the handlers
     * above provide surrogate endpoint information in case of error. In that
     * case, leave the surrogate information alone.
     */
    if (state->name == 0)
	smtpd_peer_sockaddr_to_hostname(state);

    /*
     * Do the name[addr]:port formatting for pretty reports.
     */
    state->namaddr = SMTPD_BUILD_NAMADDRPORT(state->name, state->addr,
					     state->port);
}
예제 #2
0
int     smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
{
    char   *auth_mechanism;
    char   *initial_response;
    const char *err;

    if (var_helo_required && state->helo_name == 0) {
	state->error_mask |= MAIL_ERROR_POLICY;
	smtpd_chat_reply(state, "503 5.5.1 Error: send HELO/EHLO first");
	return (-1);
    }
    if (SMTPD_STAND_ALONE(state) || !smtpd_sasl_is_active(state)
	|| (state->ehlo_discard_mask & EHLO_MASK_AUTH)) {
	state->error_mask |= MAIL_ERROR_PROTOCOL;
	smtpd_chat_reply(state, "503 5.5.1 Error: authentication not enabled");
	return (-1);
    }
#define IN_MAIL_TRANSACTION(state) ((state)->sender != 0)
    if (IN_MAIL_TRANSACTION(state)) {
	state->error_mask |= MAIL_ERROR_PROTOCOL;
	smtpd_chat_reply(state, "503 5.5.1 Error: MAIL transaction in progress");
	return (-1);
    }
    if (smtpd_milters != 0 && (err = milter_other_event(smtpd_milters)) != 0) {
	if (err[0] == '5') {
	    state->error_mask |= MAIL_ERROR_POLICY;
	    smtpd_chat_reply(state, "%s", err);
	    return (-1);
	}
	/* Sendmail compatibility: map 4xx into 454. */
	else if (err[0] == '4') {
	    state->error_mask |= MAIL_ERROR_POLICY;
	    smtpd_chat_reply(state, "454 4.3.0 Try again later");
	    return (-1);
	}
    }
#ifdef USE_TLS
    if (var_smtpd_tls_auth_only && !state->tls_context) {
	state->error_mask |= MAIL_ERROR_PROTOCOL;
	/* RFC 4954, Section 4. */
	smtpd_chat_reply(state, "504 5.5.4 Encryption required for requested authentication mechanism");
	return (-1);
    }
#endif
    if (state->sasl_username) {
	state->error_mask |= MAIL_ERROR_PROTOCOL;
	smtpd_chat_reply(state, "503 5.5.1 Error: already authenticated");
	return (-1);
    }
    if (argc < 2 || argc > 3) {
	state->error_mask |= MAIL_ERROR_PROTOCOL;
	smtpd_chat_reply(state, "501 5.5.4 Syntax: AUTH mechanism");
	return (-1);
    }

    /* Don't reuse the SASL handle after authentication failure. */
#ifndef SMTPD_FLAG_AUTH_USED
#define SMTPD_FLAG_AUTH_USED	(1<<15)
#endif
#ifndef XSASL_TYPE_CYRUS 
#define XSASL_TYPE_CYRUS	"cyrus"
#endif
    if (state->flags & SMTPD_FLAG_AUTH_USED) {
	smtpd_sasl_deactivate(state);
#ifdef USE_TLS
	if (state->tls_context != 0)
	    smtpd_sasl_activate(state, VAR_SMTPD_SASL_TLS_OPTS,
				var_smtpd_sasl_tls_opts);
	else
#endif
	    smtpd_sasl_activate(state, VAR_SMTPD_SASL_OPTS,
				var_smtpd_sasl_opts);
    } else if (strcmp(var_smtpd_sasl_type, XSASL_TYPE_CYRUS) == 0) {
	state->flags |= SMTPD_FLAG_AUTH_USED;
    }

    /*
     * All authentication failures shall be logged. The 5xx reply code from
     * the SASL authentication routine triggers tar-pit delays, which help to
     * slow down password guessing attacks.
     */
    auth_mechanism = argv[1].strval;
    initial_response = (argc == 3 ? argv[2].strval : 0);
    return (smtpd_sasl_authenticate(state, auth_mechanism, initial_response));
}
예제 #3
0
void    smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream)
{

    /*
     * Initialize the state information for this connection, and fill in the
     * connection-specific fields.
     */
    state->err = CLEANUP_STAT_OK;
    state->client = stream;
    state->buffer = vstring_alloc(100);
    state->error_count = 0;
    state->error_mask = 0;
    state->notify_mask = name_mask(VAR_NOTIFY_CLASSES, mail_error_masks,
				   var_notify_classes);
    state->helo_name = 0;
    state->queue_id = 0;
    state->cleanup = 0;
    state->dest = 0;
    state->rcpt_count = 0;
    state->access_denied = 0;
    state->history = 0;
    state->reason = 0;
    state->sender = 0;
    state->verp_delims = 0;
    state->recipient = 0;
    state->etrn_name = 0;
    state->protocol = mystrdup(MAIL_PROTO_SMTP);
    state->where = SMTPD_AFTER_CONNECT;
    state->recursion = 0;
    state->msg_size = 0;
    state->junk_cmds = 0;
    state->rcpt_overshoot = 0;
    state->defer_if_permit_client = 0;
    state->defer_if_permit_helo = 0;
    state->defer_if_permit_sender = 0;
    state->defer_if_reject.reason = 0;
    state->defer_if_permit.reason = 0;
    state->discard = 0;
    state->expand_buf = 0;
    state->prepend = 0;
    state->proxy = 0;
    state->proxy_buffer = 0;
    state->proxy_mail = 0;
    state->proxy_xforward_features = 0;
    state->saved_filter = 0;
    state->saved_redirect = 0;
    state->saved_flags = 0;
    state->instance = vstring_alloc(10);
    state->seqno = 0;

#ifdef USE_SASL_AUTH
    if (SMTPD_STAND_ALONE(state))
	var_smtpd_sasl_enable = 0;
    if (var_smtpd_sasl_enable)
	smtpd_sasl_connect(state, VAR_SMTPD_SASL_OPTS, var_smtpd_sasl_opts);
#endif

    state->break_out=0;
    state->break_code=0;
    state->break_msg[0]='\0';
    state->aclip_passflag=0;
    state->rc_ip_check=0;
    state->rc_from_check=0;
    state->rc_auth_check=0;
    state->wrcpt_count=0;
    state->sender_idx=0;
    state->sender_check = 0;
    state->reciver_check = 0;
    state->username = vstring_alloc(128);
    state->mhost = vstring_alloc(128);


    /*
     * Initialize peer information.
     */
    smtpd_peer_init(state);

    /*
     * Initialize xforward information.
     */
    smtpd_xforward_init(state);

    /*
     * Initialize the conversation history.
     */
    smtpd_chat_reset(state);
}