main.c (dovecot-2.3.16) | : | main.c (dovecot-2.3.17) | ||
---|---|---|---|---|
skipping to change at line 168 | skipping to change at line 168 | |||
size_t input_size; | size_t input_size; | |||
bool send_untagged_capability; | bool send_untagged_capability; | |||
}; | }; | |||
static void | static void | |||
client_parse_imap_login_request(const unsigned char *data, size_t len, | client_parse_imap_login_request(const unsigned char *data, size_t len, | |||
struct imap_login_request *input_r) | struct imap_login_request *input_r) | |||
{ | { | |||
size_t taglen; | size_t taglen; | |||
i_assert(len > 0); | ||||
i_zero(input_r); | i_zero(input_r); | |||
if (len == 0) | ||||
return; | ||||
if (data[0] == '1') | if (data[0] == '1') | |||
input_r->send_untagged_capability = TRUE; | input_r->send_untagged_capability = TRUE; | |||
data++; len--; | data++; len--; | |||
input_r->tag = t_strndup(data, len); | input_r->tag = t_strndup(data, len); | |||
taglen = strlen(input_r->tag) + 1; | taglen = strlen(input_r->tag) + 1; | |||
if (len > taglen) { | if (len > taglen) { | |||
input_r->input = data + taglen; | input_r->input = data + taglen; | |||
input_r->input_size = len - taglen; | input_r->input_size = len - taglen; | |||
} | } | |||
} | } | |||
static void | static void | |||
client_add_input(struct client *client, const unsigned char *client_input, | ||||
size_t client_input_size, struct imap_login_request *request_r) | ||||
{ | ||||
if (client_input_size > 0) { | ||||
client_parse_imap_login_request(client_input, client_input_size, | ||||
request_r); | ||||
if (request_r->input_size > 0) { | ||||
client_add_istream_prefix(client, request_r->input, | ||||
request_r->input_size); | ||||
} | ||||
} else { | ||||
/* IMAPLOGINTAG environment is compatible with mailfront */ | ||||
i_zero(request_r); | ||||
request_r->tag = getenv("IMAPLOGINTAG"); | ||||
} | ||||
} | ||||
static void | ||||
client_send_login_reply(struct ostream *output, const char *capability_string, | client_send_login_reply(struct ostream *output, const char *capability_string, | |||
const char *preauth_username, | const char *preauth_username, | |||
const struct imap_login_request *request) | const struct imap_login_request *request) | |||
{ | { | |||
string_t *reply = t_str_new(256); | string_t *reply = t_str_new(256); | |||
/* cork/uncork around the OK reply to minimize latency */ | /* cork/uncork around the OK reply to minimize latency */ | |||
o_stream_cork(output); | o_stream_cork(output); | |||
if (request->tag == NULL) { | if (request->tag == NULL) { | |||
str_printfa(reply, "* PREAUTH [CAPABILITY %s] Logged in as %s\r\n ", | str_printfa(reply, "* PREAUTH [CAPABILITY %s] Logged in as %s\r\n ", | |||
skipping to change at line 347 | skipping to change at line 329 | |||
if ((value = getenv("IP")) != NULL) | if ((value = getenv("IP")) != NULL) | |||
(void)net_addr2ip(value, &input.remote_ip); | (void)net_addr2ip(value, &input.remote_ip); | |||
if ((value = getenv("LOCAL_IP")) != NULL) | if ((value = getenv("LOCAL_IP")) != NULL) | |||
(void)net_addr2ip(value, &input.local_ip); | (void)net_addr2ip(value, &input.local_ip); | |||
if (client_create_from_input(&input, STDIN_FILENO, STDOUT_FILENO, | if (client_create_from_input(&input, STDIN_FILENO, STDOUT_FILENO, | |||
&client, &error) < 0) | &client, &error) < 0) | |||
i_fatal("%s", error); | i_fatal("%s", error); | |||
input_base64 = getenv("CLIENT_INPUT"); | input_base64 = getenv("CLIENT_INPUT"); | |||
if (input_base64 == NULL) | if (input_base64 == NULL) { | |||
client_add_input(client, NULL, 0, &request); | /* IMAPLOGINTAG environment is compatible with mailfront */ | |||
else { | i_zero(&request); | |||
request.tag = getenv("IMAPLOGINTAG"); | ||||
} else { | ||||
const buffer_t *input_buf = t_base64_decode_str(input_base64); | const buffer_t *input_buf = t_base64_decode_str(input_base64); | |||
client_add_input(client, input_buf->data, input_buf->used, | client_parse_imap_login_request(input_buf->data, input_buf->used, | |||
&request); | &request); | |||
if (request.input_size > 0) { | ||||
client_add_istream_prefix(client, request.input, | ||||
request.input_size); | ||||
} | ||||
} | } | |||
client_create_finish_io(client); | client_create_finish_io(client); | |||
client_send_login_reply(client->output, | client_send_login_reply(client->output, | |||
str_c(client->capability_string), | str_c(client->capability_string), | |||
client->user->username, &request); | client->user->username, &request); | |||
if (client_create_finish(client, &error) < 0) | if (client_create_finish(client, &error) < 0) | |||
i_fatal("%s", error); | i_fatal("%s", error); | |||
client_add_input_finalize(client); | client_add_input_finalize(client); | |||
/* client may be destroyed now */ | /* client may be destroyed now */ | |||
skipping to change at line 390 | skipping to change at line 378 | |||
input.local_port = login_client->auth_req.local_port; | input.local_port = login_client->auth_req.local_port; | |||
input.remote_port = login_client->auth_req.remote_port; | input.remote_port = login_client->auth_req.remote_port; | |||
input.username = username; | input.username = username; | |||
input.userdb_fields = extra_fields; | input.userdb_fields = extra_fields; | |||
input.session_id = login_client->session_id; | input.session_id = login_client->session_id; | |||
if ((flags & MAIL_AUTH_REQUEST_FLAG_CONN_SECURED) != 0) | if ((flags & MAIL_AUTH_REQUEST_FLAG_CONN_SECURED) != 0) | |||
input.conn_secured = TRUE; | input.conn_secured = TRUE; | |||
if ((flags & MAIL_AUTH_REQUEST_FLAG_CONN_SSL_SECURED) != 0) | if ((flags & MAIL_AUTH_REQUEST_FLAG_CONN_SSL_SECURED) != 0) | |||
input.conn_ssl_secured = TRUE; | input.conn_ssl_secured = TRUE; | |||
client_parse_imap_login_request(login_client->data, | ||||
login_client->auth_req.data_size, | ||||
&request); | ||||
if (client_create_from_input(&input, login_client->fd, login_client->fd, | if (client_create_from_input(&input, login_client->fd, login_client->fd, | |||
&client, &error) < 0) { | &client, &error) < 0) { | |||
int fd = login_client->fd; | int fd = login_client->fd; | |||
struct ostream *output = | struct ostream *output = | |||
o_stream_create_fd_autoclose(&fd, IO_BLOCK_SIZE); | o_stream_create_fd_autoclose(&fd, IO_BLOCK_SIZE); | |||
i_zero(&request); | ||||
client_send_login_reply(output, NULL, NULL, &request); | client_send_login_reply(output, NULL, NULL, &request); | |||
o_stream_destroy(&output); | o_stream_destroy(&output); | |||
i_error("%s", error); | i_error("%s", error); | |||
master_service_client_connection_destroyed(master_service); | master_service_client_connection_destroyed(master_service); | |||
return; | return; | |||
} | } | |||
if ((flags & MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION) != 0) | if ((flags & MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION) != 0) | |||
client->tls_compression = TRUE; | client->tls_compression = TRUE; | |||
client_add_input(client, login_client->data, | if (request.input_size > 0) { | |||
login_client->auth_req.data_size, &request); | client_add_istream_prefix(client, request.input, | |||
request.input_size); | ||||
} | ||||
/* The order here is important: | /* The order here is important: | |||
1. Finish setting up rawlog, so all input/output is written there. | 1. Finish setting up rawlog, so all input/output is written there. | |||
2. Send tagged reply to login before any potentially long-running | 2. Send tagged reply to login before any potentially long-running | |||
work (during which client could disconnect due to timeout). | work (during which client could disconnect due to timeout). | |||
3. Finish initializing user, which can potentially take a long time. | 3. Finish initializing user, which can potentially take a long time. | |||
*/ | */ | |||
client_create_finish_io(client); | client_create_finish_io(client); | |||
client_send_login_reply(client->output, | client_send_login_reply(client->output, | |||
str_c(client->capability_string), | str_c(client->capability_string), | |||
skipping to change at line 473 | skipping to change at line 466 | |||
int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | |||
{ | { | |||
static const struct setting_parser_info *set_roots[] = { | static const struct setting_parser_info *set_roots[] = { | |||
&smtp_submit_setting_parser_info, | &smtp_submit_setting_parser_info, | |||
&imap_setting_parser_info, | &imap_setting_parser_info, | |||
NULL | NULL | |||
}; | }; | |||
struct master_login_settings login_set; | struct master_login_settings login_set; | |||
enum master_service_flags service_flags = 0; | enum master_service_flags service_flags = 0; | |||
enum mail_storage_service_flags storage_service_flags = | enum mail_storage_service_flags storage_service_flags = | |||
MAIL_STORAGE_SERVICE_FLAG_NO_SSL_CA | | ||||
/* | /* | |||
* We include MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES so | * We include MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES so | |||
* that the mail_user initialization is fast and we can | * that the mail_user initialization is fast and we can | |||
* quickly send back the OK response to LOGIN/AUTHENTICATE. | * quickly send back the OK response to LOGIN/AUTHENTICATE. | |||
* Otherwise we risk a very slow namespace initialization to | * Otherwise we risk a very slow namespace initialization to | |||
* cause client timeouts on login. | * cause client timeouts on login. | |||
*/ | */ | |||
MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES; | MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES; | |||
const char *username = NULL, *auth_socket_path = "auth-master"; | const char *username = NULL, *auth_socket_path = "auth-master"; | |||
int c; | int c; | |||
End of changes. 9 change blocks. | ||||
28 lines changed or deleted | 22 lines changed or added |