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); }
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)); }
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); }