client-common.h revision bdd36cfdba3ff66d25570a9ff568d69e1eb543cf
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen#ifndef CLIENT_COMMON_H
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen#define CLIENT_COMMON_H
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen#include "net.h"
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen#include "login-proxy.h"
65988f5a8abed57e9894fec77105941e046d3490Timo Sirainen#include "sasl-server.h"
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen#include "master-login.h" /* for LOGIN_MAX_SESSION_ID_LEN */
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen#define LOGIN_MAX_MASTER_PREFIX_LEN 128
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen/* max. size of input buffer. this means:
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen IMAP: Max. length of command's all parameters. SASL-IR is read into
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen a separate larger buffer.
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen POP3: Max. length of a command line (spec says 512 would be enough)
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen*/
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen#define LOGIN_MAX_INBUF_SIZE \
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen (MASTER_AUTH_MAX_DATA_SIZE - LOGIN_MAX_MASTER_PREFIX_LEN - \
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen LOGIN_MAX_SESSION_ID_LEN)
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen/* max. size of output buffer. if it gets full, the client is disconnected.
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen SASL authentication gives the largest output. */
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen#define LOGIN_MAX_OUTBUF_SIZE 4096
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen/* Max. length of SASL authentication buffer. */
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen#define LOGIN_MAX_AUTH_BUF_SIZE 8192
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen/* Disconnect client after this many milliseconds if it hasn't managed
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen to log in yet. */
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen#define CLIENT_LOGIN_TIMEOUT_MSECS (MASTER_LOGIN_TIMEOUT_SECS*1000)
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen#define AUTH_SERVER_WAITING_MSG \
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen "Waiting for authentication process to respond.."
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen#define AUTH_MASTER_WAITING_MSG \
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen "Waiting for authentication master process to respond.."
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainenenum client_disconnect_reason {
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_DISCONNECT_TIMEOUT,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_DISCONNECT_SYSTEM_SHUTDOWN,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_DISCONNECT_RESOURCE_CONSTRAINT,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_DISCONNECT_INTERNAL_ERROR
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen};
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainenenum client_auth_result {
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_SUCCESS,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_REFERRAL_SUCCESS,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_REFERRAL_NOLOGIN,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_ABORTED,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_AUTHFAILED,
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen CLIENT_AUTH_RESULT_AUTHFAILED_REASON,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_AUTHZFAILED,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_TEMPFAIL,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen CLIENT_AUTH_RESULT_SSL_REQUIRED
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen};
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainenstruct client_auth_reply {
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const char *master_user, *reason;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen /* for proxying */
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen const char *host, *hostip, *destuser, *password;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen unsigned int port;
7c424aa51c956c628e3512055841aa2f9eef4833Timo Sirainen unsigned int proxy_timeout_msecs;
f923659c0e5298263d80622c99f4dc4132b4675bTimo Sirainen unsigned int proxy_refresh_secs;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen enum login_proxy_ssl_flags ssl_flags;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen unsigned int proxy:1;
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen unsigned int temp:1;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen unsigned int nologin:1;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen unsigned int authz_failure:1;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen};
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainenstruct client_vfuncs {
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen struct client *(*alloc)(pool_t pool);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*create)(struct client *client, void **other_sets);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*destroy)(struct client *client);
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen void (*notify_auth_ready)(struct client *client);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*notify_disconnect)(struct client *client,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen enum client_disconnect_reason reason,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const char *text);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*notify_status)(struct client *client,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen bool bad, const char *text);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*notify_starttls)(struct client *client,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen bool success, const char *text);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*starttls)(struct client *client);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*input)(struct client *client);
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen void (*auth_send_challenge)(struct client *client, const char *data);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*auth_parse_response)(struct client *client);
fab050cbfdf3da692441d2e2fb4b2a4c6ac9e0daTimo Sirainen void (*auth_result)(struct client *client,
fab050cbfdf3da692441d2e2fb4b2a4c6ac9e0daTimo Sirainen enum client_auth_result result,
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen const struct client_auth_reply *reply,
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const char *text);
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen void (*proxy_reset)(struct client *client);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen int (*proxy_parse_line)(struct client *client, const char *line);
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen void (*proxy_error)(struct client *client, const char *text);
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen};
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainenstruct client {
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen struct client *prev, *next;
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen pool_t pool;
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen struct client_vfuncs v;
2a3fc652e13a574ca14ff2405b5c29a59232db49Timo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen time_t created;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen int refcount;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen struct ip_addr local_ip;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen struct ip_addr ip;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen unsigned int local_port, remote_port;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen struct ssl_proxy *ssl_proxy;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const struct login_settings *set;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const struct master_service_ssl_settings *ssl_set;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen const char *session_id;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen int fd;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen struct istream *input;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen struct ostream *output;
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen struct io *io;
812ac1e2570c600a086c09b24d250224a822a97dTimo Sirainen struct timeout *to_auth_waiting;
d65a556a5ec078cd7f1d0060adb16fc860d66b27Timo Sirainen struct timeout *to_disconnect;
d65a556a5ec078cd7f1d0060adb16fc860d66b27Timo Sirainen
d65a556a5ec078cd7f1d0060adb16fc860d66b27Timo Sirainen unsigned char *master_data_prefix;
e4ded29bff0662a590c2439ef2df8cda8a7cdd9bTimo Sirainen unsigned int master_data_prefix_len;
e4ded29bff0662a590c2439ef2df8cda8a7cdd9bTimo Sirainen
847aeef259d42e2f14cf126699e28291e6e1fb53Timo Sirainen struct login_proxy *login_proxy;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen char *proxy_user, *proxy_master_user, *proxy_password;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int proxy_state;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int proxy_ttl;
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen char *auth_mech_name;
345253fb28498b2e0a60f4a2a8644c65feee7e75Timo Sirainen struct auth_client_request *auth_request;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen string_t *auth_response;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen time_t auth_first_started, auth_finished;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen const char *sasl_final_resp;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int master_auth_id;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int master_tag;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen sasl_server_callback_t *sasl_callback;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen
a4ee24a4d5eefa80bbefc5acba16587ae36c3b5bTimo Sirainen unsigned int bad_counter;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_attempts, auth_successes;
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen pid_t mail_pid;
a93de780c3b78cfaace287026e468f3c3e34683aTimo Sirainen
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen char *virtual_user;
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen unsigned int destroyed:1;
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen unsigned int input_blocked:1;
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainen unsigned int login_success:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int starttls:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int tls:1;
345253fb28498b2e0a60f4a2a8644c65feee7e75Timo Sirainen unsigned int secured:1;
65988f5a8abed57e9894fec77105941e046d3490Timo Sirainen unsigned int trusted:1;
65988f5a8abed57e9894fec77105941e046d3490Timo Sirainen unsigned int ssl_servername_settings_read:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int authenticating:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_tried_disabled_plaintext:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_tried_unsupported_mech:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_try_aborted:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_initializing:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_process_comm_fail:1;
a4ee24a4d5eefa80bbefc5acba16587ae36c3b5bTimo Sirainen unsigned int proxy_auth_failed:1;
a4ee24a4d5eefa80bbefc5acba16587ae36c3b5bTimo Sirainen unsigned int auth_waiting:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_user_disabled:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int auth_pass_expired:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int notified_auth_ready:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen unsigned int notified_disconnect:1;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen /* ... */
055f4599bba1874fa1148a8fa488517fa077619cTimo Sirainen};
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainenextern struct client *clients;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainenstruct client *
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainenclient_create(int fd, bool ssl, pool_t pool,
345253fb28498b2e0a60f4a2a8644c65feee7e75Timo Sirainen const struct login_settings *set,
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen const struct master_service_ssl_settings *ssl_set,
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen void **other_sets,
a93de780c3b78cfaace287026e468f3c3e34683aTimo Sirainen const struct ip_addr *local_ip, const struct ip_addr *remote_ip);
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainenvoid client_destroy(struct client *client, const char *reason);
bc2d4f1c18222a3bd2a6b2b8b5f6abb560a865b3Timo Sirainenvoid client_destroy_success(struct client *client, const char *reason);
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainenvoid client_destroy_internal_failure(struct client *client);
345253fb28498b2e0a60f4a2a8644c65feee7e75Timo Sirainen
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainenvoid client_ref(struct client *client);
a93de780c3b78cfaace287026e468f3c3e34683aTimo Sirainenbool client_unref(struct client **client) ATTR_NOWARN_UNUSED_RESULT;
72388282bf6718c39af34cfcf51438910f9d62daTimo Sirainen
void client_cmd_starttls(struct client *client);
unsigned int clients_get_count(void) ATTR_PURE;
void client_set_title(struct client *client);
void client_log(struct client *client, const char *msg);
void client_log_err(struct client *client, const char *msg);
void client_log_warn(struct client *client, const char *msg);
const char *client_get_extra_disconnect_reason(struct client *client);
void client_auth_respond(struct client *client, const char *response);
void client_auth_abort(struct client *client);
bool client_is_tls_enabled(struct client *client);
void client_auth_fail(struct client *client, const char *text);
const char *client_get_session_id(struct client *client);
bool client_read(struct client *client);
void client_input(struct client *client);
void client_notify_auth_ready(struct client *client);
void client_notify_status(struct client *client, bool bad, const char *text);
void client_notify_disconnect(struct client *client,
enum client_disconnect_reason reason,
const char *text);
void client_send_raw_data(struct client *client, const void *data, size_t size);
void client_send_raw(struct client *client, const char *data);
void client_set_auth_waiting(struct client *client);
void client_auth_send_challenge(struct client *client, const char *data);
void client_auth_parse_response(struct client *client);
int client_auth_begin(struct client *client, const char *mech_name,
const char *init_resp);
bool client_check_plaintext_auth(struct client *client, bool pass_sent);
int client_auth_read_line(struct client *client);
void client_proxy_finish_destroy_client(struct client *client);
void client_proxy_log_failure(struct client *client, const char *line);
void client_proxy_failed(struct client *client, bool send_line);
void clients_notify_auth_connected(void);
void client_destroy_oldest(void);
void clients_destroy_all(void);
void clients_destroy_all_reason(const char *reason);
#endif