#imap_client_workarounds =
}
-# Dictionary containing URLAUTH data.
-#imap_urlauth_dict =
-
# Host allowed in URLAUTH URLs sent by client. "*" allows all.
#imap_urlauth_host =
static const struct setting_define imap_urlauth_worker_setting_defines[] = {
DEF(SET_BOOL, verbose_proctitle),
- DEF(SET_STR_VARS, imap_urlauth_dict),
DEF(SET_STR, imap_urlauth_host),
DEF(SET_UINT, imap_urlauth_port),
const struct imap_urlauth_worker_settings imap_urlauth_worker_default_settings = {
.verbose_proctitle = FALSE,
- .imap_urlauth_dict = "",
.imap_urlauth_host = "",
.imap_urlauth_port = 143
};
bool verbose_proctitle;
/* imap_urlauth: */
- const char *imap_urlauth_dict;
const char *imap_urlauth_host;
unsigned int imap_urlauth_port;
};
}
/* initialize urlauth context */
- if (*set->imap_urlauth_host == '\0' ||
- *set->imap_urlauth_dict == '\0') {
- i_error("%s setting is not configured for user %s",
- *set->imap_urlauth_host == '\0' ?
- "imap_urlauth_host" : "imap_urlauth_dict",
+ if (*set->imap_urlauth_host == '\0') {
+ i_error("imap_urlauth_host setting is not configured for user %s",
mail_user->username);
client_send_line(client, "NO");
client_abort(client, "Session aborted: URLAUTH not configured");
}
memset(&config, 0, sizeof(config));
- config.dict_uri = set->imap_urlauth_dict;
config.url_host = set->imap_urlauth_host;
config.url_port = set->imap_urlauth_port;
config.access_user = client->access_user;
config.access_applications =
(const void *)array_get(&client->access_apps, &count);
- if (imap_urlauth_init(client->mail_user, &config, &client->urlauth_ctx) < 0) {
- client_send_line(client, "NO");
- client_abort(client,
- "Session aborted: Failed to init URLAUTH context");
- return 0;
- }
-
+ client->urlauth_ctx = imap_urlauth_init(client->mail_user, &config);
if (client->debug) {
i_debug("Providing access to user account `%s' on behalf of `%s'",
mail_user->username, client->access_user);
client_destroy(client, "Disconnected for inactivity");
}
-static int client_init_urlauth(struct client *client)
+static void client_init_urlauth(struct client *client)
{
struct imap_urlauth_config config;
memset(&config, 0, sizeof(config));
- config.dict_uri = client->set->imap_urlauth_dict;
config.url_host = client->set->imap_urlauth_host;
config.url_port = client->set->imap_urlauth_port;
config.socket_path = t_strconcat(client->user->set->base_dir,
config.access_anonymous = client->user->anonymous;
config.access_user = client->user->username;
- return imap_urlauth_init(client->user, &config, &client->urlauth_ctx);
+ client->urlauth_ctx = imap_urlauth_init(client->user, &config);
}
struct client *client_create(int fd_in, int fd_out, const char *session_id,
str_append(client->capability_string, " NOTIFY");
}
- if (*set->imap_urlauth_host != '\0' && *set->imap_urlauth_dict != '\0') {
- if (client_init_urlauth(client) == 0 &&
- !explicit_capability) {
- /* Enable URLAUTH capability only when dict is
- configured correctly */
+ if (*set->imap_urlauth_host != '\0' &&
+ *mail_set->mail_attribute_dict != '\0') {
+ /* Enable URLAUTH capability only when dict is
+ configured correctly */
+ client_init_urlauth(client);
+ if (!explicit_capability)
str_append(client->capability_string, " URLAUTH URLAUTH=BINARY");
- }
}
ident = mail_user_get_anvil_userip_ident(client->user);
DEF(SET_STR, imap_id_send),
DEF(SET_STR, imap_id_log),
- DEF(SET_STR_VARS, imap_urlauth_dict),
DEF(SET_STR, imap_urlauth_host),
DEF(SET_UINT, imap_urlauth_port),
.imap_id_send = "",
.imap_id_log = "",
- .imap_urlauth_dict = "",
.imap_urlauth_host = "",
.imap_urlauth_port = 143
};
const char *imap_id_log;
/* imap urlauth: */
- const char *imap_urlauth_dict;
const char *imap_urlauth_host;
unsigned int imap_urlauth_port;
#include "buffer.h"
#include "hex-binary.h"
#include "randgen.h"
-#include "dict.h"
#include "mail-user.h"
#include "mail-storage.h"
+#include "mailbox-list-iter.h"
#include "imap-urlauth-private.h"
#include "imap-urlauth-backend.h"
-#define IMAP_URLAUTH_PATH DICT_PATH_PRIVATE"imap-urlauth/"
+#define IMAP_URLAUTH_KEY "imap-urlauth"
-struct imap_urlauth_backend {
- struct mail_user *user;
- struct dict *dict;
-};
-
-int imap_urlauth_backend_create(struct mail_user *user, const char *dict_uri,
- struct imap_urlauth_backend **backend_r)
-{
- struct imap_urlauth_backend *backend;
- struct dict *dict;
- const char *error;
-
- if (user->mail_debug)
- i_debug("imap-urlauth backend: opening backend dict URI %s", dict_uri);
-
- if (dict_init(dict_uri, DICT_DATA_TYPE_STRING,
- user->username, user->set->base_dir, &dict, &error) < 0) {
- i_error("imap_urlauth_dict: Failed to initialize dict: %s", error);
- return -1;
- }
-
- backend = i_new(struct imap_urlauth_backend, 1);
- backend->user = user;
- backend->dict = dict;
-
- random_init();
- *backend_r = backend;
- return 0;
-}
-
-void imap_urlauth_backend_destroy(struct imap_urlauth_backend **_backend)
-{
- struct imap_urlauth_backend *backend = *_backend;
-
- *_backend = NULL;
-
- if (backend->dict != NULL) {
- (void)dict_wait(backend->dict);
- dict_deinit(&backend->dict);
- }
- i_free(backend);
- random_deinit();
-}
-
-static int
-imap_urlauth_backend_set_key(struct imap_urlauth_backend *backend,
- const char *path, const char *mailbox_key)
-{
- struct dict_transaction_context *dtrans;
-
- dtrans = dict_transaction_begin(backend->dict);
- dict_set(dtrans, path, mailbox_key);
- return dict_transaction_commit(&dtrans) < 0 ? -1 : 1;
-}
-
-static int
-imap_urlauth_backend_reset_key(struct imap_urlauth_backend *backend,
- const char *path)
-{
- struct dict_transaction_context *dtrans;
-
- dtrans = dict_transaction_begin(backend->dict);
- dict_unset(dtrans, path);
- return dict_transaction_commit(&dtrans) < 0 ? -1 : 1;
-}
-
-static int
-imap_urlauth_backend_get_key(struct imap_urlauth_backend *backend,
- const char *path, const char **mailbox_key_r)
-{
- return dict_lookup(backend->dict, pool_datastack_create(), path,
- mailbox_key_r);
-}
-
-int imap_urlauth_backend_get_mailbox_key(struct imap_urlauth_backend *backend,
- struct mailbox *box, bool create,
+int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create,
unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
const char **error_r,
enum mail_error *error_code_r)
{
- const char *path, *mailbox_key_hex = NULL;
- struct mailbox_metadata metadata;
- const char *mailbox = mailbox_get_vname(box);
+ struct mail_user *user = mail_storage_get_user(mailbox_get_storage(box));
+ const char *mailbox_key_hex = NULL;
buffer_t key_buf;
int ret;
*error_r = "Internal server error";
*error_code_r = MAIL_ERROR_TEMP;
- if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) {
- *error_r = mailbox_get_last_error(box, error_code_r);
- return -1;
- }
- mailbox = guid_128_to_string(metadata.guid);
-
- path = t_strconcat(IMAP_URLAUTH_PATH, dict_escape_string(mailbox), NULL);
- if ((ret = imap_urlauth_backend_get_key(backend, path,
- &mailbox_key_hex)) < 0)
+ ret = mailbox_attribute_get(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+ IMAP_URLAUTH_KEY, &mailbox_key_hex);
+ if (ret < 0)
return -1;
- if (backend->user->mail_debug) {
- i_debug("imap-urlauth backend: %skey found for mailbox %s at %s",
- (ret > 0 ? "" : "no "), mailbox, path);
+ if (user->mail_debug) {
+ i_debug("imap-urlauth: %skey found for mailbox %s",
+ (ret > 0 ? "" : "no "), mailbox_get_vname(box));
}
if (ret == 0) {
random_fill(mailbox_key_r, IMAP_URLAUTH_KEY_LEN);
mailbox_key_hex = binary_to_hex(mailbox_key_r,
IMAP_URLAUTH_KEY_LEN);
- if ((ret = imap_urlauth_backend_set_key(backend, path,
- mailbox_key_hex)) < 0)
+ ret = mailbox_attribute_set(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+ IMAP_URLAUTH_KEY, mailbox_key_hex);
+ if (ret < 0)
return -1;
- if (backend->user->mail_debug) {
- i_debug("imap-urlauth backend: created key for mailbox %s at %s",
- mailbox, path);
+ if (user->mail_debug) {
+ i_debug("imap-urlauth: created key for mailbox %s",
+ mailbox_get_vname(box));
}
} else {
/* read existing key */
if (strlen(mailbox_key_hex) != 2*IMAP_URLAUTH_KEY_LEN ||
hex_to_binary(mailbox_key_hex, &key_buf) < 0 ||
key_buf.used != IMAP_URLAUTH_KEY_LEN) {
- i_error("imap-urlauth backend: key found for mailbox %s at %s is invalid",
- mailbox, path);
+ i_error("imap-urlauth: key found for mailbox %s is invalid",
+ mailbox_get_vname(box));
return -1;
}
memcpy(mailbox_key_r, key_buf.data, IMAP_URLAUTH_KEY_LEN);
return 1;
}
-int imap_urlauth_backend_reset_mailbox_key(struct imap_urlauth_backend *backend,
- struct mailbox *box)
+int imap_urlauth_backend_reset_mailbox_key(struct mailbox *box)
{
- const char *path, *mailbox;
- struct mailbox_metadata metadata;
-
- if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0)
- return 0;
- mailbox = guid_128_to_string(metadata.guid);
-
- path = t_strconcat(IMAP_URLAUTH_PATH, dict_escape_string(mailbox), NULL);
- return imap_urlauth_backend_reset_key(backend, path) < 0 ? -1 : 1;
+ return mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+ IMAP_URLAUTH_KEY) < 0 ? -1 : 1;
}
-int imap_urlauth_backend_reset_all_keys(struct imap_urlauth_backend *backend)
+int imap_urlauth_backend_reset_all_keys(struct mail_user *user)
{
- struct dict_transaction_context *dtrans;
- struct dict_iterate_context *diter;
- const char *path, *value;
- int ret = 1;
-
- dtrans = dict_transaction_begin(backend->dict);
- diter = dict_iterate_init(backend->dict, IMAP_URLAUTH_PATH,
- DICT_ITERATE_FLAG_RECURSE);
- while (dict_iterate(diter, &path, &value))
- dict_unset(dtrans, path);
-
- if (dict_iterate_deinit(&diter) < 0)
- ret = -1;
- if (dict_transaction_commit(&dtrans) < 0)
+ const char *const patterns[] = { "*", NULL };
+ struct mailbox_list_iterate_context *iter;
+ const struct mailbox_info *info;
+ struct mailbox *box;
+ int ret = 0;
+
+ iter = mailbox_list_iter_init_namespaces(user->namespaces, patterns,
+ MAIL_NAMESPACE_TYPE_MASK_ALL,
+ MAILBOX_LIST_ITER_NO_AUTO_BOXES |
+ MAILBOX_LIST_ITER_SKIP_ALIASES |
+ MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
+ while ((info = mailbox_list_iter_next(iter)) != NULL) {
+ box = mailbox_alloc(info->ns->list, info->vname, 0);
+ if (mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+ IMAP_URLAUTH_KEY) < 0)
+ ret = -1;
+ mailbox_free(&box);
+ }
+ if (mailbox_list_iter_deinit(&iter) < 0)
ret = -1;
return ret;
}
struct imap_urlauth_backend;
-int imap_urlauth_backend_create(struct mail_user *user, const char *dict_uri,
- struct imap_urlauth_backend **backend_r);
-void imap_urlauth_backend_destroy(struct imap_urlauth_backend **backend);
-
-int imap_urlauth_backend_get_mailbox_key(struct imap_urlauth_backend *backend,
- struct mailbox *box, bool create,
+int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create,
unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
const char **error_r,
enum mail_error *error_code_r);
-int imap_urlauth_backend_reset_mailbox_key(struct imap_urlauth_backend *backend,
- struct mailbox *box);
-int imap_urlauth_backend_reset_all_keys(struct imap_urlauth_backend *backend);
+int imap_urlauth_backend_reset_mailbox_key(struct mailbox *box);
+int imap_urlauth_backend_reset_all_keys(struct mail_user *user);
#endif
struct imap_urlauth_context {
struct mail_user *user;
struct imap_urlauth_connection *conn;
- struct imap_urlauth_backend *backend;
char *url_host;
unsigned int url_port;
#define URL_HOST_ALLOW_ANY "*"
-int imap_urlauth_init(struct mail_user *user,
- const struct imap_urlauth_config *config,
- struct imap_urlauth_context **ctx_r)
+struct imap_urlauth_context *
+imap_urlauth_init(struct mail_user *user,
+ const struct imap_urlauth_config *config)
{
- struct imap_urlauth_backend *backend;
struct imap_urlauth_context *uctx;
unsigned int timeout;
i_assert(*config->url_host != '\0');
- i_assert(*config->dict_uri != '\0');
- if (imap_urlauth_backend_create(user, config->dict_uri, &backend) < 0)
- return -1;
+ random_init();
uctx = i_new(struct imap_urlauth_context, 1);
uctx->user = user;
- uctx->backend = backend;
uctx->url_host = i_strdup(config->url_host);
uctx->url_port = config->url_port;
uctx->conn = imap_urlauth_connection_init(config->socket_path,
user, config->session_id, timeout);
}
- *ctx_r = uctx;
- return 0;
+ return uctx;
}
void imap_urlauth_deinit(struct imap_urlauth_context **_uctx)
{
struct imap_urlauth_context *uctx = *_uctx;
- if (uctx->backend != NULL)
- imap_urlauth_backend_destroy(&uctx->backend);
+ *_uctx = NULL;
+
if (uctx->conn != NULL)
imap_urlauth_connection_deinit(&uctx->conn);
i_free(uctx->url_host);
i_free(uctx->access_user);
i_free(uctx->access_applications);
i_free(uctx);
- *_uctx = uctx;
+
+ random_deinit();
}
static const unsigned char *
box = imap_msgpart_url_get_mailbox(mpurl);
/* obtain mailbox key */
- ret = imap_urlauth_backend_get_mailbox_key(uctx->backend, box, TRUE,
- mailbox_key, error_r,
- &error_code);
+ ret = imap_urlauth_backend_get_mailbox_key(box, TRUE, mailbox_key,
+ error_r, &error_code);
if (ret < 0) {
imap_msgpart_url_free(&mpurl);
return ret;
}
/* obtain mailbox key */
- ret = imap_urlauth_backend_get_mailbox_key(uctx->backend, box, FALSE,
- mailbox_key, error_r,
- error_code_r);
+ ret = imap_urlauth_backend_get_mailbox_key(box, FALSE, mailbox_key,
+ error_r, error_code_r);
if (ret < 0) {
imap_msgpart_url_free(&mpurl);
return -1;
error_code_r, error_r);
}
-int imap_urlauth_reset_mailbox_key(struct imap_urlauth_context *uctx,
+int imap_urlauth_reset_mailbox_key(struct imap_urlauth_context *uctx ATTR_UNUSED,
struct mailbox *box)
{
- return imap_urlauth_backend_reset_mailbox_key(uctx->backend, box);
+ return imap_urlauth_backend_reset_mailbox_key(box);
}
int imap_urlauth_reset_all_keys(struct imap_urlauth_context *uctx)
{
- return imap_urlauth_backend_reset_all_keys(uctx->backend);
+ return imap_urlauth_backend_reset_all_keys(uctx->user);
}
struct imap_urlauth_context;
struct imap_urlauth_config {
- const char *dict_uri;
-
const char *url_host;
unsigned int url_port;
bool access_anonymous;
};
-int imap_urlauth_init(struct mail_user *user,
- const struct imap_urlauth_config *config,
- struct imap_urlauth_context **ctx_r);
+struct imap_urlauth_context *
+imap_urlauth_init(struct mail_user *user,
+ const struct imap_urlauth_config *config);
void imap_urlauth_deinit(struct imap_urlauth_context **_uctx);
int imap_urlauth_generate(struct imap_urlauth_context *uctx,