56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#ifndef SMTP_SERVER_PRIVATE_H
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#define SMTP_SERVER_PRIVATE_H
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "connection.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "smtp-server.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#define SMTP_SERVER_COMMAND_POOL_MAX (8 * 1024)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#define SMTP_SERVER_DEFAULT_MAX_COMMAND_LINE (4 * 1024)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#define SMTP_SERVER_DEFAULT_MAX_BAD_COMMANDS 10
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#define SMTP_SERVER_DEFAULT_CAPABILITIES \
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch (SMTP_CAPABILITY_SIZE | SMTP_CAPABILITY_ENHANCEDSTATUSCODES | \
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch SMTP_CAPABILITY_8BITMIME | SMTP_CAPABILITY_CHUNKING)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_reply;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_command;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_connection;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan BoschARRAY_DEFINE_TYPE(smtp_server_reply, struct smtp_server_reply);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschenum smtp_server_command_state {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* New command; callback to command start handler executing. */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch SMTP_SERVER_COMMAND_STATE_NEW = 0,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* This command is being processed; command data is fully read, but no
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch reply is yet submitted */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch SMTP_SERVER_COMMAND_STATE_PROCESSING,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* A reply is submitted for this command. If not all command data was
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch read by the handler, it is first skipped on the input. If this is a
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch multi-reply command (LMTP->DATA), not all replies may be submitted
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch yet. */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* Request is ready for sending reply; a reply is submitted and the
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch command payload is fully read. If this is a multi-reply command
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch (LMTP->DATA), not all replies may be submitted yet. In that case the
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch command state goes back to PROCESSING once the all submitted replies
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch are sent. */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* The reply for the command is sent */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch SMTP_SERVER_COMMAND_STATE_FINISHED,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* Request is aborted; still lingering due to references */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch SMTP_SERVER_COMMAND_STATE_ABORTED
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch};
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Boschstruct smtp_server_reply_content {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int status;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *status_prefix;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch string_t *text;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch size_t last_line;
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Bosch};
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Bosch
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Boschstruct smtp_server_reply {
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Bosch struct smtp_server_command *command;
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Bosch unsigned int index;
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Bosch
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Bosch /* replies may share content */
1d4c4128808d04cf4b8396ce04ce524da9194782Stephan Bosch struct smtp_server_reply_content *content;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool submitted:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool sent:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch};
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_command_reg {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *name;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch enum smtp_server_command_flags flags;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_cmd_start_func_t *func;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch};
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_command {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_cmd_ctx context;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct smtp_server_command_reg *reg;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int refcount;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch enum smtp_server_command_state state;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_command *prev, *next;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch ARRAY_TYPE(smtp_server_reply) replies;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int replies_expected;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int replies_submitted;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* private hooks */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* next: command is next to reply but has not submittted all replies yet */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_cmd_func_t *hook_next;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* replied: command has submitted all replies */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_cmd_func_t *hook_replied;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* completed: server is about to send last replies for this command */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_cmd_func_t *hook_completed;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* destroy: command is about to be destroyed */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_cmd_func_t *hook_destroy;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* private context data */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch void *data;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool input_locked:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool input_captured:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool reply_early:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch};
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_state_data {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch enum smtp_server_state state;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch time_t timestamp;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int pending_mail_cmds, pending_rcpt_cmds;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_transaction *trans;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct istream *data_input, *data_chain_input;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct istream_chain *data_chain;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int data_chunks;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool data_failed:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch};
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_connection {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct connection conn;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server *server;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch pool_t pool;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int refcount;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_settings set;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct smtp_server_callbacks *callbacks;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch void *context;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int socket_family;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct ip_addr remote_ip;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch in_port_t remote_port;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch pid_t remote_pid;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch uid_t remote_uid;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch enum smtp_proxy_protocol proxy_proto;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int proxy_ttl_plus_1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int proxy_timeout_secs;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_helo_data helo, *pending_helo;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch char *helo_domain, *helo_login, *username;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int id;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct timeout *to_idle;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct istream *raw_input;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct ostream *raw_output;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct ssl_iostream *ssl_iostream;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_command_parser *smtp_parser;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_command *command_queue_head, *command_queue_tail;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int command_queue_count;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int bad_counter;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch char *disconnect_reason;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_state_data state;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_stats stats;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
f091dd12d19df22e5403855f93dedee437bd7d87Stephan Bosch bool started:1;
912e87d5be9dd8895e8cb7c6cb51d8a752edbe8cStephan Bosch bool halted:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool ssl_start:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool ssl_secured:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool authenticated:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool created_from_streams:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool corked:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool disconnected:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool closing:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool closed:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool input_broken:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool input_locked:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool handling_input:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool rawlog_checked:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool rawlog_enabled:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch};
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch pool_t pool;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_settings set;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct ioloop *ioloop;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch ARRAY(struct smtp_server_command_reg) commands_reg;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct connection_list *conn_list;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch bool commands_unsorted:1;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch};
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic inline const char *
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_command_label(struct smtp_server_command *cmd)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch{
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (cmd->context.name == NULL)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch return "[INVALID]";
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch return cmd->context.name;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch}
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic inline const char *
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_connection_label(struct smtp_server_connection *conn)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch{
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch return conn->conn.name;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch}
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschbool smtp_server_connection_pending_command_data(
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch/*
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch * Reply
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_reply_free(struct smtp_server_command *cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
2f07c9a5d854404dad3380c5968b409e03fb4108Stephan Boschint smtp_server_reply_send(struct smtp_server_reply *resp);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschconst char *smtp_server_reply_get_one_line(struct smtp_server_reply *reply);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch/*
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch * Command
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_commands_init(struct smtp_server *server);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_debug(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *format, ...) ATTR_FORMAT(2, 3);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_command *
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_command_alloc(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_command *
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_command_new(struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *name, const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_ref(struct smtp_server_command *cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschbool smtp_server_command_unref(struct smtp_server_command **_cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_abort(struct smtp_server_command **_cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_submit_reply(struct smtp_server_command *cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschint smtp_server_connection_flush(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_ready_to_reply(struct smtp_server_command *cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_next_to_reply(struct smtp_server_command *cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_completed(struct smtp_server_command *cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_command_finished(struct smtp_server_command *cmd);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic inline bool
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_command_is_complete(struct smtp_server_command *cmd)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch{
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn = cmd->context.conn;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch return (conn->input_broken || (cmd->next != NULL) || cmd->reply_early ||
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch !smtp_server_connection_pending_command_data(conn));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch}
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_ehlo(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_helo(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_xclient(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_starttls(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_auth(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_mail(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_data(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_bdat(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_rset(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_noop(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_vrfy(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_quit(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch/*
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch * Connection
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschtypedef void smtp_server_input_callback_t(void *context);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_debug(struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *format, ...) ATTR_FORMAT(2, 3);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_error(struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *format, ...) ATTR_FORMAT(2, 3);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct connection_list *smtp_server_connection_list_init(void);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_switch_ioloop(struct smtp_server_connection *conn);
1e3de3981ee5b13f59d84c6f9cd3722ae3084852Stephan Bosch
1e3de3981ee5b13f59d84c6f9cd3722ae3084852Stephan Boschvoid smtp_server_connection_handle_output_error(
1e3de3981ee5b13f59d84c6f9cd3722ae3084852Stephan Bosch struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_trigger_output(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschbool smtp_server_connection_pending_payload(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_cork(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_uncork(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_input_halt(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_input_resume(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_input_capture(
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_input_callback_t *callback, void *context);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#define smtp_server_connection_input_capture(conn, callback, context) \
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_connection_input_capture(conn + \
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch (smtp_server_input_callback_t *)callback, context)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_timeout_stop(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_timeout_start(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_timeout_reset(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_send_line(struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *fmt, ...) ATTR_FORMAT(2, 3);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_reply_immediate(
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn, unsigned int status,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *fmt, ...) ATTR_FORMAT(3, 4);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_reset_state(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_set_state(struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch enum smtp_server_state state);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschint smtp_server_connection_ssl_init(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_clear(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_transaction *
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_connection_get_transaction(struct smtp_server_connection *conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_connection_set_proxy_data(struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct smtp_proxy_data *proxy_data);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch/*
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch * Transaction
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_transaction *
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_transaction_create(struct smtp_server_connection *conn,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct smtp_address *mail_from,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct smtp_params_mail *params,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct timeval *timestamp);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_transaction_free(struct smtp_server_transaction **_trans);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server_recipient *
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschsmtp_server_transaction_add_rcpt(struct smtp_server_transaction *trans,
5d5ad796fc34170333bb52c05614425a0dd7e182Stephan Bosch const struct smtp_address *rcpt_to,
5d5ad796fc34170333bb52c05614425a0dd7e182Stephan Bosch const struct smtp_params_rcpt *params);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschbool smtp_server_transaction_has_rcpt(struct smtp_server_transaction *trans);
6d76b99eb61df1cbe13cf76d0aac81507cbd1d21Stephan Boschunsigned int
6d76b99eb61df1cbe13cf76d0aac81507cbd1d21Stephan Boschsmtp_server_transaction_rcpt_count(struct smtp_server_transaction *trans);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#endif