smtp-server-command.c revision e69ac57b1a97e56011e988564985728be31bfb2a
/* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "llist.h"
#include "array.h"
#include "smtp-reply.h"
#include "smtp-server-private.h"
/*
* Command registry
*/
{
struct smtp_server_command_reg cmd;
}
const char *name)
{
const struct smtp_server_command_reg *cmd;
unsigned int i, count;
for (i = 0; i < count; i++) {
return;
}
}
}
static int
const struct smtp_server_command_reg *c2)
{
}
static int
smtp_server_command_bsearch(const char *name,
const struct smtp_server_command_reg *cmd)
{
}
static struct smtp_server_command_reg *
{
if (server->commands_unsorted) {
}
}
{
case SMTP_PROTOCOL_SMTP:
"EHLO", smtp_server_cmd_ehlo,
"HELO", smtp_server_cmd_helo,
break;
case SMTP_PROTOCOL_LMTP:
"LHLO", smtp_server_cmd_ehlo,
break;
}
"AUTH", smtp_server_cmd_auth,
"STARTTLS", smtp_server_cmd_starttls,
"MAIL", smtp_server_cmd_mail, 0);
"RCPT", smtp_server_cmd_rcpt, 0);
"DATA", smtp_server_cmd_data, 0);
"BDAT", smtp_server_cmd_bdat, 0);
"RSET", smtp_server_cmd_rset,
"VRFY", smtp_server_cmd_vrfy, 0);
"NOOP", smtp_server_cmd_noop,
"QUIT", smtp_server_cmd_quit,
"XCLIENT", smtp_server_cmd_xclient,
}
/*
* Logging
*/
const char *format, ...)
{
i_debug("%s-server: conn %s: command %s: %s",
}
}
/*
*
*/
struct smtp_server_command *
{
struct smtp_server_command *cmd;
return cmd;
}
struct smtp_server_command *
{
const struct smtp_server_command_reg *cmd_reg;
struct smtp_server_command *cmd;
/* RFC 5321, Section 4.2.4: Reply Code 502
Questions have been raised as to when reply code 502 (Command
not implemented) SHOULD be returned in preference to other
codes. 502 SHOULD be used when the command is actually
recognized by the SMTP server, but not implemented. If the
command is not recognized, code 500 SHOULD be returned.
*/
500, "5.5.1", "Unknown command");
/* RFC 3207, Section 4:
A SMTP server that is not publicly referenced may choose to
require that the client perform a TLS negotiation before
accepting any commands. In this case, the server SHOULD
return the reply code:
530 Must issue a STARTTLS command first
to every command other than NOOP, EHLO, STARTTLS, or QUIT. If
the client and server are using the ENHANCEDSTATUSCODES ESMTP
extension [RFC2034], the status code to be returned SHOULD be
5.7.0.
*/
530, "5.7.0", "TLS required.");
/* RFC 4954, Section 6: Status Codes
530 5.7.0 Authentication required
This response SHOULD be returned by any command other than
AUTH, EHLO, HELO, NOOP, RSET, or QUIT when server policy
requires authentication in order to perform the requested
action and authentication is not currently in force.
*/
530, "5.7.0", "Authentication required.");
} else {
if (!smtp_server_command_unref(&tmp_cmd))
}
return cmd;
}
{
}
{
return TRUE;
}
/* execute hooks */
return FALSE;
}
{
/* preemptively remove command from queue (references may still exist)
*/
}
}
unsigned int count)
{
}
{
}
{
return;
/* execute private hook_next */
}
/* execute public hook_next */
}
}
static void
{
return;
/* execute private hook_replied */
}
/* execute public hook_replied */
}
}
}
{
return;
/* execute private hook_completed */
}
/* execute public hook_completed */
}
}
}
{
unsigned int i, submitted;
submitted = 0;
for (i = 0; i < cmd->replies_expected; i++) {
const struct smtp_server_reply *reply =
submitted++;
case 500:
case 501:
case 503:
break;
}
}
/* limit number of consecutive bad commands */
if (is_bad)
conn->bad_counter++;
conn->bad_counter = 0;
/* submit reply */
if (!smtp_server_command_is_complete(cmd)) {
"Not ready to reply");
break;
}
break;
break;
default:
i_unreached();
}
if (!smtp_server_connection_unref(&conn))
return;
"4.7.0", "Too many invalid commands.");
return;
}
}
{
unsigned int i;
return FALSE;
for (i = 0; i < cmd->replies_expected; i++) {
const struct smtp_server_reply *reply =
return FALSE;
}
return TRUE;
}
struct smtp_server_reply *
unsigned int idx)
{
struct smtp_server_reply *reply;
return NULL;
return NULL;
return reply;
}
unsigned int status)
{
struct smtp_server_reply *reply;
}
{
unsigned int i;
return FALSE;
for (i = 0; i < cmd->replies_expected; i++) {
const struct smtp_server_reply *reply =
return FALSE;
}
return success;
}
{
struct smtp_server_reply *reply;
"Server closed the connection: %s",
} else {
"Client has quit the connection");
}
return;
} else if (cmd->input_locked) {
if (cmd->input_captured)
}
}
const char *fmt, ...)
{
unsigned int i;
} else for (i = 0; i < cmd->replies_expected; i++) {
const struct smtp_server_reply *reply =
}
/* send the same reply for all */
if (!sent) {
}
}
}
{
}
{
}
{
}