#include "auth-client.h"
#include "ssl-proxy.h"
#include "imap-proxy.h"
+#include "imap-login-commands.h"
#include "imap-login-settings.h"
#if LOGIN_MAX_INBUF_SIZE < 1024+2
return str_c(cap_str);
}
-static int cmd_capability(struct imap_client *imap_client)
+static int cmd_capability(struct imap_client *imap_client,
+ const struct imap_arg *args ATTR_UNUSED)
{
struct client *client = &imap_client->common;
return 1;
}
-static int cmd_starttls(struct imap_client *client)
+static int cmd_starttls(struct imap_client *client,
+ const struct imap_arg *args ATTR_UNUSED)
{
client_cmd_starttls(&client->common);
return 1;
}
}
-static int cmd_noop(struct imap_client *client)
+static int cmd_noop(struct imap_client *client,
+ const struct imap_arg *args ATTR_UNUSED)
{
client_send_reply(&client->common, IMAP_CMD_REPLY_OK,
"NOOP completed.");
return 1;
}
-static int cmd_logout(struct imap_client *client)
+static int cmd_logout(struct imap_client *client,
+ const struct imap_arg *args ATTR_UNUSED)
{
client_send_reply(&client->common, IMAP_CMD_REPLY_BYE, "Logging out");
client_send_reply(&client->common, IMAP_CMD_REPLY_OK,
return 1;
}
-static int cmd_enable(struct imap_client *client)
+static int cmd_enable(struct imap_client *client,
+ const struct imap_arg *args ATTR_UNUSED)
{
client_send_raw(&client->common, "* ENABLED\r\n");
client_send_reply(&client->common, IMAP_CMD_REPLY_OK,
static int client_command_execute(struct imap_client *client, const char *cmd,
const struct imap_arg *args)
{
- cmd = t_str_ucase(cmd);
- if (strcmp(cmd, "LOGIN") == 0)
- return cmd_login(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);
- if (strcmp(cmd, "ENABLE") == 0)
- return cmd_enable(client);
+ struct imap_login_command *login_cmd;
- return -2;
+ login_cmd = imap_login_command_lookup(cmd);
+ if (login_cmd == NULL)
+ return -2;
+ return login_cmd->func(client, args);
}
static bool imap_is_valid_tag(const char *tag)
login_set_roots = imap_login_setting_roots;
}
+static const struct imap_login_command imap_login_commands[] = {
+ { "LOGIN", cmd_login },
+ { "CAPABILITY", cmd_capability },
+ { "STARTTLS", cmd_starttls },
+ { "NOOP", cmd_noop },
+ { "LOGOUT", cmd_logout },
+ { "ENABLE", cmd_enable }
+};
+
static void imap_login_init(void)
{
+ imap_login_commands_init();
+ imap_login_commands_register(imap_login_commands,
+ N_ELEMENTS(imap_login_commands));
}
static void imap_login_deinit(void)
{
clients_destroy_all();
+ imap_login_commands_deinit();
}
static struct client_vfuncs imap_client_vfuncs = {
--- /dev/null
+/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */
+
+#include "login-common.h"
+#include "array.h"
+#include "imap-login-commands.h"
+
+static ARRAY(struct imap_login_command *) imap_login_commands;
+static pool_t imap_login_commands_pool;
+
+struct imap_login_command *imap_login_command_lookup(const char *name)
+{
+ struct imap_login_command *const *cmdp;
+
+ array_foreach(&imap_login_commands, cmdp) {
+ if (strcasecmp((*cmdp)->name, name) == 0)
+ return *cmdp;
+ }
+ return NULL;
+}
+
+void imap_login_commands_register(const struct imap_login_command *commands,
+ unsigned int count)
+{
+ struct imap_login_command *cmd;
+ unsigned int i;
+
+ for (i = 0; i < count; i++) {
+ cmd = p_new(imap_login_commands_pool, struct imap_login_command, 1);
+ cmd->name = p_strdup(imap_login_commands_pool, commands[i].name);
+ cmd->func = commands[i].func;
+ array_append(&imap_login_commands, &cmd, 1);
+ }
+}
+
+static void
+imap_login_command_unregister(const struct imap_login_command *unreg_cmd)
+{
+ struct imap_login_command *const *cmdp;
+
+ array_foreach(&imap_login_commands, cmdp) {
+ if ((*cmdp)->func == unreg_cmd->func &&
+ strcmp((*cmdp)->name, unreg_cmd->name) == 0) {
+ array_delete(&imap_login_commands,
+ array_foreach_idx(&imap_login_commands, cmdp), 1);
+ return;
+ }
+ }
+ i_panic("imap_login_command_unregister: Command '%s' not found", unreg_cmd->name);
+}
+
+void imap_login_commands_unregister(const struct imap_login_command *commands,
+ unsigned int count)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ imap_login_command_unregister(&commands[i]);
+}
+
+void imap_login_commands_init(void)
+{
+ imap_login_commands_pool =
+ pool_alloconly_create("imap login commands", 128);
+ p_array_init(&imap_login_commands, imap_login_commands_pool, 8);
+}
+
+void imap_login_commands_deinit(void)
+{
+ pool_unref(&imap_login_commands_pool);
+}