client-common.h revision da62041ae41e58c9e3ef91bd46c15484390c8247
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen#ifndef CLIENT_COMMON_H
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define CLIENT_COMMON_H
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "network.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "login-proxy.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "sasl-server.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "master-login.h" /* for LOGIN_MAX_SESSION_ID_LEN */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define LOGIN_MAX_MASTER_PREFIX_LEN 128
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* max. size of input buffer. this means:
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen IMAP: Max. length of command's all parameters. SASL-IR is read into
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen a separate larger buffer.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen POP3: Max. length of a command line (spec says 512 would be enough)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen*/
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define LOGIN_MAX_INBUF_SIZE \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (MASTER_AUTH_MAX_DATA_SIZE - LOGIN_MAX_MASTER_PREFIX_LEN - \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen LOGIN_MAX_SESSION_ID_LEN)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* max. size of output buffer. if it gets full, the client is disconnected.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen SASL authentication gives the largest output. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define LOGIN_MAX_OUTBUF_SIZE 4096
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Max. length of SASL authentication buffer. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define LOGIN_MAX_AUTH_BUF_SIZE 8192
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
cc0a651962a3e54d5a62231ac5847ae7f9f7de7fTimo Sirainen/* Disconnect client after this many milliseconds if it hasn't managed
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen to log in yet. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define CLIENT_LOGIN_TIMEOUT_MSECS (MASTER_LOGIN_TIMEOUT_SECS*1000)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define AUTH_SERVER_WAITING_MSG \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Waiting for authentication process to respond.."
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define AUTH_MASTER_WAITING_MSG \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Waiting for authentication master process to respond.."
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
0001f76bf725c5cf403bade8556f142dd43144eeTimo Sirainenenum client_cmd_reply {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CLIENT_CMD_REPLY_OK,
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen CLIENT_CMD_REPLY_AUTH_FAILED,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CLIENT_CMD_REPLY_AUTHZ_FAILED,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen CLIENT_CMD_REPLY_AUTH_FAIL_REASON,
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen CLIENT_CMD_REPLY_AUTH_FAIL_NOSSL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CLIENT_CMD_REPLY_BAD,
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen CLIENT_CMD_REPLY_BYE,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CLIENT_CMD_REPLY_STATUS,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CLIENT_CMD_REPLY_STATUS_BAD
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen};
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainenstruct client_auth_reply {
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen const char *master_user, *reason;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen /* for proxying */
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen const char *host, *hostip, *destuser, *password;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen unsigned int port;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen unsigned int proxy_timeout_msecs;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen unsigned int proxy_refresh_secs;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen enum login_proxy_ssl_flags ssl_flags;
03010dbaa74ec70f062994dfe3cd39bedc99a28bTimo Sirainen
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen unsigned int proxy:1;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen unsigned int temp:1;
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen unsigned int nologin:1;
714c6a150480112eb1a5f309d0cc39b60613a719Timo Sirainen unsigned int authz_failure:1;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen};
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainenstruct client_vfuncs {
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen struct client *(*alloc)(pool_t pool);
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen void (*create)(struct client *client, void **other_sets);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen void (*destroy)(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen void (*send_greeting)(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen void (*starttls)(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen void (*input)(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen void (*send_line)(struct client *client, enum client_cmd_reply reply,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *text);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen bool (*auth_handle_reply)(struct client *client,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct client_auth_reply *reply);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen void (*auth_send_challenge)(struct client *client, const char *data);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int (*auth_parse_response)(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen void (*proxy_reset)(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int (*proxy_parse_line)(struct client *client, const char *line);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
9a02317c852face76737763fa6ec43b444688de5Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct client {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct client *prev, *next;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen pool_t pool;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen struct client_vfuncs v;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen time_t created;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen int refcount;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen
cc0a651962a3e54d5a62231ac5847ae7f9f7de7fTimo Sirainen struct ip_addr local_ip;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct ip_addr ip;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct ip_addr real_ip;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int local_port, remote_port;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen struct ssl_proxy *ssl_proxy;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct login_settings *set;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *session_id;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int fd;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct istream *input;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct ostream *output;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct io *io;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct timeout *to_auth_waiting;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct timeout *to_disconnect;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned char *master_data_prefix;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int master_data_prefix_len;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct login_proxy *login_proxy;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char *proxy_user, *proxy_master_user, *proxy_password;
0001f76bf725c5cf403bade8556f142dd43144eeTimo Sirainen unsigned int proxy_state;
e2eac5bb5637c2d4aaf453389750740931822b92Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char *auth_mech_name;
e2bdacc34dde56aa664059ab56e8b77e82bd1805Timo Sirainen struct auth_client_request *auth_request;
e2bdacc34dde56aa664059ab56e8b77e82bd1805Timo Sirainen string_t *auth_response;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen time_t auth_first_started, auth_finished;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *sasl_final_resp;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int master_auth_id;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int master_tag;
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen sasl_server_callback_t *sasl_callback;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen unsigned int bad_counter;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen unsigned int auth_attempts, auth_successes;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pid_t mail_pid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char *virtual_user;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int destroyed:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int input_blocked:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int login_success:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int greeting_sent:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int starttls:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int tls:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int secured:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int trusted:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int ssl_servername_settings_read:1;
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen unsigned int authenticating:1;
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen unsigned int auth_tried_disabled_plaintext:1;
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen unsigned int auth_tried_unsupported_mech:1;
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen unsigned int auth_try_aborted:1;
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen unsigned int auth_initializing:1;
46908da82cd45dd90ca7e438c8453bc9669868ecTimo Sirainen unsigned int auth_process_comm_fail:1;
46908da82cd45dd90ca7e438c8453bc9669868ecTimo Sirainen unsigned int proxy_auth_failed:1;
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen unsigned int auth_waiting:1;
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen unsigned int auth_user_disabled:1;
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen unsigned int auth_pass_expired:1;
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen /* ... */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenextern struct client *clients;
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenstruct client *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenclient_create(int fd, bool ssl, pool_t pool,
0001f76bf725c5cf403bade8556f142dd43144eeTimo Sirainen const struct login_settings *set, void **other_sets,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct ip_addr *local_ip, const struct ip_addr *remote_ip);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_destroy(struct client *client, const char *reason);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_destroy_success(struct client *client, const char *reason);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_destroy_internal_failure(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_ref(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenbool client_unref(struct client **client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_cmd_starttls(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenunsigned int clients_get_count(void) ATTR_PURE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_set_title(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_log(struct client *client, const char *msg);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_log_err(struct client *client, const char *msg);
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainenvoid client_log_warn(struct client *client, const char *msg);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenconst char *client_get_extra_disconnect_reason(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenbool client_is_trusted(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_auth_failed(struct client *client);
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenbool client_is_tls_enabled(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenconst char *client_get_session_id(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenbool client_read(struct client *client);
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainenvoid client_input(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_send_line(struct client *client, enum client_cmd_reply reply,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *text);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_send_raw_data(struct client *client, const void *data, size_t size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_send_raw(struct client *client, const char *data);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenvoid client_set_auth_waiting(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_auth_send_challenge(struct client *client, const char *data);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint client_auth_parse_response(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint client_auth_begin(struct client *client, const char *mech_name,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *init_resp);
cc0a651962a3e54d5a62231ac5847ae7f9f7de7fTimo Sirainenbool client_check_plaintext_auth(struct client *client, bool pass_sent);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint client_auth_read_line(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_proxy_finish_destroy_client(struct client *client);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_proxy_log_failure(struct client *client, const char *line);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_proxy_failed(struct client *client, bool send_line);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
06eb8c1371aa06478d8840b1373cab7c2752d5edTimo Sirainenvoid clients_notify_auth_connected(void);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid client_destroy_oldest(void);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid clients_destroy_all(void);
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenvoid clients_destroy_all_reason(const char *reason);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen