[dovecot-cvs] dovecot/src/login Makefile.am,1.3,1.4 client-authenticate.c,1.29,1.30 client-authenticate.h,1.2,1.3 client.c,1.24,1.25 client.h,1.9,1.10
cras at procontrol.fi
cras at procontrol.fi
Tue Jan 7 19:45:40 EET 2003
- Previous message: [dovecot-cvs] dovecot/src/lib istream-file.c,1.4,1.5 istream-internal.h,1.2,1.3 istream.c,1.3,1.4
- Next message: [dovecot-cvs] dovecot/src/lib ostream-file.c,1.3,1.4 ostream.c,1.3,1.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/login
In directory danu:/tmp/cvs-serv29994
Modified Files:
Makefile.am client-authenticate.c client-authenticate.h
client.c client.h
Log Message:
Login process now uses the same imap-parser as the imap process itself. This
fixes the problem of literals not working before logging in.
Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/login/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Makefile.am 24 Nov 2002 20:05:06 -0000 1.3
+++ Makefile.am 7 Jan 2003 17:45:38 -0000 1.4
@@ -3,10 +3,12 @@
pkglibexec_PROGRAMS = imap-login
INCLUDES = \
- -I$(top_srcdir)/src/lib
+ -I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib-imap
imap_login_LDADD = \
../lib/liblib.a \
+ ../lib-imap/imap-parser.o \
$(SSL_LIBS)
imap_login_SOURCES = \
Index: client-authenticate.c
===================================================================
RCS file: /home/cvs/dovecot/src/login/client-authenticate.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- client-authenticate.c 6 Jan 2003 15:44:48 -0000 1.29
+++ client-authenticate.c 7 Jan 2003 17:45:38 -0000 1.30
@@ -8,6 +8,7 @@
#include "ostream.h"
#include "safe-memset.h"
#include "str.h"
+#include "imap-parser.h"
#include "auth-connection.h"
#include "../auth/auth-mech-desc.h"
#include "client.h"
@@ -128,7 +129,7 @@
case AUTH_RESULT_SUCCESS:
client->auth_request = NULL;
- master_request_imap(client->fd, auth_process, client->tag,
+ master_request_imap(client->fd, auth_process, client->cmd_tag,
request->cookie, &client->ip,
master_callback, client);
@@ -180,9 +181,20 @@
}
}
-int cmd_login(struct client *client, const char *user, const char *pass)
+int cmd_login(struct client *client, struct imap_arg *args)
{
- const char *error;
+ const char *user, *pass, *error;
+
+ /* two arguments: username and password */
+ if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
+ return FALSE;
+ if (args[1].type != IMAP_ARG_ATOM && args[1].type != IMAP_ARG_STRING)
+ return FALSE;
+ if (args[2].type != IMAP_ARG_EOL)
+ return FALSE;
+
+ user = IMAP_ARG_STR(&args[0]);
+ pass = IMAP_ARG_STR(&args[1]);
if (!client->tls && disable_plaintext_auth) {
client_send_tagline(client,
@@ -239,6 +251,7 @@
if (!client_read(client))
return;
+ /* @UNSAFE */
line = i_stream_next_line(client->input);
if (line == NULL)
return;
@@ -270,11 +283,18 @@
safe_memset(buffer_free_without_data(buf), 0, bufsize);
}
-int cmd_authenticate(struct client *client, const char *mech_name)
+int cmd_authenticate(struct client *client, struct imap_arg *args)
{
struct auth_mech_desc *mech;
- const char *error;
+ const char *mech_name, *error;
+ /* we want only one argument: authentication mechanism name */
+ if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
+ return FALSE;
+ if (args[1].type != IMAP_ARG_EOL)
+ return FALSE;
+
+ mech_name = IMAP_ARG_STR(&args[0]);
if (*mech_name == '\0')
return FALSE;
Index: client-authenticate.h
===================================================================
RCS file: /home/cvs/dovecot/src/login/client-authenticate.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- client-authenticate.h 5 Jan 2003 13:09:53 -0000 1.2
+++ client-authenticate.h 7 Jan 2003 17:45:38 -0000 1.3
@@ -3,7 +3,7 @@
const char *client_authenticate_get_capabilities(void);
-int cmd_login(struct client *client, const char *user, const char *pass);
-int cmd_authenticate(struct client *client, const char *method_name);
+int cmd_login(struct client *client, struct imap_arg *args);
+int cmd_authenticate(struct client *client, struct imap_arg *args);
#endif
Index: client.c
===================================================================
RCS file: /home/cvs/dovecot/src/login/client.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- client.c 5 Jan 2003 13:09:53 -0000 1.24
+++ client.c 7 Jan 2003 17:45:38 -0000 1.25
@@ -9,12 +9,20 @@
#include "process-title.h"
#include "safe-memset.h"
#include "strescape.h"
+#include "imap-parser.h"
#include "client.h"
#include "client-authenticate.h"
#include "ssl-proxy.h"
#include <syslog.h>
+/* max. size of one parameter in line */
+#define MAX_INBUF_SIZE 512
+
+/* max. number of IMAP argument elements to accept. The maximum memory usage
+ for command from user is around MAX_INBUF_SIZE * MAX_IMAP_ARG_ELEMENTS */
+#define MAX_IMAP_ARG_ELEMENTS 4
+
/* Disconnect client after idling this many seconds */
#define CLIENT_LOGIN_IDLE_TIMEOUT 60
@@ -118,122 +126,127 @@
return TRUE;
}
-int client_read(struct client *client)
+static int client_command_execute(struct client *client, const char *cmd,
+ struct imap_arg *args)
{
- switch (i_stream_read(client->input)) {
- case -2:
- /* buffer full */
- client_send_line(client, "* BYE Input buffer full, aborting");
- client_destroy(client, "Disconnected: Input buffer full");
- return FALSE;
- case -1:
- /* disconnected */
- client_destroy(client, "Disconnected");
- return FALSE;
- default:
- /* something was read */
- return TRUE;
- }
+ cmd = str_ucase(t_strdup_noconst(cmd));
+ if (strcmp(cmd, "LOGIN") == 0)
+ return cmd_login(client, args);
+ if (strcmp(cmd, "AUTHENTICATE") == 0)
+ return cmd_authenticate(client, args);
+ if (strcmp(cmd, "CAPABILITY") == 0)
+ return cmd_capability(client);
+ if (strcmp(cmd, "STARTTLS") == 0)
+ return cmd_starttls(client);
+ if (strcmp(cmd, "NOOP") == 0)
+ return cmd_noop(client);
+ if (strcmp(cmd, "LOGOUT") == 0)
+ return cmd_logout(client);
+
+ return FALSE;
}
-static char *get_next_arg(char **linep)
+/* Skip incoming data until newline is found,
+ returns TRUE if newline was found. */
+static int client_skip_line(struct client *client)
{
- char *line, *start;
- int quoted;
-
- line = *linep;
- while (*line == ' ') line++;
+ const unsigned char *data;
+ size_t i, data_size;
- /* @UNSAFE: get next argument, unescape arg if it's quoted */
- if (*line == '"') {
- quoted = TRUE;
- line++;
+ data = i_stream_get_data(client->input, &data_size);
- start = line;
- while (*line != '\0' && *line != '"') {
- if (*line == '\\' && line[1] != '\0')
- line++;
- line++;
+ for (i = 0; i < data_size; i++) {
+ if (data[i] == '\n') {
+ i_stream_skip(client->input, i+1);
+ return TRUE;
}
-
- if (*line == '"')
- *line++ = '\0';
- str_unescape(start);
- } else {
- start = line;
- while (*line != '\0' && *line != ' ')
- line++;
-
- if (*line == ' ')
- *line++ = '\0';
}
- *linep = line;
- return start;
+ return FALSE;
}
-static int client_command_execute(struct client *client, char *line)
+static void client_handle_input(struct client *client)
{
- char *cmd;
- int ret;
+ struct imap_arg *args;
- cmd = get_next_arg(&line);
- str_ucase(cmd);
+ if (client->cmd_finished) {
+ /* clear the previous command from memory. don't do this
+ immediately after handling command since we need the
+ cmd_tag to stay some time after authentication commands. */
+ client->cmd_tag = NULL;
+ client->cmd_name = NULL;
+ imap_parser_reset(client->parser);
- if (strcmp(cmd, "LOGIN") == 0) {
- char *user, *pass;
+ /* remove \r\n */
+ if (!client_skip_line(client))
+ return;
- user = get_next_arg(&line);
- pass = get_next_arg(&line);
- ret = cmd_login(client, user, pass);
+ client->cmd_finished = FALSE;
+ }
- safe_memset(pass, 0, strlen(pass));
- return ret;
+ if (client->cmd_tag == NULL) {
+ client->cmd_tag = imap_parser_read_word(client->parser);
+ if (client->cmd_tag == NULL)
+ return; /* need more data */
}
- if (strcmp(cmd, "AUTHENTICATE") == 0)
- return cmd_authenticate(client, get_next_arg(&line));
- if (strcmp(cmd, "CAPABILITY") == 0)
- return cmd_capability(client);
- if (strcmp(cmd, "STARTTLS") == 0)
- return cmd_starttls(client);
- if (strcmp(cmd, "NOOP") == 0)
- return cmd_noop(client);
- if (strcmp(cmd, "LOGOUT") == 0)
- return cmd_logout(client);
- return FALSE;
+ if (client->cmd_name == NULL) {
+ client->cmd_name = imap_parser_read_word(client->parser);
+ if (client->cmd_name == NULL)
+ return; /* need more data */
+ }
+
+ switch (imap_parser_read_args(client->parser, 0, 0, &args)) {
+ case -1:
+ /* error */
+ client_destroy(client, NULL);
+ return;
+ case -2:
+ /* not enough data */
+ return;
+ }
+
+ if (*client->cmd_tag == '\0' ||
+ !client_command_execute(client, client->cmd_name, args)) {
+ client_send_tagline(client,
+ "BAD Error in IMAP command received by server.");
+ }
+
+ client->cmd_finished = TRUE;
+}
+
+int client_read(struct client *client)
+{
+ switch (i_stream_read(client->input)) {
+ case -2:
+ /* buffer full */
+ client_send_line(client, "* BYE Input buffer full, aborting");
+ client_destroy(client, "Disconnected: Input buffer full");
+ return FALSE;
+ case -1:
+ /* disconnected */
+ client_destroy(client, "Disconnected");
+ return FALSE;
+ default:
+ /* something was read */
+ return TRUE;
+ }
}
void client_input(void *context, int fd __attr_unused__,
struct io *io __attr_unused__)
{
struct client *client = context;
- char *line;
client->last_input = ioloop_time;
- i_free(client->tag);
- client->tag = i_strdup("*");
-
if (!client_read(client))
return;
client_ref(client);
- o_stream_cork(client->output);
- while ((line = i_stream_next_line(client->input)) != NULL) {
- /* split the arguments, make sure we have at
- least tag + command */
- i_free(client->tag);
- client->tag = i_strdup(get_next_arg(&line));
-
- if (*client->tag == '\0' ||
- !client_command_execute(client, line)) {
- /* error */
- client_send_tagline(client, "BAD Error in IMAP command "
- "received by server.");
- }
- }
+ o_stream_cork(client->output);
+ client_handle_input(client);
if (client_unref(client))
o_stream_flush(client->output);
@@ -306,7 +319,11 @@
client->input = i_stream_create_file(fd, default_pool, 8192, FALSE);
client->output = o_stream_create_file(fd, default_pool, 1024,
IO_PRIORITY_DEFAULT, FALSE);
+ client->parser = imap_parser_create(client->input, client->output,
+ MAX_INBUF_SIZE,
+ MAX_IMAP_ARG_ELEMENTS);
client->plain_login = buffer_create_dynamic(system_pool, 128, 8192);
+
client->last_input = ioloop_time;
hash_insert(clients, client, client);
@@ -324,6 +341,7 @@
hash_remove(clients, client);
+ imap_parser_destroy(client->parser);
i_stream_close(client->input);
o_stream_close(client->output);
@@ -351,7 +369,6 @@
i_stream_unref(client->input);
o_stream_unref(client->output);
- i_free(client->tag);
buffer_free(client->plain_login);
i_free(client);
@@ -367,7 +384,7 @@
void client_send_tagline(struct client *client, const char *line)
{
- client_send_line(client, t_strconcat(client->tag, " ", line, NULL));
+ client_send_line(client, t_strconcat(client->cmd_tag, " ", line, NULL));
}
void client_syslog(struct client *client, const char *text)
Index: client.h
===================================================================
RCS file: /home/cvs/dovecot/src/login/client.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- client.h 5 Jan 2003 13:09:53 -0000 1.9
+++ client.h 7 Jan 2003 17:45:38 -0000 1.10
@@ -12,14 +12,16 @@
struct io *io;
struct istream *input;
struct ostream *output;
+ struct imap_parser *parser;
time_t last_input;
- char *tag;
+ const char *cmd_tag, *cmd_name;
buffer_t *plain_login;
struct auth_request *auth_request;
unsigned int tls:1;
+ unsigned int cmd_finished:1;
};
struct client *client_create(int fd, struct ip_addr *ip, int imaps);
- Previous message: [dovecot-cvs] dovecot/src/lib istream-file.c,1.4,1.5 istream-internal.h,1.2,1.3 istream.c,1.3,1.4
- Next message: [dovecot-cvs] dovecot/src/lib ostream-file.c,1.3,1.4 ostream.c,1.3,1.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list