smtp-server.h revision 912e87d5be9dd8895e8cb7c6cb51d8a752edbe8c
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen#ifndef SMTP_SERVER_H
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen#define SMTP_SERVER_H
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen#include "smtp-common.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "smtp-command.h"
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen#include "smtp-params.h"
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_address;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_reply;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_command;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainenstruct smtp_server_helo_data;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_esmtp_param;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_cmd_ehlo;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_cmd_mail;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_cmd_ctx;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_command;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_reply;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen/*
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen * Types
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenenum smtp_server_state {
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen SMTP_SERVER_STATE_GREETING = 0,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen SMTP_SERVER_STATE_XCLIENT,
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen SMTP_SERVER_STATE_HELO,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen SMTP_SERVER_STATE_STARTTLS,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen SMTP_SERVER_STATE_AUTH,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen SMTP_SERVER_STATE_READY,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen SMTP_SERVER_STATE_MAIL_FROM,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen SMTP_SERVER_STATE_RCPT_TO,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen SMTP_SERVER_STATE_DATA,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen};
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenextern const char *const smtp_server_state_names[];
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenstruct smtp_server_helo_data {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen const char *domain;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen bool domain_valid:1; /* valid domain/literal specified */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool old_smtp:1; /* client sent HELO rather than EHLO */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen};
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen/*
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen * Transaction
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_recipient {
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_address *path;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_params_rcpt params;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen void *context;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen};
48566ca412a7cf3b42512fd0ec112744778e5da0Timo SirainenARRAY_DEFINE_TYPE(smtp_server_recipient, struct smtp_server_recipient *);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_transaction {
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen pool_t pool;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server_connection *conn;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *id;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct timeval timestamp;
c649139f889c02154fc9a153728b81619edb5663Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_address *mail_from;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_params_mail params;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch ARRAY_TYPE(smtp_server_recipient) rcpt_to;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch void *context;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch};
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenvoid smtp_server_transaction_fail_data(
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct smtp_server_transaction *trans,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct smtp_server_cmd_ctx *data_cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen unsigned int status, const char *enh_code,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen const char *fmt, va_list args) ATTR_FORMAT(5, 0);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_transaction_write_trace_record(string_t *str,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_transaction *trans);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
df1713bd29d29a3e3f3ebfdf05f929525825a7d3Timo Sirainen/*
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen * Callbacks
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_cmd_helo {
f0339f522dc9c8e2e8a29ef9a3f937c431c6bd1bTimo Sirainen struct smtp_server_helo_data helo;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen bool first:1; /* this is the first */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen bool changed:1; /* this EHLO/HELO/LHLO is the first or
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen different from a previous one */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen};
df1713bd29d29a3e3f3ebfdf05f929525825a7d3Timo Sirainen
df1713bd29d29a3e3f3ebfdf05f929525825a7d3Timo Sirainenstruct smtp_server_cmd_mail {
df1713bd29d29a3e3f3ebfdf05f929525825a7d3Timo Sirainen struct smtp_address *path;
cd2fc7dd28c3a2e3f82e8480eaf3ba7c4abc3614Timo Sirainen struct smtp_params_mail params;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct timeval timestamp;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen};
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_cmd_rcpt {
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_address *path;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_params_rcpt params;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* called once the recipient is definitively added to the transaction */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch void (*hook_finished)(struct smtp_server_cmd_ctx *cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server_transaction *trans,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server_recipient *rcpt,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch unsigned int index);
c649139f889c02154fc9a153728b81619edb5663Timo Sirainen
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch void *trans_context;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch};
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_server_cmd_auth {
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *sasl_mech;
c649139f889c02154fc9a153728b81619edb5663Timo Sirainen const char *initial_response;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen};
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Boschstruct smtp_server_callbacks {
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch /* Command callbacks:
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch These are used to override/implement the behavior of the various core
53ec1ff2231d477db3103c51987fa9cb6033bc16Timo Sirainen SMTP commands. Commands are handled asynchronously, which means that
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen the command is not necessarily finished when the callback ends. A
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen command is finished either when 1 is returned or a reply is submitted
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch for it. When a callback returns 0, the command implementation is
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen waiting for an external event and when it returns -1 an error
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen occurred. When 1 is returned, a default success reply is set if no
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen reply was submitted. Not submitting an error reply when -1 is
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen returned causes an assert fail. Except for RCPT and DATA, all these
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen callbacks are optional to implement; appropriate default behavior is
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen provided.
88b90ce9dfe1056d1ec5497b95592d30a849e5f1Timo Sirainen
88b90ce9dfe1056d1ec5497b95592d30a849e5f1Timo Sirainen The SMTP server API takes care of transaction state checking.
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen However, until all previous commands are handled, a transaction
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen command cannot rely on the transaction state being final. Use
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen cmd->hook_next to get notified when all previous commands are
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen finished and the current command is next in line to reply.
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen If the implementation does not need asynchronous behavior, set
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen max_pipelined_commands=1 and don't return 0 from any command handler.
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch /* HELO/EHLO/LHLO */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_helo)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd,
f7fa93fb42a5b9d4a7e2f0367f03f920ef7ec443Timo Sirainen struct smtp_server_cmd_helo *data);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* STARTTLS */
f7fa93fb42a5b9d4a7e2f0367f03f920ef7ec443Timo Sirainen int (*conn_cmd_starttls)(void *conn_ctx,
f7fa93fb42a5b9d4a7e2f0367f03f920ef7ec443Timo Sirainen struct smtp_server_cmd_ctx *cmd);
f7fa93fb42a5b9d4a7e2f0367f03f920ef7ec443Timo Sirainen /* AUTH */
dafbec2c6b4275233a78cb137f41dd8041aa1c46Timo Sirainen int (*conn_cmd_auth)(void *conn_ctx,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server_cmd_ctx *cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server_cmd_auth *data);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_auth_continue)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd, const char *response);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* MAIL */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_mail)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_mail *data);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* RCPT */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_rcpt)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_rcpt *data);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* RSET */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_rset)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* DATA */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_data_begin)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_transaction *trans,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct istream *data_input);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_data_continue)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_transaction *trans);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* VRFY */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_vrfy)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen const char *param);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* NOOP */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_noop)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* QUIT */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen int (*conn_cmd_quit)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* XCLIENT */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen void (*conn_cmd_xclient)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_proxy_data *data);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* Command input callbacks:
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen These can be used to do stuff before and after a pipelined group of
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen commands is read.
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen */
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen void (*conn_cmd_input_pre)(void *context);
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen void (*conn_cmd_input_post)(void *context);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* Transaction events */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen void (*conn_trans_free)(void *context,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct smtp_server_transaction *trans);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* Protocol state events */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen void (*conn_state_changed)(void *context,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen enum smtp_server_state newstate);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen /* Proxy data */
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen void (*conn_proxy_data_updated)(void *conn_ctx,
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen const struct smtp_proxy_data *data);
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen /* Connection */
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen int (*conn_start_tls)(void *conn_ctx,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct istream **input, struct ostream **output);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen void (*conn_disconnect)(void *context, const char *reason);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen void (*conn_destroy)(void *context);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen /* Security */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen bool (*conn_is_trusted)(void *context);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen};
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen/*
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen * Server
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct smtp_server_settings {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen enum smtp_protocol protocol;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen enum smtp_capability capabilities;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *hostname;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *login_greeting;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *rawlog_dir;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* The maximum time in milliseconds a client is allowed to be idle
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen before it is disconnected. */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int max_client_idle_time_msecs;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* maximum number of commands in pipeline per connection (default = 1)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int max_pipelined_commands;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* maximum number of sequential bad commands */
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen unsigned int max_bad_commands;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* maximum number of recipients in a transaction
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (0 means unlimited, which is the default) */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int max_recipients;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* command limits */
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen struct smtp_command_limits command_limits;
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* accept these additional custom XCLIENT fields */
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen const char *const *xclient_extensions;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* The kernel send/receive buffer sizes used for the connection sockets.
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen Configuring this is mainly useful for the test suite. The kernel
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen defaults are used when these settings are 0. */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen size_t socket_send_buffer_size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen size_t socket_recv_buffer_size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool debug:1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool auth_optional:1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool tls_required:1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool rcpt_domain_optional:1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool param_extensions:1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen};
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenstruct smtp_server_stats {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int command_count, reply_count;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen uoff_t input, output;
91c58af8e992d028eb325707904debb58ae80438Timo Sirainen};
91c58af8e992d028eb325707904debb58ae80438Timo Sirainen
91c58af8e992d028eb325707904debb58ae80438Timo Sirainenstruct smtp_server *smtp_server_init(const struct smtp_server_settings *set);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid smtp_server_deinit(struct smtp_server **_server);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen/*
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen * Connection
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen */
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen/* Create connection. It is still inactive and needs to be started with
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen one of the functions below. */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_connection *
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainensmtp_server_connection_create(struct smtp_server *server,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen int fd_in, int fd_out,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen const struct ip_addr *remote_ip, in_port_t remote_port,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen bool ssl_start, const struct smtp_server_settings *set,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen const struct smtp_server_callbacks *callbacks, void *context)
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen ATTR_NULL(4, 6, 8);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_connection *
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainensmtp_server_connection_create_from_streams(struct smtp_server *server,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct istream *input, struct ostream *output,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct ip_addr *remote_ip, in_port_t remote_port,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct smtp_server_settings *set,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct smtp_server_callbacks *callbacks, void *context)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ATTR_NULL(4, 6, 8);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid smtp_server_connection_ref(struct smtp_server_connection *conn);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenbool smtp_server_connection_unref(struct smtp_server_connection **_conn);
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen/* Initialize the connection with state and data from login service */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid smtp_server_connection_login(struct smtp_server_connection *conn,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen const char *username, const char *helo,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const unsigned char *pdata,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int pdata_len, bool ssl_secured);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen/* Start the connection. Establishes SSL layer immediately if instructed,
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen and sends the greeting once the connection is ready for commands. */
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainenvoid smtp_server_connection_start(struct smtp_server_connection *conn);
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen/* Start the connection, but only establish SSL layer and send greeting;
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen handling command input is held off until smtp_server_connection_resume() is
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen called. */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_connection_start_pending(struct smtp_server_connection *conn);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen/* Halt connection command input and idle timeout entirely. */
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_halt(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen/* Resume connection command input and idle timeout. */
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_resume(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_input_lock(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_input_unlock(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_set_streams(struct smtp_server_connection *conn,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen struct istream *input, struct ostream *output);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_set_ssl_streams(struct smtp_server_connection *conn,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen struct istream *input, struct ostream *output);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_close(struct smtp_server_connection **_conn,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen const char *reason) ATTR_NULL(2);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_terminate(struct smtp_server_connection **_conn,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen const char *enh_code, const char *reason)
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen ATTR_NULL(3);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenbool smtp_server_connection_data_check_state(struct smtp_server_cmd_ctx *cmd);
acc4e0a41f1c8ef0559a19c280afc1b97b9e0818Timo Sirainenvoid smtp_server_connection_data_chunk_init(struct smtp_server_cmd_ctx *cmd);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenint smtp_server_connection_data_chunk_add(struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen struct istream *chunk, uoff_t chunk_size, bool chunk_last,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen bool client_input);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenenum smtp_server_state
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainensmtp_server_connection_get_state(struct smtp_server_connection *conn);
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainenconst char *
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainensmtp_server_connection_get_security_string(struct smtp_server_connection *conn);
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainenstruct smtp_server_transaction *
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainensmtp_server_connection_get_transaction(struct smtp_server_connection *conn);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenconst char *
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainensmtp_server_connection_get_transaction_id(struct smtp_server_connection *conn);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainenconst struct smtp_server_stats *
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainensmtp_server_connection_get_stats(struct smtp_server_connection *conn);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainenvoid *smtp_server_connection_get_context(struct smtp_server_connection *conn)
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen ATTR_PURE;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenenum smtp_protocol
acc4e0a41f1c8ef0559a19c280afc1b97b9e0818Timo Sirainensmtp_server_connection_get_protocol(struct smtp_server_connection *conn)
acc4e0a41f1c8ef0559a19c280afc1b97b9e0818Timo Sirainen ATTR_PURE;
acc4e0a41f1c8ef0559a19c280afc1b97b9e0818Timo Sirainenconst char *
acc4e0a41f1c8ef0559a19c280afc1b97b9e0818Timo Sirainensmtp_server_connection_get_protocol_name(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenstruct smtp_server_helo_data *
acc4e0a41f1c8ef0559a19c280afc1b97b9e0818Timo Sirainensmtp_server_connection_get_helo_data(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenvoid smtp_server_connection_get_proxy_data(struct smtp_server_connection *conn,
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct smtp_proxy_data *proxy_data);
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainenvoid smtp_server_connection_set_capabilities(
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen struct smtp_server_connection *conn, enum smtp_capability capabilities);
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainenbool smtp_server_connection_is_ssl_secured(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenbool smtp_server_connection_is_trusted(struct smtp_server_connection *conn);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen/*
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen * Command
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen */
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenenum smtp_server_command_flags {
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen SMTP_SERVER_CMD_FLAG_PRETLS = BIT(0),
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen SMTP_SERVER_CMD_FLAG_PREAUTH = BIT(1)
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch};
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/* Commands are handled asynchronously, which means that the command is not
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch necessary finished when the start function ends. A command is finished
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch when a reply is submitted for it. Several command hooks are available to
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch get notified about events in the command's life cycle.
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch */
3858a7a5da361c35f1e6e50c8e3214dc0cf379d6Phil Carmody
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschtypedef void smtp_server_cmd_input_callback_t(struct smtp_server_cmd_ctx *cmd);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschtypedef void smtp_server_cmd_start_func_t(struct smtp_server_cmd_ctx *cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *params);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschtypedef void smtp_server_cmd_func_t(struct smtp_server_cmd_ctx *cmd);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_server_cmd_ctx {
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch pool_t pool;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *name;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server *server;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server_connection *conn;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch struct smtp_server_command *cmd;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch /* public hooks */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch /* next: command is next to reply but has not submittted all replies
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch yet */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch smtp_server_cmd_func_t *hook_next;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch /* replied: command has submitted all replies */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch smtp_server_cmd_func_t *hook_replied;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch /* completed: server is about to send last replies for this command */
1a115c1eb46e9103f81228dde272852cb78ed4b5Timo Sirainen smtp_server_cmd_func_t *hook_completed;
1a115c1eb46e9103f81228dde272852cb78ed4b5Timo Sirainen /* destroy: command is about to be destroyed */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch smtp_server_cmd_func_t *hook_destroy;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch void *context;
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch};
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/* The core SMTP commands are pre-registered. Special connection callbacks are
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch provided for the core SMTP commands. Only use this command registration API
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch when custom/extension SMTP commands are required.
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_command_register(struct smtp_server *server, const char *name,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch smtp_server_cmd_start_func_t *func,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch enum smtp_server_command_flags);
9937dfc157dc64ed781b7aa264aa893d1d50c5c4Timo Sirainenvoid smtp_server_command_unregister(struct smtp_server *server,
9937dfc157dc64ed781b7aa264aa893d1d50c5c4Timo Sirainen const char *name);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_command_set_reply_count(struct smtp_server_command *cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch unsigned int count);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid smtp_server_command_fail(struct smtp_server_command *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen unsigned int status, const char *enh_code,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen const char *fmt, ...) ATTR_FORMAT(4, 5);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_server_reply *
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainensmtp_server_command_get_reply(struct smtp_server_command *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen unsigned int idx);
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Boschbool smtp_server_command_reply_status_equals(struct smtp_server_command *cmd,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int status);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenbool smtp_server_command_is_replied(struct smtp_server_command *cmd);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenbool smtp_server_command_replied_success(struct smtp_server_command *cmd);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_command_input_lock(struct smtp_server_cmd_ctx *cmd);
c649139f889c02154fc9a153728b81619edb5663Timo Sirainenvoid smtp_server_command_input_unlock(struct smtp_server_cmd_ctx *cmd);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_command_input_capture(struct smtp_server_cmd_ctx *cmd,
6b09a3b269f4b10364c9a77f6614dbe3d306b79dTimo Sirainen smtp_server_cmd_input_callback_t *callback);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen/* AUTH */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_cmd_auth_send_challenge(struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen const char *challenge);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_cmd_auth_success(struct smtp_server_cmd_ctx *cmd,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen const char *username, const char *success_msg)
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen ATTR_NULL(3);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/*
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch * Reply
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_server_reply *
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschsmtp_server_reply_create_index(struct smtp_server_command *cmd,
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainen unsigned int index, unsigned int status, const char *enh_code)
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch ATTR_NULL(3);
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainenstruct smtp_server_reply *
34a41fd572d2516549b3a3b340c36730f284612aTimo Sirainensmtp_server_reply_create(struct smtp_server_command *cmd,
428d63767dc20aeb87695b82fb01cd0a06d7769cTimo Sirainen unsigned int status, const char *enh_code) ATTR_NULL(3);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschstruct smtp_server_reply *
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainensmtp_server_reply_create_forward(struct smtp_server_command *cmd,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int index, const struct smtp_reply *from);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainenvoid smtp_server_reply_add_text(struct smtp_server_reply *reply,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *line);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid smtp_server_reply_submit(struct smtp_server_reply *reply);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen/* Submit a reply for the command at the specified index (> 0 only if more than
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch a single reply is expected). */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply_indexv(struct smtp_server_cmd_ctx *_cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch unsigned int index, unsigned int status, const char *enh_code,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *fmt, va_list args) ATTR_FORMAT(5, 0);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply_index(struct smtp_server_cmd_ctx *_cmd,
1a115c1eb46e9103f81228dde272852cb78ed4b5Timo Sirainen unsigned int index, unsigned int status, const char *enh_code,
1a115c1eb46e9103f81228dde272852cb78ed4b5Timo Sirainen const char *fmt, ...) ATTR_FORMAT(5, 6);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/* Submit the reply for the specified command. */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply(struct smtp_server_cmd_ctx *_cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch unsigned int status, const char *enh_code, const char *fmt, ...)
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch ATTR_FORMAT(4, 5);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/* Forward a reply for the command at the specified index (> 0 only if more
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch than a single reply is expected). */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply_index_forward(struct smtp_server_cmd_ctx *cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch unsigned int index, const struct smtp_reply *from);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/* Forward the reply for the specified command. */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply_forward(struct smtp_server_cmd_ctx *cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const struct smtp_reply *from);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/* Submit the same message for all expected replies for this command. */
c215ca02d468b0e542523df1ed18e5f2d7e63968Timo Sirainenvoid smtp_server_reply_all(struct smtp_server_cmd_ctx *_cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch unsigned int status, const char *enh_code,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *fmt, ...) ATTR_FORMAT(4, 5);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch/* Submit and send the same message for all expected replies for this command
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch early; i.e., no matter whether all command data is received completely. */
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply_early(struct smtp_server_cmd_ctx *_cmd,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch unsigned int status, const char *enh_code,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *fmt, ...) ATTR_FORMAT(4, 5);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen/* Reply the command with a 221 bye message */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_reply_quit(struct smtp_server_cmd_ctx *_cmd);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_switch_ioloop(struct smtp_server *server);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen/* EHLO */
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenstruct smtp_server_reply *
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschsmtp_server_reply_create_ehlo(struct smtp_server_command *cmd);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply_ehlo_add(struct smtp_server_reply *reply,
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Bosch const char *keyword);
2d7df7973f80011033e8e9fa676d3ff4c14468d8Stephan Boschvoid smtp_server_reply_ehlo_add_param(struct smtp_server_reply *reply,
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen const char *keyword, const char *param_fmt, ...) ATTR_FORMAT(3, 4);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenvoid smtp_server_reply_ehlo_add_xclient(struct smtp_server_reply *reply);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen#endif
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen