changeset 1056:a9b499b2611e HEAD

Disconnect after too many bad commands. We also crashed if there were no mails in mailbox.
author Timo Sirainen <tss@iki.fi>
date Thu, 30 Jan 2003 20:05:33 +0200
parents a72bba3f8a55
children c5ab972db48c
files src/pop3/client.c src/pop3/commands.c src/pop3/commands.h
diffstat 3 files changed, 73 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/pop3/client.c	Thu Jan 30 19:59:31 2003 +0200
+++ b/src/pop3/client.c	Thu Jan 30 20:05:33 2003 +0200
@@ -54,8 +54,11 @@
 
 	client->messages_count = status.messages;
 	client->uidvalidity = status.uidvalidity;
+
+	if (client->messages_count == 0)
+		return TRUE;
+
 	client->message_sizes = i_new(uoff_t, client->messages_count);
-
 	messageset = t_strdup_printf("1:%u", client->messages_count);
 	for (i = 0; i < 2; i++) {
 		ctx = client->mailbox->fetch_init(client->mailbox,
@@ -214,7 +217,12 @@
 		else
 			*args++ = '\0';
 
-		client_command_execute(client, line, args);
+		if (client_command_execute(client, line, args))
+			client->bad_counter = 0;
+		else if (++client->bad_counter > CLIENT_MAX_BAD_COMMANDS) {
+			client_send_line(client, "-ERR Too many bad commands.");
+			client_disconnect(client);
+		}
 	}
 	o_stream_flush(client->output);
 
--- a/src/pop3/commands.c	Thu Jan 30 19:59:31 2003 +0200
+++ b/src/pop3/commands.c	Thu Jan 30 20:05:33 2003 +0200
@@ -84,12 +84,12 @@
 	return args;
 }
 
-static void cmd_dele(struct client *client, const char *args)
+static int cmd_dele(struct client *client, const char *args)
 {
 	unsigned int msgnum;
 
 	if (get_msgnum(client, args, &msgnum) == NULL)
-		return;
+		return FALSE;
 
 	if (!client->deleted) {
 		client->deleted_bitmask = i_malloc(MSGS_BITMASK_SIZE(client));
@@ -98,9 +98,10 @@
 
 	client->deleted_bitmask[msgnum / CHAR_BIT] |= 1 << (msgnum % CHAR_BIT);
 	client_send_line(client, "+OK Marked to be deleted.");
+	return TRUE;
 }
 
-static void cmd_list(struct client *client, const char *args)
+static int cmd_list(struct client *client, const char *args)
 {
 	unsigned int i;
 
@@ -115,19 +116,23 @@
 	} else {
 		unsigned int msgnum;
 
-		if (get_msgnum(client, args, &msgnum) != NULL) {
-			client_send_line(client, "+OK %u %"PRIuUOFF_T, msgnum+1,
-					 client->message_sizes[msgnum]);
-		}
+		if (get_msgnum(client, args, &msgnum) == NULL)
+			return FALSE;
+
+		client_send_line(client, "+OK %u %"PRIuUOFF_T, msgnum+1,
+				 client->message_sizes[msgnum]);
 	}
+
+	return TRUE;
 }
 
-static void cmd_noop(struct client *client, const char *args __attr_unused__)
+static int cmd_noop(struct client *client, const char *args __attr_unused__)
 {
 	client_send_line(client, "+OK");
+	return TRUE;
 }
 
-static void cmd_quit(struct client *client, const char *args __attr_unused__)
+static int cmd_quit(struct client *client, const char *args __attr_unused__)
 {
 	unsigned int first, last, msgnum, max, i, j;
 	struct mail_full_flags flags;
@@ -136,7 +141,7 @@
 	if (!client->deleted) {
 		client_send_line(client, "+OK Logging out.");
 		client_disconnect(client);
-		return;
+		return TRUE;
 	}
 
 	set = t_str_new(1024);
@@ -189,6 +194,7 @@
 		client_send_storage_error(client);
 
 	client_disconnect(client);
+	return TRUE;
 }
 
 static void stream_send_escaped(struct ostream *output, struct istream *input,
@@ -290,15 +296,18 @@
 	(void)client->mailbox->fetch_deinit(ctx, NULL);
 }
 
-static void cmd_retr(struct client *client, const char *args)
+static int cmd_retr(struct client *client, const char *args)
 {
 	unsigned int msgnum;
 
-	if (get_msgnum(client, args, &msgnum) != NULL)
-		fetch(client, msgnum, (uoff_t)-1);
+	if (get_msgnum(client, args, &msgnum) == NULL)
+		return FALSE;
+
+	fetch(client, msgnum, (uoff_t)-1);
+	return TRUE;
 }
 
-static void cmd_rset(struct client *client, const char *args __attr_unused__)
+static int cmd_rset(struct client *client, const char *args __attr_unused__)
 {
 	if (client->deleted) {
 		client->deleted = FALSE;
@@ -306,24 +315,29 @@
 	}
 
 	client_send_line(client, "+OK");
+	return TRUE;
 }
 
-static void cmd_stat(struct client *client, const char *args __attr_unused__)
+static int cmd_stat(struct client *client, const char *args __attr_unused__)
 {
 	client_send_line(client, "+OK %u %"PRIuUOFF_T, client->
 			 messages_count, client->total_size);
+	return TRUE;
 }
 
-static void cmd_top(struct client *client, const char *args)
+static int cmd_top(struct client *client, const char *args)
 {
 	unsigned int msgnum;
 	uoff_t max_lines;
 
 	args = get_msgnum(client, args, &msgnum);
-	if (args != NULL) {
-		if (get_size(client, args, &max_lines) != NULL)
-			fetch(client, msgnum, max_lines);
-	}
+	if (args == NULL)
+		return FALSE;
+	if (get_size(client, args, &max_lines) == NULL)
+		return FALSE;
+
+	fetch(client, msgnum, max_lines);
+	return TRUE;
 }
 
 static void list_uids(struct client *client, unsigned int message)
@@ -360,7 +374,7 @@
 		client_send_line(client, "-ERR Message not found.");
 }
 
-static void cmd_uidl(struct client *client, const char *args)
+static int cmd_uidl(struct client *client, const char *args)
 {
 	if (*args == '\0') {
 		client_send_line(client, "+OK");
@@ -369,12 +383,16 @@
 	} else {
 		unsigned int msgnum;
 
-		if (get_msgnum(client, args, &msgnum) != NULL)
-			list_uids(client, msgnum+1);
+		if (get_msgnum(client, args, &msgnum) == NULL)
+			return FALSE;
+
+		list_uids(client, msgnum+1);
 	}
+
+	return TRUE;
 }
 
-void client_command_execute(struct client *client,
+int client_command_execute(struct client *client,
 			    const char *name, const char *args)
 {
 	/* keep the command uppercased */
@@ -384,58 +402,41 @@
 
 	switch (*name) {
 	case 'D':
-		if (strcmp(name, "DELE") == 0) {
-			cmd_dele(client, args);
-			return;
-		}
+		if (strcmp(name, "DELE") == 0)
+			return cmd_dele(client, args);
 		break;
 	case 'L':
-		if (strcmp(name, "LIST") == 0) {
-			cmd_list(client, args);
-			return;
-		}
+		if (strcmp(name, "LIST") == 0)
+			return cmd_list(client, args);
 		break;
 	case 'N':
-		if (strcmp(name, "NOOP") == 0) {
-			cmd_noop(client, args);
-			return;
-		}
+		if (strcmp(name, "NOOP") == 0)
+			return cmd_noop(client, args);
 		break;
 	case 'Q':
-		if (strcmp(name, "QUIT") == 0) {
-			cmd_quit(client, args);
-			return;
-		}
+		if (strcmp(name, "QUIT") == 0)
+			return cmd_quit(client, args);
 		break;
 	case 'R':
-		if (strcmp(name, "RETR") == 0) {
-			cmd_retr(client, args);
-			return;
-		}
-		if (strcmp(name, "RSET") == 0) {
-			cmd_rset(client, args);
-			return;
-		}
+		if (strcmp(name, "RETR") == 0)
+			return cmd_retr(client, args);
+		if (strcmp(name, "RSET") == 0)
+			return cmd_rset(client, args);
 		break;
 	case 'S':
-		if (strcmp(name, "STAT") == 0) {
-			cmd_stat(client, args);
-			return;
-		}
+		if (strcmp(name, "STAT") == 0)
+			return cmd_stat(client, args);
 		break;
 	case 'T':
-		if (strcmp(name, "TOP") == 0) {
-			cmd_top(client, args);
-			return;
-		}
+		if (strcmp(name, "TOP") == 0)
+			return cmd_top(client, args);
 		break;
 	case 'U':
-		if (strcmp(name, "UIDL") == 0) {
-			cmd_uidl(client, args);
-			return;
-		}
+		if (strcmp(name, "UIDL") == 0)
+			return cmd_uidl(client, args);
 		break;
 	}
 
 	client_send_line(client, "-ERR Unknown command: %s", name);
+	return FALSE;
 }
--- a/src/pop3/commands.h	Thu Jan 30 19:59:31 2003 +0200
+++ b/src/pop3/commands.h	Thu Jan 30 20:05:33 2003 +0200
@@ -1,7 +1,7 @@
 #ifndef __COMMANDS_H
 #define __COMMANDS_H
 
-void client_command_execute(struct client *client,
-			    const char *name, const char *args);
+int client_command_execute(struct client *client,
+			   const char *name, const char *args);
 
 #endif