Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7928:9e226056a208 HEAD
Send login command OK reply in IMAP/POP3 process.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 21 Jun 2008 12:50:28 +0300 |
parents | 2351a81ce699 |
children | 55d1a2bf4573 |
files | src/imap-login/client-authenticate.c src/imap-login/client.c src/imap-login/client.h src/imap/main.c src/login-common/client-common.h src/login-common/master.c src/master/login-process.c src/master/mail-process.c src/master/mail-process.h src/master/master-login-interface.h src/master/master-settings.c src/pop3-login/client-authenticate.c src/pop3/main.c |
diffstat | 13 files changed, 97 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap-login/client-authenticate.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/imap-login/client-authenticate.c Sat Jun 21 12:50:28 2008 +0300 @@ -82,6 +82,7 @@ io_remove(&client->io); client->io = io_add(client->common.fd, IO_READ, client_input, client); + client->common.auth_command_tag = NULL; } static bool client_handle_args(struct imap_client *client, @@ -207,14 +208,6 @@ if (client_handle_args(client, args, TRUE)) break; } - - if (client->full_capability_sent) - client_send_tagline(client, "OK Logged in."); - else { - client_send_tagline(client, t_strdup_printf( - "OK [CAPABILITY %s] Logged in.", - capability_string)); - } client_destroy_success(client, "Login"); break; case SASL_SERVER_REPLY_AUTH_FAILED: @@ -271,6 +264,8 @@ static int client_auth_begin(struct imap_client *client, const char *mech_name, const char *init_resp) { + client->common.auth_command_tag = client->cmd_tag; + client_ref(client); sasl_server_auth_begin(&client->common, IMAP_SERVICE_NAME, mech_name, init_resp, sasl_callback);
--- a/src/imap-login/client.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/imap-login/client.c Sat Jun 21 12:50:28 2008 +0300 @@ -108,7 +108,8 @@ static int cmd_capability(struct imap_client *client) { - client->full_capability_sent = TRUE; + client->common.master_login_flags |= + LOGIN_IMAP_FLAG_FULL_CAPABILITY_SENT; client_send_line(client, t_strconcat( "* CAPABILITY ", get_capability(client, TRUE), NULL)); client_send_tagline(client, "OK Capability completed.");
--- a/src/imap-login/client.h Sat Jun 21 12:23:08 2008 +0300 +++ b/src/imap-login/client.h Sat Jun 21 12:50:28 2008 +0300 @@ -31,7 +31,6 @@ unsigned int destroyed:1; unsigned int greeting_sent:1; unsigned int id_logged:1; - unsigned int full_capability_sent:1; }; void client_destroy(struct imap_client *client, const char *reason);
--- a/src/imap/main.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/imap/main.c Sat Jun 21 12:50:28 2008 +0300 @@ -24,7 +24,7 @@ #include <syslog.h> #define IS_STANDALONE() \ - (getenv("LOGGED_IN") == NULL && getenv("IMAPLOGINTAG") == NULL) + (getenv("IMAPLOGINTAG") == NULL) struct client_workaround_list { const char *name; @@ -167,7 +167,7 @@ struct client *client; struct ostream *output; struct mail_namespace *ns; - const char *user, *str; + const char *user, *str, *tag; lib_signals_init(); lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); @@ -244,15 +244,21 @@ output = client->output; o_stream_ref(output); o_stream_cork(output); - if (IS_STANDALONE()) { + + /* IMAPLOGINTAG environment is compatible with mailfront */ + tag = getenv("IMAPLOGINTAG"); + if (tag == NULL) { client_send_line(client, t_strconcat( "* PREAUTH [CAPABILITY ", str_c(capability_string), "] " "Logged in as ", user, NULL)); - } else if (getenv("IMAPLOGINTAG") != NULL) { - /* Support for mailfront */ - client_send_line(client, t_strconcat(getenv("IMAPLOGINTAG"), - " OK Logged in.", NULL)); + } else if (getenv("CLIENT_SEND_CAPABILITY") == NULL) { + client_send_line(client, + t_strconcat(tag, " OK Logged in.", NULL)); + } else { + client_send_line(client, t_strconcat( + tag, " OK [CAPABILITY ", + str_c(capability_string), "] Logged in", NULL)); } str = getenv("CLIENT_INPUT"); if (str != NULL) T_BEGIN { @@ -290,7 +296,7 @@ int main(int argc ATTR_UNUSED, char *argv[], char *envp[]) { #ifdef DEBUG - if (getenv("LOGGED_IN") != NULL && getenv("GDB") == NULL) + if (!IS_STANDALONE() && getenv("GDB") == NULL) fd_debug_verify_leaks(3, 1024); #endif if (IS_STANDALONE() && getuid() == 0 &&
--- a/src/login-common/client-common.h Sat Jun 21 12:23:08 2008 +0300 +++ b/src/login-common/client-common.h Sat Jun 21 12:50:28 2008 +0300 @@ -23,10 +23,12 @@ int fd; struct istream *input; + const char *auth_command_tag; char *auth_mech_name; struct auth_request *auth_request; + enum master_login_flags master_login_flags; unsigned int master_tag; master_callback_t *master_callback; sasl_server_callback_t *sasl_callback;
--- a/src/login-common/master.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/login-common/master.c Sat Jun 21 12:50:28 2008 +0300 @@ -66,13 +66,18 @@ const unsigned char *data; size_t size; ssize_t ret; + unsigned int cmd_tag_size; i_assert(auth_pid != 0); data = i_stream_get_data(client->input, &size); + cmd_tag_size = client->auth_command_tag == NULL ? 0 : + strlen(client->auth_command_tag); + buf = buffer_create_dynamic(pool_datastack_create(), - sizeof(*req) + size); - buffer_write(buf, sizeof(*req), data, size); + sizeof(*req) + size + cmd_tag_size); + buffer_write(buf, sizeof(*req), client->auth_command_tag, cmd_tag_size); + buffer_write(buf, sizeof(*req) + cmd_tag_size, data, size); req = buffer_get_space_unsafe(buf, 0, sizeof(*req)); req->version = MASTER_LOGIN_PROTOCOL_VERSION; req->tag = ++master_tag_counter; @@ -82,8 +87,10 @@ req->auth_id = auth_id; req->local_ip = client->local_ip; req->remote_ip = client->ip; - req->data_size = size; -#if LOGIN_MAX_INBUF_SIZE != MASTER_LOGIN_MAX_DATA_SIZE + req->flags = client->master_login_flags; + req->cmd_tag_size = cmd_tag_size; + req->data_size = req->cmd_tag_size + size; +#if (LOGIN_MAX_INBUF_SIZE*2) != MASTER_LOGIN_MAX_DATA_SIZE # error buffer max sizes unsynced #endif i_assert(req->data_size <= LOGIN_MAX_INBUF_SIZE);
--- a/src/master/login-process.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/master/login-process.c Sat Jun 21 12:50:28 2008 +0300 @@ -44,12 +44,9 @@ struct login_auth_request { struct login_process *process; unsigned int tag; + unsigned int login_tag; - unsigned int login_tag; - int fd; - - unsigned int data_size; - struct ip_addr local_ip, remote_ip; + struct mail_login_request mail_request; unsigned char data[]; }; @@ -104,11 +101,8 @@ master_reply.status = create_mail_process(group->mail_process_type, - group->set, - request->fd, &request->local_ip, - &request->remote_ip, user, args, - request->data_size, request->data, - FALSE); + group->set, &request->mail_request, + user, args, request->data, FALSE); } T_END; /* reply to login */ @@ -124,7 +118,7 @@ login_process_destroy(request->process); } - if (close(request->fd) < 0) + if (close(request->mail_request.fd) < 0) i_error("close(mail client) failed: %m"); login_process_unref(request->process); i_free(request); @@ -441,10 +435,12 @@ authreq->process = p; authreq->tag = ++auth_id_counter; authreq->login_tag = req.tag; - authreq->fd = client_fd; - authreq->local_ip = req.local_ip; - authreq->remote_ip = req.remote_ip; - authreq->data_size = req.data_size; + authreq->mail_request.fd = client_fd; + authreq->mail_request.local_ip = req.local_ip; + authreq->mail_request.remote_ip = req.remote_ip; + authreq->mail_request.flags = req.flags; + authreq->mail_request.cmd_tag_size = req.cmd_tag_size; + authreq->mail_request.data_size = req.data_size; memcpy(authreq->data, data, req.data_size); auth_process = auth_process_find(req.auth_pid);
--- a/src/master/mail-process.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/master/mail-process.c Sat Jun 21 12:50:28 2008 +0300 @@ -522,11 +522,9 @@ enum master_login_status create_mail_process(enum process_type process_type, struct settings *set, - int socket_fd, const struct ip_addr *local_ip, - const struct ip_addr *remote_ip, + const struct mail_login_request *request, const char *user, const char *const *args, - unsigned int input_size, const unsigned char *input, - bool dump_capability) + const unsigned char *data, bool dump_capability) { const struct var_expand_table *var_expand_table; const char *p, *addr, *mail, *chroot_dir, *home_dir, *full_home_dir; @@ -553,7 +551,8 @@ /* check process limit for this user */ process_group = dump_capability ? NULL : - mail_process_group_lookup(process_type, user, remote_ip); + mail_process_group_lookup(process_type, user, + &request->remote_ip); process_count = process_group == NULL ? 0 : array_count(&process_group->processes); if (process_count >= set->mail_max_userip_connections && @@ -684,8 +683,8 @@ var_expand_table = get_var_expand_table(process_names[process_type], user, home_given ? home_dir : NULL, - net_ip2addr(local_ip), - net_ip2addr(remote_ip), + net_ip2addr(&request->local_ip), + net_ip2addr(&request->remote_ip), pid != 0 ? pid : getpid(), uid); str = t_str_new(128); @@ -697,10 +696,9 @@ log_set_prefix(log, str_c(str)); log_set_pid(log, pid); if (process_group == NULL) { - process_group = - mail_process_group_create(process_type, - user, - remote_ip); + process_group = mail_process_group_create( + process_type, user, + &request->remote_ip); } mail_process_group_add(process_group, pid); } @@ -724,9 +722,9 @@ child_process_init_env(); /* move the client socket into stdin and stdout fds, log to stderr */ - if (dup2(dump_capability ? null_fd : socket_fd, 0) < 0) + if (dup2(dump_capability ? null_fd : request->fd, 0) < 0) i_fatal("dup2(stdin) failed: %m"); - if (dup2(socket_fd, 1) < 0) + if (dup2(request->fd, 1) < 0) i_fatal("dup2(stdout) failed: %m"); if (dup2(log_fd, 2) < 0) i_fatal("dup2(stderr) failed: %m"); @@ -831,13 +829,23 @@ env_put(t_strconcat("HOME=", home_dir, NULL)); env_put(t_strconcat("USER=", user, NULL)); - addr = net_ip2addr(remote_ip); + addr = net_ip2addr(&request->remote_ip); env_put(t_strconcat("IP=", addr, NULL)); - if (input_size > 0) { + i_assert(request->cmd_tag_size <= request->data_size); + if (request->cmd_tag_size > 0) { + env_put(t_strconcat("IMAPLOGINTAG=", + t_strndup(data, request->cmd_tag_size), NULL)); + } + if ((request->flags & LOGIN_IMAP_FLAG_FULL_CAPABILITY_SENT) == 0 && + process_type == PROCESS_TYPE_IMAP) + env_put("CLIENT_SEND_CAPABILITY=1"); + + if (request->data_size > request->cmd_tag_size) { str_truncate(str, 0); str_append(str, "CLIENT_INPUT="); - base64_encode(input, input_size, str); + base64_encode(data + request->cmd_tag_size, + request->data_size - request->cmd_tag_size, str); env_put(str_c(str)); }
--- a/src/master/mail-process.h Sat Jun 21 12:23:08 2008 +0300 +++ b/src/master/mail-process.h Sat Jun 21 12:50:28 2008 +0300 @@ -1,8 +1,17 @@ #ifndef MAIL_PROCESS_H #define MAIL_PROCESS_H +#include "master-login-interface.h" #include "child-process.h" +struct mail_login_request { + int fd; + enum master_login_flags flags; + unsigned int cmd_tag_size; + unsigned int data_size; + struct ip_addr local_ip, remote_ip; +}; + struct login_group; struct auth_master_reply; @@ -10,11 +19,9 @@ enum master_login_status create_mail_process(enum process_type process_type, struct settings *set, - int socket_fd, const struct ip_addr *local_ip, - const struct ip_addr *remote_ip, + const struct mail_login_request *request, const char *user, const char *const *args, - unsigned int input_size, const unsigned char *input, - bool dump_capability); + const unsigned char *data, bool dump_capability); void mail_processes_init(void); void mail_processes_deinit(void);
--- a/src/master/master-login-interface.h Sat Jun 21 12:23:08 2008 +0300 +++ b/src/master/master-login-interface.h Sat Jun 21 12:50:28 2008 +0300 @@ -9,8 +9,9 @@ (or something else) is changed. */ #define MASTER_LOGIN_PROTOCOL_VERSION 3 -/* This should be kept in sync with LOGIN_MAX_INBUF_SIZE */ -#define MASTER_LOGIN_MAX_DATA_SIZE 4096 +/* This should be kept in sync with LOGIN_MAX_INBUF_SIZE. Multiply it by two + to make sure there's space to transfer the command tag */ +#define MASTER_LOGIN_MAX_DATA_SIZE (4096*2) enum master_login_state { /* process is accepting new connections */ @@ -24,6 +25,10 @@ LOGIN_STATE_COUNT }; +enum master_login_flags { + LOGIN_IMAP_FLAG_FULL_CAPABILITY_SENT = 0x01 +}; + struct master_login_request { uint32_t version; /* if fd == -1, tag is used as master_login_state */ @@ -32,7 +37,9 @@ uint32_t auth_pid; uint32_t auth_id; /* request follows this many bytes of client input */ - uint32_t data_size; + uint16_t data_size; + uint16_t cmd_tag_size; + uint32_t flags; ino_t ino;
--- a/src/master/master-settings.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/master/master-settings.c Sat Jun 21 12:50:28 2008 +0300 @@ -614,7 +614,7 @@ NULL }; enum master_login_status login_status; - struct ip_addr ip; + struct mail_login_request request; char buf[4096]; int fd[2], status; ssize_t ret; @@ -638,16 +638,17 @@ args[1] = t_strdup_printf("gid=%s", dec2str(getegid())); } - memset(&ip, 0, sizeof(ip)); if (pipe(fd) < 0) { i_error("pipe() failed: %m"); return FALSE; } fd_close_on_exec(fd[0], TRUE); fd_close_on_exec(fd[1], TRUE); - login_status = create_mail_process(PROCESS_TYPE_IMAP, set, fd[1], - &ip, &ip, "dump-capability", - args, 0, NULL, TRUE); + + memset(&request, 0, sizeof(request)); + request.fd = fd[1]; + login_status = create_mail_process(PROCESS_TYPE_IMAP, set, &request, + "dump-capability", args, NULL, TRUE); if (login_status != MASTER_LOGIN_STATUS_OK) { (void)close(fd[0]); (void)close(fd[1]);
--- a/src/pop3-login/client-authenticate.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/pop3-login/client-authenticate.c Sat Jun 21 12:50:28 2008 +0300 @@ -169,7 +169,6 @@ break; } - client_send_line(client, "+OK Logged in."); client_destroy_success(client, "Login"); break; case SASL_SERVER_REPLY_AUTH_FAILED:
--- a/src/pop3/main.c Sat Jun 21 12:23:08 2008 +0300 +++ b/src/pop3/main.c Sat Jun 21 12:50:28 2008 +0300 @@ -242,6 +242,9 @@ if (client == NULL) return FALSE; + if (!IS_STANDALONE()) + client_send_line(client, "+OK Logged in."); + str = getenv("CLIENT_INPUT"); if (str != NULL) T_BEGIN { buffer_t *buf = t_base64_decode_str(str);