smtpd_sasl_proto.c [plain text]
#include <sys_defs.h>
#include <string.h>
#include <msg.h>
#include <mymalloc.h>
#include <mail_params.h>
#include <mail_proto.h>
#include <mail_error.h>
#include "smtpd.h"
#include "smtpd_token.h"
#include "smtpd_chat.h"
#include "smtpd_sasl_proto.h"
#include "smtpd_sasl_glue.h"
#ifdef USE_SASL_AUTH
int smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
{
char *auth_mechanism;
char *initial_response;
char *err;
if (var_helo_required && state->helo_name == 0) {
state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "503 Error: send HELO/EHLO first");
return (-1);
}
if (SMTPD_STAND_ALONE(state) || !var_smtpd_sasl_enable) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "503 Error: authentication not enabled");
return (-1);
}
#ifdef HAS_SSL
if (state->tls_auth_only && !state->tls_active) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "538 Encryption required for requested authentication mechanism");
return (-1);
}
#endif
if (state->sasl_username) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "503 Error: already authenticated");
return (-1);
}
if (argc < 2 || argc > 3) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 Syntax: AUTH mechanism");
return (-1);
}
auth_mechanism = argv[1].strval;
initial_response = (argc == 3 ? argv[2].strval : 0);
if ( var_smtpd_use_pw_server )
{
err = smtpd_pw_server_authenticate( state, auth_mechanism, initial_response );
}
else
{
err = smtpd_sasl_authenticate(state, auth_mechanism, initial_response);
}
if (err != 0) {
msg_warn("%s[%s]: SASL %s authentication failed",
state->name, state->addr, auth_mechanism);
smtpd_chat_reply(state, "%s", err);
return (-1);
}
smtpd_chat_reply(state, "235 Authentication successful");
return (0);
}
void smtpd_sasl_auth_reset(SMTPD_STATE *state)
{
smtpd_sasl_logout(state);
}
char *smtpd_sasl_mail_opt(SMTPD_STATE *state, const char *addr)
{
if (!var_smtpd_sasl_enable) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
return ("503 Error: authentication disabled");
}
#if 0
if (state->sasl_username == 0) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
return ("503 Error: send AUTH command first");
}
#endif
if (state->sasl_sender != 0) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
return ("503 Error: multiple AUTH= options");
}
if (strcmp(addr, "<>") != 0)
state->sasl_sender = mystrdup(addr);
return (0);
}
void smtpd_sasl_mail_log(SMTPD_STATE *state)
{
#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
msg_info("%s: client=%s[%s]%s%s%s%s%s%s",
state->queue_id, state->name, state->addr,
IFELSE(state->sasl_method, ", sasl_method=", ""),
IFELSE(state->sasl_method, state->sasl_method, ""),
IFELSE(state->sasl_username, ", sasl_username=", ""),
IFELSE(state->sasl_username, state->sasl_username, ""),
IFELSE(state->sasl_sender, ", sasl_sender=", ""),
IFELSE(state->sasl_sender, state->sasl_sender, ""));
}
void smtpd_sasl_mail_reset(SMTPD_STATE *state)
{
if (state->sasl_sender) {
myfree(state->sasl_sender);
state->sasl_sender = 0;
}
}
int permit_sasl_auth(SMTPD_STATE *state, int ifyes, int ifnot)
{
if (state->sasl_method && strcasecmp(state->sasl_method, "anonymous"))
return (ifyes);
return (ifnot);
}
#endif