1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
5
#include "hex-binary.h"
8
#include "mail-storage.h"
9
#include "mailbox-list-iter.h"
10
#include "imap-urlauth-private.h"
11
#include "imap-urlauth-backend.h"
13
#define IMAP_URLAUTH_KEY MAILBOX_ATTRIBUTE_PREFIX_DOVECOT"imap-urlauth"
16
imap_urlauth_backend_trans_get_mailbox_key(struct mailbox_transaction_context *trans,
18
unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
20
enum mail_error *error_code_r)
22
struct mailbox *box = mailbox_transaction_get_mailbox(trans);
23
struct mail_user *user = mail_storage_get_user(mailbox_get_storage(box));
24
struct mail_attribute_value urlauth_key;
25
const char *mailbox_key_hex = NULL;
29
*error_r = "Internal server error";
30
*error_code_r = MAIL_ERROR_TEMP;
32
ret = mailbox_attribute_get(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE,
33
IMAP_URLAUTH_KEY, &urlauth_key);
37
if (user->mail_debug) {
38
i_debug("imap-urlauth: %skey found for mailbox %s",
39
(ret > 0 ? "" : "no "), mailbox_get_vname(box));
47
random_fill(mailbox_key_r, IMAP_URLAUTH_KEY_LEN);
48
mailbox_key_hex = binary_to_hex(mailbox_key_r,
49
IMAP_URLAUTH_KEY_LEN);
50
memset(&urlauth_key, 0, sizeof(urlauth_key));
51
urlauth_key.value = mailbox_key_hex;
52
ret = mailbox_attribute_set(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE,
53
IMAP_URLAUTH_KEY, &urlauth_key);
56
if (user->mail_debug) {
57
i_debug("imap-urlauth: created key for mailbox %s",
58
mailbox_get_vname(box));
61
/* read existing key */
62
buffer_create_from_data(&key_buf, mailbox_key_r,
63
IMAP_URLAUTH_KEY_LEN);
64
mailbox_key_hex = urlauth_key.value;
65
if (strlen(mailbox_key_hex) != 2*IMAP_URLAUTH_KEY_LEN ||
66
hex_to_binary(mailbox_key_hex, &key_buf) < 0 ||
67
key_buf.used != IMAP_URLAUTH_KEY_LEN) {
68
i_error("imap-urlauth: key found for mailbox %s is invalid",
69
mailbox_get_vname(box));
76
int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create,
77
unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
79
enum mail_error *error_code_r)
81
struct mailbox_transaction_context *t;
84
t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
85
ret = imap_urlauth_backend_trans_get_mailbox_key(t, create, mailbox_key_r, error_r, error_code_r);
86
if (mailbox_transaction_commit(&t) < 0)
91
int imap_urlauth_backend_reset_mailbox_key(struct mailbox *box)
93
struct mailbox_transaction_context *t;
96
t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
97
ret = mailbox_attribute_unset(t, MAIL_ATTRIBUTE_TYPE_PRIVATE,
99
if (mailbox_transaction_commit(&t) < 0)
104
static int imap_urlauth_backend_mailbox_reset_key(struct mailbox *box)
107
enum mail_error error;
109
if (mailbox_open(box) < 0) {
110
errstr = mailbox_get_last_error(box, &error);
111
if (error == MAIL_ERROR_NOTFOUND || error == MAIL_ERROR_PERM)
113
i_error("urlauth key reset: Couldn't open mailbox %s: %s",
114
mailbox_get_vname(box), errstr);
117
return imap_urlauth_backend_reset_mailbox_key(box);
120
int imap_urlauth_backend_reset_all_keys(struct mail_user *user)
122
const char *const patterns[] = { "*", NULL };
123
struct mailbox_list_iterate_context *iter;
124
const struct mailbox_info *info;
128
iter = mailbox_list_iter_init_namespaces(user->namespaces, patterns,
129
MAIL_NAMESPACE_TYPE_MASK_ALL,
130
MAILBOX_LIST_ITER_NO_AUTO_BOXES |
131
MAILBOX_LIST_ITER_SKIP_ALIASES |
132
MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
133
while ((info = mailbox_list_iter_next(iter)) != NULL) {
134
box = mailbox_alloc(info->ns->list, info->vname, 0);
135
if (imap_urlauth_backend_mailbox_reset_key(box) < 0)
139
if (mailbox_list_iter_deinit(&iter) < 0)