import dovecot-2.3.16-2.el8
This commit is contained in:
parent
56c8e8bb5b
commit
4bb6def194
@ -1,2 +1,2 @@
|
||||
b9c7290dad1ac3bc1ead11359812a137a3d173f7 SOURCES/dovecot-2.3-pigeonhole-0.5.8.tar.gz
|
||||
65b93f7fd53705b3c97f9eee141a76c5f4f3a624 SOURCES/dovecot-2.3.8.tar.gz
|
||||
4673c244c6ea73ee3da0bb61d0206a1fe3d0be0e SOURCES/dovecot-2.3-pigeonhole-0.5.16.tar.gz
|
||||
b5c598ae8b9901bfabdf2c93271f57cde0bde73e SOURCES/dovecot-2.3.16.tar.gz
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
SOURCES/dovecot-2.3-pigeonhole-0.5.8.tar.gz
|
||||
SOURCES/dovecot-2.3.8.tar.gz
|
||||
SOURCES/dovecot-2.3-pigeonhole-0.5.16.tar.gz
|
||||
SOURCES/dovecot-2.3.16.tar.gz
|
||||
|
@ -1,11 +1,11 @@
|
||||
diff -up dovecot-2.3.0.1/dovecot.service.in.waitonline dovecot-2.3.0.1/dovecot.service.in
|
||||
--- dovecot-2.3.0.1/dovecot.service.in.waitonline 2018-03-01 10:35:39.888371078 +0100
|
||||
+++ dovecot-2.3.0.1/dovecot.service.in 2018-03-01 10:36:29.738784661 +0100
|
||||
@@ -12,6 +12,7 @@ After=local-fs.target network-online.tar
|
||||
diff -up dovecot-2.3.15/dovecot.service.in.waitonline dovecot-2.3.15/dovecot.service.in
|
||||
--- dovecot-2.3.15/dovecot.service.in.waitonline 2021-06-21 20:19:19.560494654 +0200
|
||||
+++ dovecot-2.3.15/dovecot.service.in 2021-06-21 20:21:17.443066248 +0200
|
||||
@@ -15,6 +15,7 @@ After=local-fs.target network-online.tar
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Type=@systemdservicetype@
|
||||
+ExecStartPre=/usr/libexec/dovecot/prestartscript
|
||||
ExecStart=@sbindir@/dovecot -F
|
||||
PIDFile=@rundir@/master.pid
|
||||
ExecReload=@bindir@/doveadm reload
|
||||
ExecStop=@bindir@/doveadm stop
|
||||
|
@ -1,6 +1,6 @@
|
||||
diff -up dovecot-2.3.0.1/dovecot-init.service.initbysystemd dovecot-2.3.0.1/dovecot-init.service
|
||||
--- dovecot-2.3.0.1/dovecot-init.service.initbysystemd 2018-03-01 10:38:22.059716008 +0100
|
||||
+++ dovecot-2.3.0.1/dovecot-init.service 2018-03-01 10:38:22.059716008 +0100
|
||||
diff -up dovecot-2.3.15/dovecot-init.service.initbysystemd dovecot-2.3.15/dovecot-init.service
|
||||
--- dovecot-2.3.15/dovecot-init.service.initbysystemd 2021-06-21 20:21:49.250680889 +0200
|
||||
+++ dovecot-2.3.15/dovecot-init.service 2021-06-21 20:21:49.250680889 +0200
|
||||
@@ -0,0 +1,13 @@
|
||||
+[Unit]
|
||||
+Description=One-time Dovecot init service
|
||||
@ -15,32 +15,37 @@ diff -up dovecot-2.3.0.1/dovecot-init.service.initbysystemd dovecot-2.3.0.1/dove
|
||||
+ SSLDIR=/etc/pki/dovecot/ OPENSSLCONFIG=/etc/pki/dovecot/dovecot-openssl.cnf /usr/libexec/dovecot/mkcert.sh /dev/null 2>&1;\
|
||||
+fi'
|
||||
+
|
||||
diff -up dovecot-2.3.0.1/dovecot.service.in.initbysystemd dovecot-2.3.0.1/dovecot.service.in
|
||||
--- dovecot-2.3.0.1/dovecot.service.in.initbysystemd 2018-03-01 10:38:22.060716016 +0100
|
||||
+++ dovecot-2.3.0.1/dovecot.service.in 2018-03-01 10:40:45.524901319 +0100
|
||||
@@ -8,7 +8,8 @@
|
||||
diff -up dovecot-2.3.15/dovecot.service.in.initbysystemd dovecot-2.3.15/dovecot.service.in
|
||||
--- dovecot-2.3.15/dovecot.service.in.initbysystemd 2021-06-21 20:21:49.250680889 +0200
|
||||
+++ dovecot-2.3.15/dovecot.service.in 2021-06-21 20:22:46.935981920 +0200
|
||||
@@ -11,7 +11,8 @@
|
||||
Description=Dovecot IMAP/POP3 email server
|
||||
Documentation=man:dovecot(1)
|
||||
Documentation=http://wiki2.dovecot.org/
|
||||
Documentation=https://doc.dovecot.org/
|
||||
-After=local-fs.target network-online.target
|
||||
+After=local-fs.target network-online.target dovecot-init.service
|
||||
+Requires=dovecot-init.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
diff -up dovecot-2.3.0.1/Makefile.am.initbysystemd dovecot-2.3.0.1/Makefile.am
|
||||
--- dovecot-2.3.0.1/Makefile.am.initbysystemd 2018-02-28 15:28:57.000000000 +0100
|
||||
+++ dovecot-2.3.0.1/Makefile.am 2018-03-01 10:38:22.060716016 +0100
|
||||
@@ -63,9 +63,10 @@ if HAVE_SYSTEMD
|
||||
Type=@systemdservicetype@
|
||||
diff -up dovecot-2.3.15/Makefile.am.initbysystemd dovecot-2.3.15/Makefile.am
|
||||
--- dovecot-2.3.15/Makefile.am.initbysystemd 2021-06-21 20:21:49.250680889 +0200
|
||||
+++ dovecot-2.3.15/Makefile.am 2021-06-21 20:24:26.676765849 +0200
|
||||
@@ -21,6 +21,7 @@ EXTRA_DIST = \
|
||||
run-test-valgrind.supp \
|
||||
dovecot.service.in \
|
||||
dovecot.socket \
|
||||
+ dovecot-init.service \
|
||||
$(conf_DATA)
|
||||
|
||||
noinst_DATA = dovecot-config
|
||||
@@ -69,7 +70,8 @@ dovecot-config: dovecot-config.in Makefi
|
||||
if WANT_SYSTEMD
|
||||
systemdsystemunit_DATA = \
|
||||
dovecot.socket \
|
||||
- dovecot.service
|
||||
+ dovecot.service \
|
||||
+ dovecot-init.service
|
||||
else
|
||||
-EXTRA_DIST += dovecot.socket dovecot.service.in
|
||||
+EXTRA_DIST += dovecot.socket dovecot.service.in dovecot-init.service
|
||||
endif
|
||||
|
||||
install-exec-hook:
|
||||
|
@ -1,9 +1,9 @@
|
||||
diff -up dovecot-2.2.36/doc/dovecot-openssl.cnf.bigkey dovecot-2.2.36/doc/dovecot-openssl.cnf
|
||||
--- dovecot-2.2.36/doc/dovecot-openssl.cnf.bigkey 2017-06-23 13:18:28.000000000 +0200
|
||||
+++ dovecot-2.2.36/doc/dovecot-openssl.cnf 2018-10-16 17:15:35.836205498 +0200
|
||||
diff -up dovecot-2.3.15/doc/dovecot-openssl.cnf.bigkey dovecot-2.3.15/doc/dovecot-openssl.cnf
|
||||
--- dovecot-2.3.15/doc/dovecot-openssl.cnf.bigkey 2021-06-21 20:24:51.913456628 +0200
|
||||
+++ dovecot-2.3.15/doc/dovecot-openssl.cnf 2021-06-21 20:25:36.352912123 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
[ req ]
|
||||
-default_bits = 1024
|
||||
-default_bits = 2048
|
||||
+default_bits = 3072
|
||||
encrypt_key = yes
|
||||
distinguished_name = req_dn
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,121 +0,0 @@
|
||||
diff -up dovecot-2.3.8/src/lib-smtp/smtp-address.c.smtppre dovecot-2.3.8/src/lib-smtp/smtp-address.c
|
||||
--- dovecot-2.3.8/src/lib-smtp/smtp-address.c.smtppre 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib-smtp/smtp-address.c 2020-05-29 19:11:19.340621409 +0200
|
||||
@@ -467,7 +467,7 @@ void smtp_address_detail_parse(pool_t po
|
||||
*detail_r = p+1;
|
||||
}
|
||||
|
||||
- if (address->domain == NULL)
|
||||
+ if (address->domain == NULL || *address->domain == '\0')
|
||||
*username_r = user;
|
||||
else if (strchr(user, '@') == NULL ) {
|
||||
/* username is just glued to the domain... no SMTP escaping */
|
||||
@@ -548,7 +548,7 @@ void smtp_address_write(string_t *out,
|
||||
if (quoted)
|
||||
str_append_c(out, '\"');
|
||||
|
||||
- if (address->domain == NULL)
|
||||
+ if (address->domain == NULL || *address->domain == '\0')
|
||||
return;
|
||||
|
||||
str_append_c(out, '@');
|
||||
@@ -587,8 +587,12 @@ void smtp_address_init(struct smtp_addre
|
||||
const char *localpart, const char *domain)
|
||||
{
|
||||
i_zero(address);
|
||||
+ if (localpart == NULL || *localpart == '\0')
|
||||
+ return;
|
||||
+
|
||||
address->localpart = localpart;
|
||||
- address->domain = (localpart == NULL ? NULL : domain);
|
||||
+ if (domain != NULL && *domain != '\0')
|
||||
+ address->domain = domain;
|
||||
}
|
||||
|
||||
int smtp_address_init_from_msg(struct smtp_address *address,
|
||||
@@ -597,7 +601,7 @@ int smtp_address_init_from_msg(struct sm
|
||||
const char *p;
|
||||
|
||||
i_zero(address);
|
||||
- if (msg_addr->mailbox == NULL)
|
||||
+ if (msg_addr->mailbox == NULL || *msg_addr->mailbox == '\0')
|
||||
return 0;
|
||||
|
||||
/* The message_address_parse() function allows UTF-8 codepoints in
|
||||
@@ -609,7 +613,8 @@ int smtp_address_init_from_msg(struct sm
|
||||
}
|
||||
|
||||
address->localpart = msg_addr->mailbox;
|
||||
- address->domain = msg_addr->domain;
|
||||
+ if (msg_addr->domain != NULL && *msg_addr->domain != '\0')
|
||||
+ address->domain = msg_addr->domain;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -617,8 +622,8 @@ struct smtp_address *
|
||||
smtp_address_clone(pool_t pool, const struct smtp_address *src)
|
||||
{
|
||||
struct smtp_address *new;
|
||||
- size_t size, lpsize, dsize = 0;
|
||||
- char *data, *localpart, *domain = NULL;
|
||||
+ size_t size, lpsize = 0, dsize = 0;
|
||||
+ char *data, *localpart = NULL, *domain = NULL;
|
||||
|
||||
if (smtp_address_isnull(src))
|
||||
return NULL;
|
||||
@@ -626,17 +631,21 @@ smtp_address_clone(pool_t pool, const st
|
||||
/* @UNSAFE */
|
||||
|
||||
size = sizeof(struct smtp_address);
|
||||
- lpsize = strlen(src->localpart) + 1;
|
||||
- size = MALLOC_ADD(size, lpsize);
|
||||
- if (src->domain != NULL) {
|
||||
+ if (src->localpart != NULL && *src->localpart != '\0') {
|
||||
+ lpsize = strlen(src->localpart) + 1;
|
||||
+ size = MALLOC_ADD(size, lpsize);
|
||||
+ }
|
||||
+ if (src->domain != NULL && *src->domain != '\0') {
|
||||
dsize = strlen(src->domain) + 1;
|
||||
size = MALLOC_ADD(size, dsize);
|
||||
}
|
||||
|
||||
data = p_malloc(pool, size);
|
||||
new = (struct smtp_address *)data;
|
||||
- localpart = PTR_OFFSET(data, sizeof(*new));
|
||||
- memcpy(localpart, src->localpart, lpsize);
|
||||
+ if (lpsize > 0) {
|
||||
+ localpart = PTR_OFFSET(data, sizeof(*new));
|
||||
+ memcpy(localpart, src->localpart, lpsize);
|
||||
+ }
|
||||
if (dsize > 0) {
|
||||
domain = PTR_OFFSET(data, sizeof(*new) + lpsize);
|
||||
memcpy(domain, src->domain, dsize);
|
||||
@@ -681,8 +690,8 @@ smtp_address_clone_temp(const struct smt
|
||||
return NULL;
|
||||
|
||||
new = t_new(struct smtp_address, 1);
|
||||
- new->localpart = t_strdup(src->localpart);
|
||||
- new->domain = t_strdup(src->domain);
|
||||
+ new->localpart = t_strdup_empty(src->localpart);
|
||||
+ new->domain = t_strdup_empty(src->domain);
|
||||
return new;
|
||||
}
|
||||
|
||||
@@ -720,7 +729,7 @@ smtp_address_add_detail(pool_t pool, con
|
||||
new_addr = p_new(pool, struct smtp_address, 1);
|
||||
new_addr->localpart = p_strconcat(pool,
|
||||
address->localpart, delim, detail, NULL);
|
||||
- new_addr->domain = p_strdup(pool, address->domain);
|
||||
+ new_addr->domain = p_strdup_empty(pool, address->domain);
|
||||
|
||||
return new_addr;
|
||||
}
|
||||
@@ -737,7 +746,7 @@ smtp_address_add_detail_temp(const struc
|
||||
new_addr = t_new(struct smtp_address, 1);
|
||||
new_addr->localpart = t_strconcat(
|
||||
address->localpart, delim, detail, NULL);
|
||||
- new_addr->domain = t_strdup(address->domain);
|
||||
+ new_addr->domain = t_strdup_empty(address->domain);
|
||||
|
||||
return new_addr;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
From 68165c8acc6d32a06f8dce2ef515c714c243ce4e Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 17 Aug 2020 18:33:20 +0300
|
||||
Subject: [PATCH] imap: Escape tag when sending it to imap-hibernate process
|
||||
|
||||
---
|
||||
src/imap/imap-client-hibernate.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/imap/imap-client-hibernate.c b/src/imap/imap-client-hibernate.c
|
||||
index f639d722cb..4ef323453c 100644
|
||||
--- a/src/imap/imap-client-hibernate.c
|
||||
+++ b/src/imap/imap-client-hibernate.c
|
||||
@@ -97,8 +97,10 @@ static void imap_hibernate_write_cmd(struct client *client, string_t *cmd,
|
||||
str_printfa(cmd, "\tuid=%s", dec2str(user->uid));
|
||||
if (user->gid != (gid_t)-1)
|
||||
str_printfa(cmd, "\tgid=%s", dec2str(user->gid));
|
||||
- if (tag != NULL)
|
||||
- str_printfa(cmd, "\ttag=%s", tag);
|
||||
+ if (tag != NULL) {
|
||||
+ str_append(cmd, "\ttag=");
|
||||
+ str_append_tabescaped(cmd, tag);
|
||||
+ }
|
||||
str_append(cmd, "\tstats=");
|
||||
str_append_tabescaped(cmd, client_stats(client));
|
||||
if (client->command_queue != NULL &&
|
@ -1,25 +0,0 @@
|
||||
From 73937b5fe7eb1dde76f30ef6b181c920bbbc4558 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 24 Aug 2020 16:58:16 +0300
|
||||
Subject: [PATCH] imap: Fix crash if imap-hibernate socket can't be connected
|
||||
to
|
||||
|
||||
The error was supposed to be returned to caller, not logged directly.
|
||||
---
|
||||
src/imap/imap-client-hibernate.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/imap/imap-client-hibernate.c b/src/imap/imap-client-hibernate.c
|
||||
index 4ef323453c..d3451b1bf6 100644
|
||||
--- a/src/imap/imap-client-hibernate.c
|
||||
+++ b/src/imap/imap-client-hibernate.c
|
||||
@@ -176,7 +176,8 @@ imap_hibernate_process_send(struct client *client, const buffer_t *state,
|
||||
"/"IMAP_HIBERNATE_SOCKET_NAME, NULL);
|
||||
fd = net_connect_unix_with_retries(path, 1000);
|
||||
if (fd == -1) {
|
||||
- i_error("net_connect_unix(%s) failed: %m", path);
|
||||
+ *error_r = t_strdup_printf(
|
||||
+ "net_connect_unix(%s) failed: %m", path);
|
||||
return -1;
|
||||
}
|
||||
net_set_nonblock(fd, FALSE);
|
@ -1,31 +0,0 @@
|
||||
From c7d158681fabdb3044bd213c332e489b46625a3b Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 24 Aug 2020 19:10:10 +0300
|
||||
Subject: [PATCH] imap: Delay initializing client IO until
|
||||
client_create_finish()
|
||||
|
||||
This helps writing unit tests.
|
||||
---
|
||||
src/imap/imap-client.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c
|
||||
index 95e57dbf53..c8ffeafc43 100644
|
||||
--- a/src/imap/imap-client.c
|
||||
+++ b/src/imap/imap-client.c
|
||||
@@ -143,7 +143,6 @@ struct client *client_create(int fd_in, int fd_out,
|
||||
o_stream_set_flush_callback(client->output, client_output, client);
|
||||
|
||||
p_array_init(&client->module_contexts, client->pool, 5);
|
||||
- client->io = io_add_istream(client->input, client_input, client);
|
||||
client->last_input = ioloop_time;
|
||||
client->to_idle = timeout_add(CLIENT_IDLE_TIMEOUT_MSECS,
|
||||
client_idle_timeout, client);
|
||||
@@ -228,6 +227,7 @@ int client_create_finish(struct client *client, const char **error_r)
|
||||
return -1;
|
||||
mail_namespaces_set_storage_callbacks(client->user->namespaces,
|
||||
&mail_storage_callbacks, client);
|
||||
+ client->io = io_add_istream(client->input, client_input, client);
|
||||
|
||||
client->v.init(client);
|
||||
return 0;
|
@ -1,105 +0,0 @@
|
||||
From 1a27cfa8e337b7e3298ba230059e766cdbc1123d Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 24 Aug 2020 19:10:43 +0300
|
||||
Subject: [PATCH] imap: imap_client_hibernate() - Return reason string on
|
||||
failure
|
||||
|
||||
This helps writing a unit test for it.
|
||||
---
|
||||
src/imap/cmd-idle.c | 3 ++-
|
||||
src/imap/imap-client-hibernate.c | 10 +++++++++-
|
||||
src/imap/imap-client.h | 5 +++--
|
||||
3 files changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/imap/cmd-idle.c b/src/imap/cmd-idle.c
|
||||
index 8a05582d03..2b31dc714e 100644
|
||||
--- a/src/imap/cmd-idle.c
|
||||
+++ b/src/imap/cmd-idle.c
|
||||
@@ -175,11 +175,12 @@ static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx)
|
||||
static void idle_hibernate_timeout(struct cmd_idle_context *ctx)
|
||||
{
|
||||
struct client *client = ctx->client;
|
||||
+ const char *reason;
|
||||
|
||||
i_assert(ctx->sync_ctx == NULL);
|
||||
i_assert(!ctx->sync_pending);
|
||||
|
||||
- if (imap_client_hibernate(&client)) {
|
||||
+ if (imap_client_hibernate(&client, &reason)) {
|
||||
/* client may be destroyed now */
|
||||
} else {
|
||||
/* failed - don't bother retrying */
|
||||
diff --git a/src/imap/imap-client-hibernate.c b/src/imap/imap-client-hibernate.c
|
||||
index d3451b1bf6..0709e4a244 100644
|
||||
--- a/src/imap/imap-client-hibernate.c
|
||||
+++ b/src/imap/imap-client-hibernate.c
|
||||
@@ -203,19 +203,23 @@ imap_hibernate_process_send(struct client *client, const buffer_t *state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-bool imap_client_hibernate(struct client **_client)
|
||||
+bool imap_client_hibernate(struct client **_client, const char **reason_r)
|
||||
{
|
||||
struct client *client = *_client;
|
||||
buffer_t *state;
|
||||
const char *error;
|
||||
int ret, fd_notify = -1, fd_hibernate = -1;
|
||||
|
||||
+ *reason_r = NULL;
|
||||
+
|
||||
if (client->fd_in != client->fd_out) {
|
||||
/* we won't try to hibernate stdio clients */
|
||||
+ *reason_r = "stdio clients can't be hibernated";
|
||||
return FALSE;
|
||||
}
|
||||
if (o_stream_get_buffer_used_size(client->output) > 0) {
|
||||
/* wait until we've sent the pending output to client */
|
||||
+ *reason_r = "output pending to client";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -233,11 +237,13 @@ bool imap_client_hibernate(struct client **_client)
|
||||
"Couldn't export state: %s (mailbox=%s)", error,
|
||||
client->mailbox == NULL ? "" :
|
||||
mailbox_get_vname(client->mailbox));
|
||||
+ *reason_r = error;
|
||||
} else if (ret == 0) {
|
||||
e_debug(client->event, "Couldn't hibernate imap client: "
|
||||
"Couldn't export state: %s (mailbox=%s)", error,
|
||||
client->mailbox == NULL ? "" :
|
||||
mailbox_get_vname(client->mailbox));
|
||||
+ *reason_r = error;
|
||||
}
|
||||
if (ret > 0 && client->mailbox != NULL) {
|
||||
fd_notify = mailbox_watch_extract_notify_fd(client->mailbox,
|
||||
@@ -248,6 +254,7 @@ bool imap_client_hibernate(struct client **_client)
|
||||
e_debug(client->event, "Couldn't hibernate imap client: "
|
||||
"Couldn't extract notifications fd: %s",
|
||||
error);
|
||||
+ *reason_r = error;
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
@@ -257,5 +264,6 @@ bool imap_client_hibernate(struct client **_client)
|
||||
e_error(client->event,
|
||||
"Couldn't hibernate imap client: %s", error);
|
||||
+ *reason_r = error;
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
diff --git a/src/imap/imap-client.h b/src/imap/imap-client.h
|
||||
index f2ffe0d7c9..4e591d5c7c 100644
|
||||
--- a/src/imap/imap-client.h
|
||||
+++ b/src/imap/imap-client.h
|
||||
@@ -323,8 +323,9 @@ enum mailbox_feature client_enabled_mailbox_features(struct client *client);
|
||||
const char *const *client_enabled_features(struct client *client);
|
||||
|
||||
/* Send client processing to imap-idle process. If successful, returns TRUE
|
||||
- and destroys the client. */
|
||||
-bool imap_client_hibernate(struct client **client);
|
||||
+ and destroys the client. If hibernation failed, the exact reason is
|
||||
+ returned (mainly for unit tests). */
|
||||
+bool imap_client_hibernate(struct client **client, const char **reason_r);
|
||||
|
||||
struct imap_search_update *
|
||||
client_search_update_lookup(struct client *client, const char *tag,
|
@ -1,129 +0,0 @@
|
||||
diff -up dovecot-2.3.8/src/imap/imap-client-hibernate.c.CVE_2020_24386-prereq1 dovecot-2.3.8/src/imap/imap-client-hibernate.c
|
||||
--- dovecot-2.3.8/src/imap/imap-client-hibernate.c.CVE_2020_24386-prereq1 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/imap/imap-client-hibernate.c 2021-01-08 17:14:40.051174282 +0100
|
||||
@@ -19,24 +19,26 @@
|
||||
#define IMAP_HIBERNATE_SEND_TIMEOUT_SECS 10
|
||||
#define IMAP_HIBERNATE_HANDSHAKE "VERSION\timap-hibernate\t1\t0\n"
|
||||
|
||||
-static int imap_hibernate_handshake(int fd, const char *path)
|
||||
+static int
|
||||
+imap_hibernate_handshake(int fd, const char *path, const char **error_r)
|
||||
{
|
||||
char buf[1024];
|
||||
ssize_t ret;
|
||||
|
||||
if (write_full(fd, IMAP_HIBERNATE_HANDSHAKE,
|
||||
strlen(IMAP_HIBERNATE_HANDSHAKE)) < 0) {
|
||||
- i_error("write(%s) failed: %m", path);
|
||||
+ *error_r = t_strdup_printf("write(%s) failed: %m", path);
|
||||
return -1;
|
||||
} else if ((ret = read(fd, buf, sizeof(buf)-1)) < 0) {
|
||||
- i_error("read(%s) failed: %m", path);
|
||||
+ *error_r = t_strdup_printf("read(%s) failed: %m", path);
|
||||
return -1;
|
||||
} else if (ret > 0 && buf[ret-1] == '\n') {
|
||||
buf[ret-1] = '\0';
|
||||
if (version_string_verify(buf, "imap-hibernate", 1))
|
||||
return 0;
|
||||
}
|
||||
- i_error("%s sent invalid VERSION handshake: %s", path, buf);
|
||||
+ *error_r = t_strdup_printf("%s sent invalid VERSION handshake: %s",
|
||||
+ path, buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -105,40 +107,42 @@ static void imap_hibernate_write_cmd(str
|
||||
|
||||
static int
|
||||
imap_hibernate_process_send_cmd(int fd_socket, const char *path,
|
||||
- const string_t *cmd, int fd_client)
|
||||
+ const string_t *cmd, int fd_client,
|
||||
+ const char **error_r)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
i_assert(fd_socket != -1);
|
||||
i_assert(str_len(cmd) > 1);
|
||||
|
||||
- if (imap_hibernate_handshake(fd_socket, path) < 0)
|
||||
+ if (imap_hibernate_handshake(fd_socket, path, error_r) < 0)
|
||||
return -1;
|
||||
if ((ret = fd_send(fd_socket, fd_client, str_data(cmd), 1)) < 0) {
|
||||
- i_error("fd_send(%s) failed: %m", path);
|
||||
+ *error_r = t_strdup_printf("fd_send(%s) failed: %m", path);
|
||||
return -1;
|
||||
}
|
||||
if ((ret = write_full(fd_socket, str_data(cmd)+1, str_len(cmd)-1)) < 0) {
|
||||
- i_error("write(%s) failed: %m", path);
|
||||
+ *error_r = t_strdup_printf("write(%s) failed: %m", path);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int imap_hibernate_process_read(int fd, const char *path)
|
||||
+static int
|
||||
+imap_hibernate_process_read(int fd, const char *path, const char **error_r)
|
||||
{
|
||||
char buf[1024];
|
||||
ssize_t ret;
|
||||
|
||||
if ((ret = read(fd, buf, sizeof(buf)-1)) < 0) {
|
||||
- i_error("read(%s) failed: %m", path);
|
||||
+ *error_r = t_strdup_printf("read(%s) failed: %m", path);
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
- i_error("%s disconnected", path);
|
||||
+ *error_r = t_strdup_printf("%s disconnected", path);
|
||||
return -1;
|
||||
} else if (buf[0] != '+') {
|
||||
buf[ret] = '\0';
|
||||
- i_error("%s returned failure: %s", path,
|
||||
+ *error_r = t_strdup_printf("%s returned failure: %s", path,
|
||||
ret > 0 && buf[0] == '-' ? buf+1 : buf);
|
||||
return -1;
|
||||
} else {
|
||||
@@ -147,8 +151,8 @@ static int imap_hibernate_process_read(i
|
||||
}
|
||||
|
||||
static int
|
||||
-imap_hibernate_process_send(struct client *client,
|
||||
- const buffer_t *state, int fd_notify, int *fd_r)
|
||||
+imap_hibernate_process_send(struct client *client, const buffer_t *state,
|
||||
+ int fd_notify, int *fd_r, const char **error_r)
|
||||
{
|
||||
string_t *cmd = t_str_new(512);
|
||||
const char *path;
|
||||
@@ -171,14 +175,14 @@ imap_hibernate_process_send(struct clien
|
||||
imap_hibernate_write_cmd(client, cmd, state, fd_notify);
|
||||
|
||||
alarm(IMAP_HIBERNATE_SEND_TIMEOUT_SECS);
|
||||
- if (imap_hibernate_process_send_cmd(fd, path, cmd, client->fd_in) < 0 ||
|
||||
- imap_hibernate_process_read(fd, path) < 0)
|
||||
+ if (imap_hibernate_process_send_cmd(fd, path, cmd, client->fd_in, error_r) < 0 ||
|
||||
+ imap_hibernate_process_read(fd, path, error_r) < 0)
|
||||
ret = -1;
|
||||
else if (fd_notify != -1) {
|
||||
if ((ret = fd_send(fd, fd_notify, "\n", 1)) < 0)
|
||||
- i_error("fd_send(%s) failed: %m", path);
|
||||
+ *error_r = t_strdup_printf("fd_send(%s) failed: %m", path);
|
||||
else
|
||||
- ret = imap_hibernate_process_read(fd, path);
|
||||
+ ret = imap_hibernate_process_read(fd, path, error_r);
|
||||
}
|
||||
alarm(0);
|
||||
if (ret < 0) {
|
||||
@@ -229,8 +233,12 @@ bool imap_client_hibernate(struct client
|
||||
}
|
||||
}
|
||||
if (ret > 0) {
|
||||
- if (imap_hibernate_process_send(client, state, fd_notify, &fd_hibernate) < 0)
|
||||
+ if (imap_hibernate_process_send(client, state, fd_notify,
|
||||
+ &fd_hibernate, &error) < 0) {
|
||||
+ e_error(client->event,
|
||||
+ "Couldn't hibernate imap client: %s", error);
|
||||
ret = -1;
|
||||
+ }
|
||||
}
|
||||
i_close_fd(&fd_notify);
|
||||
if (ret > 0) {
|
@ -1,185 +0,0 @@
|
||||
From b9a2f18466a0d3377bab3e7a57691bdd75d8507c Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 17 Aug 2020 17:32:11 +0300
|
||||
Subject: [PATCH] lib-imap: Add imap_parser_read_tag() and _read_command_name()
|
||||
|
||||
---
|
||||
src/lib-imap/imap-parser.c | 67 +++++++++++++++++++++++++++++++++
|
||||
src/lib-imap/imap-parser.h | 7 ++++
|
||||
src/lib-imap/test-imap-parser.c | 67 +++++++++++++++++++++++++++++++++
|
||||
3 files changed, 141 insertions(+)
|
||||
|
||||
diff --git a/src/lib-imap/imap-parser.c b/src/lib-imap/imap-parser.c
|
||||
index b6c6e63fb1..52d79282fa 100644
|
||||
--- a/src/lib-imap/imap-parser.c
|
||||
+++ b/src/lib-imap/imap-parser.c
|
||||
@@ -947,3 +947,70 @@ const char *imap_parser_read_word(struct imap_parser *parser)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+
|
||||
+static int
|
||||
+imap_parser_read_next_atom(struct imap_parser *parser, bool parsing_tag,
|
||||
+ const char **atom_r)
|
||||
+{
|
||||
+ const unsigned char *data;
|
||||
+ size_t i, data_size;
|
||||
+
|
||||
+ data = i_stream_get_data(parser->input, &data_size);
|
||||
+
|
||||
+ /*
|
||||
+ tag = 1*<any ASTRING-CHAR except "+">
|
||||
+ ASTRING-CHAR = ATOM-CHAR / resp-specials
|
||||
+ ATOM-CHAR = <any CHAR except atom-specials>
|
||||
+
|
||||
+ x-command = "X" atom <experimental command arguments>
|
||||
+ atom = 1*ATOM-CHAR
|
||||
+ */
|
||||
+ for (i = 0; i < data_size; i++) {
|
||||
+ /* explicitly check for atom-specials, because
|
||||
+ IS_ATOM_PARSER_INPUT() allows some atom-specials */
|
||||
+ switch (data[i]) {
|
||||
+ case ' ':
|
||||
+ case '\r':
|
||||
+ case '\n':
|
||||
+ data_size = i + (data[i] == ' ' ? 1 : 0);
|
||||
+ parser->line_size += data_size;
|
||||
+ i_stream_skip(parser->input, data_size);
|
||||
+ *atom_r = p_strndup(parser->pool, data, i);
|
||||
+ /* don't allow empty string */
|
||||
+ return i == 0 ? -1 : 1;
|
||||
+ /* atom-specials: */
|
||||
+ case '(':
|
||||
+ case ')':
|
||||
+ case '{':
|
||||
+ /* list-wildcards: */
|
||||
+ case '%':
|
||||
+ case '*':
|
||||
+ /* quoted-specials: */
|
||||
+ case '"':
|
||||
+ case '\\':
|
||||
+ /* resp-specials: */
|
||||
+ case ']':
|
||||
+ return -1;
|
||||
+ case '+':
|
||||
+ if (parsing_tag)
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ if ((unsigned char)data[i] < ' ' ||
|
||||
+ (unsigned char)data[i] >= 0x80)
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int imap_parser_read_tag(struct imap_parser *parser, const char **tag_r)
|
||||
+{
|
||||
+ return imap_parser_read_next_atom(parser, TRUE, tag_r);
|
||||
+}
|
||||
+
|
||||
+int imap_parser_read_command_name(struct imap_parser *parser,
|
||||
+ const char **name_r)
|
||||
+{
|
||||
+ return imap_parser_read_next_atom(parser, FALSE, name_r);
|
||||
+}
|
||||
diff --git a/src/lib-imap/imap-parser.h b/src/lib-imap/imap-parser.h
|
||||
index e5d01c17f2..5e09d61d2b 100644
|
||||
--- a/src/lib-imap/imap-parser.h
|
||||
+++ b/src/lib-imap/imap-parser.h
|
||||
@@ -101,5 +101,12 @@ int imap_parser_finish_line(struct imap_parser *parser, unsigned int count,
|
||||
/* Read one word - used for reading tag and command name.
|
||||
Returns NULL if more data is needed. */
|
||||
const char *imap_parser_read_word(struct imap_parser *parser);
|
||||
+/* Read command tag. Returns 1 if tag was returned, 0 if more data is needed,
|
||||
+ -1 if input isn't a valid tag. */
|
||||
+int imap_parser_read_tag(struct imap_parser *parser, const char **tag_r);
|
||||
+/* Read command name. Returns 1 if command name was returned, 0 if more data is
|
||||
+ needed, -1 if input isn't a valid command name string. */
|
||||
+int imap_parser_read_command_name(struct imap_parser *parser,
|
||||
+ const char **name_r);
|
||||
|
||||
#endif
|
||||
diff --git a/src/lib-imap/test-imap-parser.c b/src/lib-imap/test-imap-parser.c
|
||||
index 93ef8fd59b..3ca4e34858 100644
|
||||
--- a/src/lib-imap/test-imap-parser.c
|
||||
+++ b/src/lib-imap/test-imap-parser.c
|
||||
@@ -79,10 +79,77 @@ static void test_imap_parser_partial_list(void)
|
||||
test_end();
|
||||
}
|
||||
|
||||
+static void test_imap_parser_read_tag_cmd(void)
|
||||
+{
|
||||
+ enum read_type {
|
||||
+ BOTH,
|
||||
+ TAG,
|
||||
+ COMMAND
|
||||
+ };
|
||||
+ struct {
|
||||
+ const char *input;
|
||||
+ const char *tag;
|
||||
+ int ret;
|
||||
+ enum read_type type;
|
||||
+ } tests[] = {
|
||||
+ { "tag foo", "tag", 1, BOTH },
|
||||
+ { "tag\r", "tag", 1, BOTH },
|
||||
+ { "tag\rfoo", "tag", 1, BOTH },
|
||||
+ { "tag\nfoo", "tag", 1, BOTH },
|
||||
+ { "tag\r\nfoo", "tag", 1, BOTH },
|
||||
+ { "\n", NULL, -1, BOTH },
|
||||
+ { "tag", NULL, 0, BOTH },
|
||||
+ { "tag\t", NULL, -1, BOTH },
|
||||
+ { "tag\001", NULL, -1, BOTH },
|
||||
+ { "tag\x80", NULL, -1, BOTH },
|
||||
+ { "tag(", NULL, -1, BOTH },
|
||||
+ { "tag)", NULL, -1, BOTH },
|
||||
+ { "tag{", NULL, -1, BOTH },
|
||||
+ { "tag/ ", "tag/", 1, BOTH },
|
||||
+ { "tag%", NULL, -1, BOTH },
|
||||
+ { "tag*", NULL, -1, BOTH },
|
||||
+ { "tag\"", NULL, -1, BOTH },
|
||||
+ { "tag\\", NULL, -1, BOTH },
|
||||
+ { "tag+", NULL, -1, TAG },
|
||||
+ { "tag+ ", "tag+", 1, COMMAND },
|
||||
+ };
|
||||
+ struct istream *input;
|
||||
+ struct imap_parser *parser;
|
||||
+ const char *atom;
|
||||
+ int ret;
|
||||
+
|
||||
+ test_begin("imap_parser_read_tag and imap_parser_read_command_name");
|
||||
+ for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
|
||||
+ if (tests[i].type != COMMAND) {
|
||||
+ input = test_istream_create(tests[i].input);
|
||||
+ test_assert(i_stream_read(input) > 0);
|
||||
+ parser = imap_parser_create(input, NULL, 1024);
|
||||
+ ret = imap_parser_read_tag(parser, &atom);
|
||||
+ test_assert_idx(ret == tests[i].ret, i);
|
||||
+ test_assert_idx(ret <= 0 || strcmp(tests[i].tag, atom) == 0, i);
|
||||
+ imap_parser_unref(&parser);
|
||||
+ i_stream_destroy(&input);
|
||||
+ }
|
||||
+
|
||||
+ if (tests[i].type != TAG) {
|
||||
+ input = test_istream_create(tests[i].input);
|
||||
+ test_assert(i_stream_read(input) > 0);
|
||||
+ parser = imap_parser_create(input, NULL, 1024);
|
||||
+ ret = imap_parser_read_command_name(parser, &atom);
|
||||
+ test_assert_idx(ret == tests[i].ret, i);
|
||||
+ test_assert_idx(ret <= 0 || strcmp(tests[i].tag, atom) == 0, i);
|
||||
+ imap_parser_unref(&parser);
|
||||
+ i_stream_destroy(&input);
|
||||
+ }
|
||||
+ }
|
||||
+ test_end();
|
||||
+}
|
||||
+
|
||||
int main(void)
|
||||
{
|
||||
static void (*const test_functions[])(void) = {
|
||||
test_imap_parser_crlf,
|
||||
+ test_imap_parser_read_tag_cmd,
|
||||
NULL
|
||||
};
|
||||
return test_run(test_functions);
|
@ -1,46 +0,0 @@
|
||||
From eea57c8683325f9767b2eb1b44a0b23352541c1e Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 17 Aug 2020 17:59:19 +0300
|
||||
Subject: [PATCH] imap: Split off client_command_failed_early()
|
||||
|
||||
---
|
||||
src/imap/imap-client.c | 19 ++++++++++++++-----
|
||||
1 file changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c
|
||||
index 07b2a8018b..0bf03caa97 100644
|
||||
--- a/src/imap/imap-client.c
|
||||
+++ b/src/imap/imap-client.c
|
||||
@@ -1176,6 +1176,19 @@ bool client_handle_unfinished_cmd(struct client_command_context *cmd)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+client_command_failed_early(struct client_command_context **_cmd,
|
||||
+ const char *error)
|
||||
+{
|
||||
+ struct client_command_context *cmd = *_cmd;
|
||||
+
|
||||
+ io_loop_time_refresh();
|
||||
+ command_stats_start(cmd);
|
||||
+ client_send_command_error(cmd, error);
|
||||
+ cmd->param_error = TRUE;
|
||||
+ client_command_free(_cmd);
|
||||
+}
|
||||
+
|
||||
static bool client_command_input(struct client_command_context *cmd)
|
||||
{
|
||||
struct client *client = cmd->client;
|
||||
@@ -1239,11 +1252,7 @@ static bool client_command_input(struct client_command_context *cmd)
|
||||
|
||||
if (cmd->func == NULL) {
|
||||
/* unknown command */
|
||||
- io_loop_time_refresh();
|
||||
- command_stats_start(cmd);
|
||||
- client_send_command_error(cmd, "Unknown command.");
|
||||
- cmd->param_error = TRUE;
|
||||
- client_command_free(&cmd);
|
||||
+ client_command_failed_early(&cmd, "Unknown command.");
|
||||
return TRUE;
|
||||
} else {
|
||||
i_assert(!client->disconnected);
|
@ -1,77 +0,0 @@
|
||||
From 0386140f61f9ba62225e90b419215f72bba6ad8b Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 17 Aug 2020 18:11:36 +0300
|
||||
Subject: [PATCH] imap: Use imap_parser_read_tag() and _read_command_name()
|
||||
|
||||
---
|
||||
src/imap/imap-client.c | 33 ++++++++++++++++++++++-----------
|
||||
1 file changed, 22 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c
|
||||
index 0bf03caa97..95e57dbf53 100644
|
||||
--- a/src/imap/imap-client.c
|
||||
+++ b/src/imap/imap-client.c
|
||||
@@ -1182,6 +1182,9 @@ client_command_failed_early(struct client_command_context **_cmd,
|
||||
{
|
||||
struct client_command_context *cmd = *_cmd;
|
||||
|
||||
+ /* ignore the rest of this line */
|
||||
+ cmd->client->input_skip_line = TRUE;
|
||||
+
|
||||
io_loop_time_refresh();
|
||||
command_stats_start(cmd);
|
||||
client_send_command_error(cmd, error);
|
||||
@@ -1193,6 +1196,8 @@ static bool client_command_input(struct client_command_context *cmd)
|
||||
{
|
||||
struct client *client = cmd->client;
|
||||
struct command *command;
|
||||
+ const char *tag, *name;
|
||||
+ int ret;
|
||||
|
||||
if (cmd->func != NULL) {
|
||||
/* command is being executed - continue it */
|
||||
@@ -1207,27 +1212,33 @@ static bool client_command_input(struct client_command_context *cmd)
|
||||
}
|
||||
|
||||
if (cmd->tag == NULL) {
|
||||
- cmd->tag = imap_parser_read_word(cmd->parser);
|
||||
- if (cmd->tag == NULL)
|
||||
+ ret = imap_parser_read_tag(cmd->parser, &tag);
|
||||
+ if (ret == 0)
|
||||
return FALSE; /* need more data */
|
||||
- cmd->tag = p_strdup(cmd->pool, cmd->tag);
|
||||
+ if (ret < 0) {
|
||||
+ client_command_failed_early(&cmd, "Invalid tag.");
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ cmd->tag = p_strdup(cmd->pool, tag);
|
||||
}
|
||||
|
||||
if (cmd->name == NULL) {
|
||||
- cmd->name = imap_parser_read_word(cmd->parser);
|
||||
- if (cmd->name == NULL)
|
||||
+ ret = imap_parser_read_command_name(cmd->parser, &name);
|
||||
+ if (ret == 0)
|
||||
return FALSE; /* need more data */
|
||||
+ if (ret < 0) {
|
||||
+ client_command_failed_early(&cmd, "Invalid command name.");
|
||||
+ return TRUE;
|
||||
+ }
|
||||
|
||||
/* UID commands are a special case. better to handle them
|
||||
here. */
|
||||
- if (!cmd->uid && strcasecmp(cmd->name, "UID") == 0) {
|
||||
+ if (!cmd->uid && strcasecmp(name, "UID") == 0) {
|
||||
cmd->uid = TRUE;
|
||||
- cmd->name = imap_parser_read_word(cmd->parser);
|
||||
- if (cmd->name == NULL)
|
||||
- return FALSE; /* need more data */
|
||||
+ return client_command_input(cmd);
|
||||
}
|
||||
- cmd->name = !cmd->uid ? p_strdup(cmd->pool, cmd->name) :
|
||||
- p_strconcat(cmd->pool, "UID ", cmd->name, NULL);
|
||||
+ cmd->name = !cmd->uid ? p_strdup(cmd->pool, name) :
|
||||
+ p_strconcat(cmd->pool, "UID ", name, NULL);
|
||||
client_command_init_finished(cmd);
|
||||
imap_refresh_proctitle();
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
From 62061e8cf68f506c0ccaaba21fd4174764ca875f Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 17 Aug 2020 18:15:35 +0300
|
||||
Subject: [PATCH] imap-login: Split off client_invalid_command()
|
||||
|
||||
---
|
||||
src/imap-login/imap-login-client.c | 27 +++++++++++++++++----------
|
||||
1 file changed, 17 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/imap-login/imap-login-client.c b/src/imap-login/imap-login-client.c
|
||||
index e2af176309..ce5049d567 100644
|
||||
--- a/src/imap-login/imap-login-client.c
|
||||
+++ b/src/imap-login/imap-login-client.c
|
||||
@@ -194,6 +194,22 @@ static int client_command_execute(struct imap_client *client, const char *cmd,
|
||||
return login_cmd->func(client, args);
|
||||
}
|
||||
|
||||
+static bool client_invalid_command(struct imap_client *client)
|
||||
+{
|
||||
+ if (*client->cmd_tag == '\0')
|
||||
+ client->cmd_tag = "*";
|
||||
+ if (++client->common.bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
|
||||
+ client_send_reply(&client->common, IMAP_CMD_REPLY_BYE,
|
||||
+ "Too many invalid IMAP commands.");
|
||||
+ client_destroy(&client->common,
|
||||
+ "Disconnected: Too many invalid commands");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ client_send_reply(&client->common, IMAP_CMD_REPLY_BAD,
|
||||
+ "Error in IMAP command received by server.");
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static bool imap_is_valid_tag(const char *tag)
|
||||
{
|
||||
for (; *tag != '\0'; tag++) {
|
||||
@@ -326,17 +342,8 @@ static bool imap_client_input_next_cmd(struct client *_client)
|
||||
"not the command name. Add that before the command, "
|
||||
"like: a login user pass");
|
||||
} else if (ret < 0) {
|
||||
- if (*client->cmd_tag == '\0')
|
||||
- client->cmd_tag = "*";
|
||||
- if (++client->common.bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
|
||||
- client_send_reply(&client->common, IMAP_CMD_REPLY_BYE,
|
||||
- "Too many invalid IMAP commands.");
|
||||
- client_destroy(&client->common,
|
||||
- "Disconnected: Too many invalid commands");
|
||||
+ if (!client_invalid_command(client))
|
||||
return FALSE;
|
||||
- }
|
||||
- client_send_reply(&client->common, IMAP_CMD_REPLY_BAD,
|
||||
- "Error in IMAP command received by server.");
|
||||
}
|
||||
|
||||
return ret != 0 && !client->common.destroyed;
|
@ -1,110 +0,0 @@
|
||||
From 9d3ecff3de5553159334cf644e996a616dc52670 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 17 Aug 2020 18:22:42 +0300
|
||||
Subject: [PATCH] imap-login: Use imap_parser_read_tag() and
|
||||
_read_command_name()
|
||||
|
||||
---
|
||||
src/imap-login/imap-login-client.c | 58 ++++++++++++------------------
|
||||
1 file changed, 23 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/src/imap-login/imap-login-client.c b/src/imap-login/imap-login-client.c
|
||||
index ce5049d567..b2c8af9cbf 100644
|
||||
--- a/src/imap-login/imap-login-client.c
|
||||
+++ b/src/imap-login/imap-login-client.c
|
||||
@@ -196,7 +196,7 @@ static int client_command_execute(struct imap_client *client, const char *cmd,
|
||||
|
||||
static bool client_invalid_command(struct imap_client *client)
|
||||
{
|
||||
- if (*client->cmd_tag == '\0')
|
||||
+ if (client->cmd_tag == NULL || *client->cmd_tag == '\0')
|
||||
client->cmd_tag = "*";
|
||||
if (++client->common.bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
|
||||
client_send_reply(&client->common, IMAP_CMD_REPLY_BYE,
|
||||
@@ -210,33 +210,6 @@ static bool client_invalid_command(struct imap_client *client)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-static bool imap_is_valid_tag(const char *tag)
|
||||
-{
|
||||
- for (; *tag != '\0'; tag++) {
|
||||
- switch (*tag) {
|
||||
- case '+':
|
||||
- /* atom-specials: */
|
||||
- case '(':
|
||||
- case ')':
|
||||
- case '{':
|
||||
- case '/':
|
||||
- case ' ':
|
||||
- /* list-wildcards: */
|
||||
- case '%':
|
||||
- case '*':
|
||||
- /* quoted-specials: */
|
||||
- case '"':
|
||||
- case '\\':
|
||||
- return FALSE;
|
||||
- default:
|
||||
- if (*tag < ' ') /* CTL */
|
||||
- return FALSE;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- return TRUE;
|
||||
-}
|
||||
-
|
||||
static int client_parse_command(struct imap_client *client,
|
||||
const struct imap_arg **args_r)
|
||||
{
|
||||
@@ -261,6 +234,9 @@ static int client_parse_command(struct imap_client *client,
|
||||
|
||||
static bool client_handle_input(struct imap_client *client)
|
||||
{
|
||||
+ const char *tag, *name;
|
||||
+ int ret;
|
||||
+
|
||||
i_assert(!client->common.authenticating);
|
||||
|
||||
if (client->cmd_finished) {
|
||||
@@ -282,23 +258,35 @@ static bool client_handle_input(struct imap_client *client)
|
||||
}
|
||||
|
||||
if (client->cmd_tag == NULL) {
|
||||
- client->cmd_tag = imap_parser_read_word(client->parser);
|
||||
- if (client->cmd_tag == NULL)
|
||||
+ ret = imap_parser_read_tag(client->parser, &tag);
|
||||
+ if (ret == 0)
|
||||
return FALSE; /* need more data */
|
||||
- if (!imap_is_valid_tag(client->cmd_tag) ||
|
||||
- strlen(client->cmd_tag) > IMAP_TAG_MAX_LEN) {
|
||||
+ if (ret < 0 || strlen(tag) > IMAP_TAG_MAX_LEN) {
|
||||
/* the tag is invalid, don't allow it and don't
|
||||
send it back. this attempts to prevent any
|
||||
potentially dangerous replies in case someone tries
|
||||
to access us using HTTP protocol. */
|
||||
- client->cmd_tag = "";
|
||||
+ client->skip_line = TRUE;
|
||||
+ client->cmd_finished = TRUE;
|
||||
+ if (!client_invalid_command(client))
|
||||
+ return FALSE;
|
||||
+ return client_handle_input(client);
|
||||
}
|
||||
+ client->cmd_tag = tag;
|
||||
}
|
||||
|
||||
if (client->cmd_name == NULL) {
|
||||
- client->cmd_name = imap_parser_read_word(client->parser);
|
||||
- if (client->cmd_name == NULL)
|
||||
+ ret = imap_parser_read_command_name(client->parser, &name);
|
||||
+ if (ret == 0)
|
||||
return FALSE; /* need more data */
|
||||
+ if (ret < 0) {
|
||||
+ client->skip_line = TRUE;
|
||||
+ client->cmd_finished = TRUE;
|
||||
+ if (!client_invalid_command(client))
|
||||
+ return FALSE;
|
||||
+ return client_handle_input(client);
|
||||
+ }
|
||||
+ client->cmd_name = name;
|
||||
}
|
||||
return client->common.v.input_next_cmd(&client->common);
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
From 7a70f01fe8084431901433a2f74cb9c70fd00568 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Mon, 17 Aug 2020 18:26:01 +0300
|
||||
Subject: [PATCH] lib-imap: Add imap_parser_client_read_tag()
|
||||
|
||||
---
|
||||
src/lib-imap/imap-parser.c | 6 ++++++
|
||||
src/lib-imap/imap-parser.h | 5 +++++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/src/lib-imap/imap-parser.c b/src/lib-imap/imap-parser.c
|
||||
index 52d79282fa..cc283f5c06 100644
|
||||
--- a/src/lib-imap/imap-parser.c
|
||||
+++ b/src/lib-imap/imap-parser.c
|
||||
@@ -1014,3 +1014,9 @@ int imap_parser_read_command_name(struct imap_parser *parser,
|
||||
{
|
||||
return imap_parser_read_next_atom(parser, FALSE, name_r);
|
||||
}
|
||||
+
|
||||
+int imap_parser_client_read_tag(struct imap_parser *parser,
|
||||
+ const char **tag_r)
|
||||
+{
|
||||
+ return imap_parser_read_next_atom(parser, FALSE, tag_r);
|
||||
+}
|
||||
diff --git a/src/lib-imap/imap-parser.h b/src/lib-imap/imap-parser.h
|
||||
index 5e09d61d2b..cd3748c00f 100644
|
||||
--- a/src/lib-imap/imap-parser.h
|
||||
+++ b/src/lib-imap/imap-parser.h
|
||||
@@ -108,5 +108,10 @@ int imap_parser_read_tag(struct imap_parser *parser, const char **tag_r);
|
||||
needed, -1 if input isn't a valid command name string. */
|
||||
int imap_parser_read_command_name(struct imap_parser *parser,
|
||||
const char **name_r);
|
||||
+/* For IMAP clients: Read the command tag, which could also be "+" or "*".
|
||||
+ Returns 1 if tag was returned, 0 if more data is needed, -1 if input isn't
|
||||
+ valid. */
|
||||
+int imap_parser_client_read_tag(struct imap_parser *parser,
|
||||
+ const char **tag_r);
|
||||
|
||||
#endif
|
@ -1,126 +0,0 @@
|
||||
From fb97a1cddbda4019e327fa736972a1c7433fedaa Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Fri, 11 Sep 2020 09:53:03 +0300
|
||||
Subject: [PATCH] lib-mail: message-parser - Fix assert-crash when enforcing
|
||||
MIME part limit
|
||||
|
||||
The limit could have been exceeded with message/rfc822 parts.
|
||||
---
|
||||
src/lib-mail/message-parser.c | 3 +-
|
||||
src/lib-mail/test-message-parser.c | 82 ++++++++++++++++++++++++++++++
|
||||
2 files changed, 84 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
|
||||
index 6ab4c3266f..40a504da0a 100644
|
||||
--- a/src/lib-mail/message-parser.c
|
||||
+++ b/src/lib-mail/message-parser.c
|
||||
@@ -703,7 +703,8 @@ static int parse_next_header(struct message_parser_ctx *ctx,
|
||||
ctx->multipart = FALSE;
|
||||
ctx->parse_next_block = parse_next_body_to_boundary;
|
||||
} else if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0 &&
|
||||
- !parse_too_many_nested_mime_parts(ctx)) {
|
||||
+ !parse_too_many_nested_mime_parts(ctx) &&
|
||||
+ ctx->total_parts_count < ctx->max_total_mime_parts) {
|
||||
ctx->parse_next_block = parse_next_body_message_rfc822_init;
|
||||
} else {
|
||||
part->flags &= ~MESSAGE_PART_FLAG_MESSAGE_RFC822;
|
||||
diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c
|
||||
index 8c5a3404f1..c4e117afc7 100644
|
||||
--- a/src/lib-mail/test-message-parser.c
|
||||
+++ b/src/lib-mail/test-message-parser.c
|
||||
@@ -1127,6 +1127,87 @@ static const char input_msg[] =
|
||||
test_end();
|
||||
}
|
||||
|
||||
+static void test_message_parser_mime_part_limit_rfc822(void)
|
||||
+{
|
||||
+static const char input_msg[] =
|
||||
+"Content-Type: multipart/mixed; boundary=\"1\"\n"
|
||||
+"\n"
|
||||
+"--1\n"
|
||||
+"Content-Type: multipart/mixed; boundary=\"2\"\n"
|
||||
+"\n"
|
||||
+"--2\n"
|
||||
+"Content-Type: message/rfc822\n"
|
||||
+"\n"
|
||||
+"Content-Type: text/plain\n"
|
||||
+"\n"
|
||||
+"1\n"
|
||||
+"--2\n"
|
||||
+"Content-Type: message/rfc822\n"
|
||||
+"\n"
|
||||
+"Content-Type: text/plain\n"
|
||||
+"\n"
|
||||
+"22\n"
|
||||
+"--1\n"
|
||||
+"Content-Type: message/rfc822\n"
|
||||
+"\n"
|
||||
+"Content-Type: text/plain\n"
|
||||
+"\n"
|
||||
+"333\n";
|
||||
+ const struct message_parser_settings parser_set = {
|
||||
+ .max_total_mime_parts = 3,
|
||||
+ };
|
||||
+ struct message_parser_ctx *parser;
|
||||
+ struct istream *input;
|
||||
+ struct message_part *parts, *part;
|
||||
+ struct message_block block;
|
||||
+ pool_t pool;
|
||||
+ int ret;
|
||||
+
|
||||
+ test_begin("message parser mime part limit rfc822");
|
||||
+ pool = pool_alloconly_create("message parser", 10240);
|
||||
+ input = test_istream_create(input_msg);
|
||||
+
|
||||
+ parser = message_parser_init(pool, input, &parser_set);
|
||||
+ while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
|
||||
+ test_assert(ret < 0);
|
||||
+ message_parser_deinit(&parser, &parts);
|
||||
+
|
||||
+ part = parts;
|
||||
+ test_assert(part->children_count == 2);
|
||||
+ test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
|
||||
+ test_assert(part->header_size.lines == 2);
|
||||
+ test_assert(part->header_size.physical_size == 45);
|
||||
+ test_assert(part->header_size.virtual_size == 45+2);
|
||||
+ test_assert(part->body_size.lines == 21);
|
||||
+ test_assert(part->body_size.physical_size == 238);
|
||||
+ test_assert(part->body_size.virtual_size == 238+21);
|
||||
+
|
||||
+ part = parts->children;
|
||||
+ test_assert(part->children_count == 1);
|
||||
+ test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
|
||||
+ test_assert(part->header_size.lines == 2);
|
||||
+ test_assert(part->header_size.physical_size == 45);
|
||||
+ test_assert(part->header_size.virtual_size == 45+2);
|
||||
+ test_assert(part->body_size.lines == 18);
|
||||
+ test_assert(part->body_size.physical_size == 189);
|
||||
+ test_assert(part->body_size.virtual_size == 189+18);
|
||||
+
|
||||
+ part = parts->children->children;
|
||||
+ test_assert(part->children_count == 0);
|
||||
+ test_assert(part->flags == MESSAGE_PART_FLAG_IS_MIME);
|
||||
+ test_assert(part->header_size.lines == 2);
|
||||
+ test_assert(part->header_size.physical_size == 30);
|
||||
+ test_assert(part->header_size.virtual_size == 30+2);
|
||||
+ test_assert(part->body_size.lines == 15);
|
||||
+ test_assert(part->body_size.physical_size == 155);
|
||||
+ test_assert(part->body_size.virtual_size == 155+15);
|
||||
+
|
||||
+ test_parsed_parts(input, parts);
|
||||
+ i_stream_unref(&input);
|
||||
+ pool_unref(&pool);
|
||||
+ test_end();
|
||||
+}
|
||||
+
|
||||
int main(void)
|
||||
{
|
||||
static void (*const test_functions[])(void) = {
|
||||
@@ -1301,6 +1382,7 @@ int main(void)
|
||||
test_message_parser_mime_part_nested_limit,
|
||||
test_message_parser_mime_part_nested_limit_rfc822,
|
||||
test_message_parser_mime_part_limit,
|
||||
+ test_message_parser_mime_part_limit_rfc822,
|
||||
NULL
|
||||
};
|
||||
return test_run(test_functions);
|
@ -1,63 +0,0 @@
|
||||
From 266e54b7b8c34c9a58dd60a2e53c5ca7d1deae19 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Fri, 11 Sep 2020 10:57:51 +0300
|
||||
Subject: [PATCH] lib-imap: Don't generate invalid BODYSTRUCTURE when reaching
|
||||
MIME part limit
|
||||
|
||||
If the last MIME part was message/rfc822 and its child was truncated away,
|
||||
BODYSTRUCTURE was missing the ENVELOPE and BODY[STRUCTURE] parts. Fixed by
|
||||
writing empty dummy ones.
|
||||
---
|
||||
src/lib-imap/imap-bodystructure.c | 29 +++++++++++++++++++++++++++--
|
||||
1 file changed, 27 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib-imap/imap-bodystructure.c b/src/lib-imap/imap-bodystructure.c
|
||||
index 4e379e56a9..e3da1090b4 100644
|
||||
--- a/src/lib-imap/imap-bodystructure.c
|
||||
+++ b/src/lib-imap/imap-bodystructure.c
|
||||
@@ -146,11 +146,25 @@ static void part_write_body(const struct message_part *part,
|
||||
string_t *str, bool extended)
|
||||
{
|
||||
const struct message_part_data *data = part->data;
|
||||
- bool text;
|
||||
+ bool text, message_rfc822;
|
||||
|
||||
i_assert(part->data != NULL);
|
||||
|
||||
- if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0) {
|
||||
+ if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0)
|
||||
+ message_rfc822 = TRUE;
|
||||
+ else if (data->content_type != NULL &&
|
||||
+ strcasecmp(data->content_type, "message") == 0 &&
|
||||
+ strcasecmp(data->content_subtype, "rfc822") == 0) {
|
||||
+ /* It's message/rfc822, but without
|
||||
+ MESSAGE_PART_FLAG_MESSAGE_RFC822. That likely means maximum
|
||||
+ MIME part count was reached while parsing the mail. Write
|
||||
+ the missing child mail's ENVELOPE and BODY as empty dummy
|
||||
+ values. */
|
||||
+ message_rfc822 = TRUE;
|
||||
+ } else
|
||||
+ message_rfc822 = FALSE;
|
||||
+
|
||||
+ if (message_rfc822) {
|
||||
str_append(str, "\"message\" \"rfc822\"");
|
||||
text = FALSE;
|
||||
} else {
|
||||
@@ -200,6 +214,17 @@ static void part_write_body(const struct message_part *part,
|
||||
|
||||
part_write_bodystructure_siblings(part->children, str, extended);
|
||||
str_printfa(str, " %u", part->body_size.lines);
|
||||
+ } else if (message_rfc822) {
|
||||
+ /* truncated MIME part - write out dummy values */
|
||||
+ i_assert(part->children == NULL);
|
||||
+
|
||||
+ str_append(str, " (NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) ");
|
||||
+
|
||||
+ if (!extended)
|
||||
+ str_append(str, EMPTY_BODY);
|
||||
+ else
|
||||
+ str_append(str, EMPTY_BODYSTRUCTURE);
|
||||
+ str_printfa(str, " %u", part->body_size.lines);
|
||||
}
|
||||
|
||||
if (!extended)
|
@ -1,228 +0,0 @@
|
||||
From 530c1e950a1bb46ff4e4a7c8e4b7cd945ff28916 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Wed, 18 Nov 2020 18:55:34 +0200
|
||||
Subject: [PATCH] lib-imap: Fix writing BODYSTRUCTURE for truncated
|
||||
message/rfc822 part
|
||||
|
||||
If the max nesting limit is reached, write the last part out as
|
||||
application/octet-stream instead of dummy message/rfc822.
|
||||
|
||||
Fixes error while parsing BODYSTRUCTURE:
|
||||
message_part message/rfc822 flag doesn't match BODYSTRUCTURE
|
||||
---
|
||||
src/lib-imap/imap-bodystructure.c | 54 +++++++++----------
|
||||
src/lib-imap/test-imap-bodystructure.c | 73 ++++++++++++++++++++++++--
|
||||
2 files changed, 96 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/src/lib-imap/imap-bodystructure.c b/src/lib-imap/imap-bodystructure.c
|
||||
index e3da1090b4..ab422c00d2 100644
|
||||
--- a/src/lib-imap/imap-bodystructure.c
|
||||
+++ b/src/lib-imap/imap-bodystructure.c
|
||||
@@ -142,31 +142,42 @@ static void part_write_body_multipart(const struct message_part *part,
|
||||
part_write_bodystructure_common(data, str);
|
||||
}
|
||||
|
||||
+static bool part_is_truncated(const struct message_part *part)
|
||||
+{
|
||||
+ const struct message_part_data *data = part->data;
|
||||
+
|
||||
+ i_assert((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0);
|
||||
+
|
||||
+ if (data->content_type != NULL) {
|
||||
+ if (strcasecmp(data->content_type, "message") == 0 &&
|
||||
+ strcasecmp(data->content_subtype, "rfc822") == 0) {
|
||||
+ /* It's message/rfc822, but without
|
||||
+ MESSAGE_PART_FLAG_MESSAGE_RFC822. */
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
static void part_write_body(const struct message_part *part,
|
||||
string_t *str, bool extended)
|
||||
{
|
||||
const struct message_part_data *data = part->data;
|
||||
- bool text, message_rfc822;
|
||||
+ bool text;
|
||||
|
||||
i_assert(part->data != NULL);
|
||||
|
||||
- if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0)
|
||||
- message_rfc822 = TRUE;
|
||||
- else if (data->content_type != NULL &&
|
||||
- strcasecmp(data->content_type, "message") == 0 &&
|
||||
- strcasecmp(data->content_subtype, "rfc822") == 0) {
|
||||
- /* It's message/rfc822, but without
|
||||
- MESSAGE_PART_FLAG_MESSAGE_RFC822. That likely means maximum
|
||||
- MIME part count was reached while parsing the mail. Write
|
||||
- the missing child mail's ENVELOPE and BODY as empty dummy
|
||||
- values. */
|
||||
- message_rfc822 = TRUE;
|
||||
- } else
|
||||
- message_rfc822 = FALSE;
|
||||
-
|
||||
- if (message_rfc822) {
|
||||
+ if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0) {
|
||||
str_append(str, "\"message\" \"rfc822\"");
|
||||
text = FALSE;
|
||||
+ } else if (part_is_truncated(part)) {
|
||||
+ /* Maximum MIME part count was reached while parsing the mail.
|
||||
+ Write this part out as application/octet-stream instead.
|
||||
+ We're not using text/plain, because it would require
|
||||
+ message-parser to use MESSAGE_PART_FLAG_TEXT for this part
|
||||
+ to avoid losing line count in message_part serialization. */
|
||||
+ str_append(str, "\"application\" \"octet-stream\"");
|
||||
+ text = FALSE;
|
||||
} else {
|
||||
/* "content type" "subtype" */
|
||||
if (data->content_type == NULL) {
|
||||
@@ -214,17 +225,6 @@ static void part_write_body(const struct message_part *part,
|
||||
|
||||
part_write_bodystructure_siblings(part->children, str, extended);
|
||||
str_printfa(str, " %u", part->body_size.lines);
|
||||
- } else if (message_rfc822) {
|
||||
- /* truncated MIME part - write out dummy values */
|
||||
- i_assert(part->children == NULL);
|
||||
-
|
||||
- str_append(str, " (NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) ");
|
||||
-
|
||||
- if (!extended)
|
||||
- str_append(str, EMPTY_BODY);
|
||||
- else
|
||||
- str_append(str, EMPTY_BODYSTRUCTURE);
|
||||
- str_printfa(str, " %u", part->body_size.lines);
|
||||
}
|
||||
|
||||
if (!extended)
|
||||
diff --git a/src/lib-imap/test-imap-bodystructure.c b/src/lib-imap/test-imap-bodystructure.c
|
||||
index dfc9957488..6cb699e126 100644
|
||||
--- a/src/lib-imap/test-imap-bodystructure.c
|
||||
+++ b/src/lib-imap/test-imap-bodystructure.c
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "istream.h"
|
||||
#include "str.h"
|
||||
#include "message-part-data.h"
|
||||
+#include "message-part-serialize.h"
|
||||
#include "message-parser.h"
|
||||
#include "imap-bodystructure.h"
|
||||
#include "test-common.h"
|
||||
@@ -379,12 +380,14 @@ struct normalize_test normalize_tests[] = {
|
||||
static const unsigned int normalize_tests_count = N_ELEMENTS(normalize_tests);
|
||||
|
||||
static struct message_part *
|
||||
-msg_parse(pool_t pool, const char *message, bool parse_bodystructure)
|
||||
+msg_parse(pool_t pool, const char *message, unsigned int max_nested_mime_parts,
|
||||
+ bool parse_bodystructure)
|
||||
{
|
||||
const struct message_parser_settings parser_set = {
|
||||
.hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
|
||||
MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
|
||||
.flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
|
||||
+ .max_nested_mime_parts = max_nested_mime_parts,
|
||||
};
|
||||
struct message_parser_ctx *parser;
|
||||
struct istream *input;
|
||||
@@ -418,7 +421,7 @@ static void test_imap_bodystructure_write(void)
|
||||
pool_t pool = pool_alloconly_create("imap bodystructure write", 1024);
|
||||
|
||||
test_begin(t_strdup_printf("imap bodystructure write [%u]", i));
|
||||
- parts = msg_parse(pool, test->message, TRUE);
|
||||
+ parts = msg_parse(pool, test->message, 0, TRUE);
|
||||
|
||||
imap_bodystructure_write(parts, str, TRUE);
|
||||
test_assert(strcmp(str_c(str), test->bodystructure) == 0);
|
||||
@@ -445,7 +448,7 @@ static void test_imap_bodystructure_parse(void)
|
||||
pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024);
|
||||
|
||||
test_begin(t_strdup_printf("imap bodystructure parser [%u]", i));
|
||||
- parts = msg_parse(pool, test->message, FALSE);
|
||||
+ parts = msg_parse(pool, test->message, 0, FALSE);
|
||||
|
||||
test_assert(imap_body_parse_from_bodystructure(test->bodystructure,
|
||||
str, &error) == 0);
|
||||
@@ -512,7 +515,7 @@ static void test_imap_bodystructure_normalize(void)
|
||||
pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024);
|
||||
|
||||
test_begin(t_strdup_printf("imap bodystructure normalize [%u]", i));
|
||||
- parts = msg_parse(pool, test->message, FALSE);
|
||||
+ parts = msg_parse(pool, test->message, 0, FALSE);
|
||||
|
||||
ret = imap_bodystructure_parse(test->input,
|
||||
pool, parts, &error);
|
||||
@@ -531,6 +534,67 @@ static void test_imap_bodystructure_normalize(void)
|
||||
} T_END;
|
||||
}
|
||||
|
||||
+static const struct {
|
||||
+ const char *input;
|
||||
+ const char *bodystructure;
|
||||
+ unsigned int max_depth;
|
||||
+} truncation_tests[] = {
|
||||
+ {
|
||||
+ .input = "Content-Type: message/rfc822\n"
|
||||
+ "\n"
|
||||
+ "Content-Type: message/rfc822\n"
|
||||
+ "Header2: value2\n"
|
||||
+ "\n"
|
||||
+ "Subject: hello world\n"
|
||||
+ "Header2: value2\n"
|
||||
+ "Header3: value3\n"
|
||||
+ "\n"
|
||||
+ "body line 1\n"
|
||||
+ "body line 2\n"
|
||||
+ "body line 4\n"
|
||||
+ "body line 3\n",
|
||||
+ .bodystructure = "\"message\" \"rfc822\" NIL NIL NIL \"7bit\" 159 (NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) (\"application\" \"octet-stream\" NIL NIL NIL \"7bit\" 110 NIL NIL NIL NIL) 11 NIL NIL NIL NIL",
|
||||
+ .max_depth = 2,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void test_imap_bodystructure_truncation(void)
|
||||
+{
|
||||
+ struct message_part *parts;
|
||||
+ const char *error;
|
||||
+ string_t *str_body = t_str_new(128);
|
||||
+ string_t *str_parts = t_str_new(128);
|
||||
+ pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024);
|
||||
+
|
||||
+ test_begin("imap bodystructure truncation");
|
||||
+
|
||||
+ for (unsigned int i = 0; i < N_ELEMENTS(truncation_tests); i++) {
|
||||
+ p_clear(pool);
|
||||
+ str_truncate(str_body, 0);
|
||||
+ str_truncate(str_parts, 0);
|
||||
+
|
||||
+ parts = msg_parse(pool, truncation_tests[i].input,
|
||||
+ truncation_tests[i].max_depth,
|
||||
+ TRUE);
|
||||
+
|
||||
+ /* write out BODYSTRUCTURE and serialize message_parts */
|
||||
+ imap_bodystructure_write(parts, str_body, TRUE);
|
||||
+ message_part_serialize(parts, str_parts);
|
||||
+
|
||||
+ /* now deserialize message_parts and make sure they can be used
|
||||
+ to parse BODYSTRUCTURE */
|
||||
+ parts = message_part_deserialize(pool, str_data(str_parts),
|
||||
+ str_len(str_parts), &error);
|
||||
+ test_assert(parts != NULL);
|
||||
+ test_assert(imap_bodystructure_parse(str_c(str_body), pool,
|
||||
+ parts, &error) == 0);
|
||||
+ test_assert_strcmp(str_c(str_body),
|
||||
+ truncation_tests[i].bodystructure);
|
||||
+ }
|
||||
+ pool_unref(&pool);
|
||||
+ test_end();
|
||||
+}
|
||||
+
|
||||
int main(void)
|
||||
{
|
||||
static void (*const test_functions[])(void) = {
|
||||
@@ -538,6 +602,7 @@ int main(void)
|
||||
test_imap_bodystructure_parse,
|
||||
test_imap_bodystructure_normalize,
|
||||
test_imap_bodystructure_parse_full,
|
||||
+ test_imap_bodystructure_truncation,
|
||||
NULL
|
||||
};
|
||||
return test_run(test_functions);
|
@ -1,64 +0,0 @@
|
||||
From ec2c5ffde7a1ca63219d47831725599e7de76f7f Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Wed, 18 Nov 2020 20:48:11 +0200
|
||||
Subject: [PATCH] lib-imap: Fix writing BODYSTRUCTURE for truncated multipart/
|
||||
part
|
||||
|
||||
If the max nesting limit is reached, write the last part out as
|
||||
application/octet-stream. The original content-type could be confusing
|
||||
IMAP clients when they don't see any child parts.
|
||||
---
|
||||
src/lib-imap/imap-bodystructure.c | 6 ++++++
|
||||
src/lib-imap/test-imap-bodystructure.c | 15 +++++++++++++++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/src/lib-imap/imap-bodystructure.c b/src/lib-imap/imap-bodystructure.c
|
||||
index ab422c00d2..bfb6e64197 100644
|
||||
--- a/src/lib-imap/imap-bodystructure.c
|
||||
+++ b/src/lib-imap/imap-bodystructure.c
|
||||
@@ -147,6 +147,7 @@ static bool part_is_truncated(const struct message_part *part)
|
||||
const struct message_part_data *data = part->data;
|
||||
|
||||
i_assert((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0);
|
||||
+ i_assert((part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0);
|
||||
|
||||
if (data->content_type != NULL) {
|
||||
if (strcasecmp(data->content_type, "message") == 0 &&
|
||||
@@ -155,6 +156,11 @@ static bool part_is_truncated(const struct message_part *part)
|
||||
MESSAGE_PART_FLAG_MESSAGE_RFC822. */
|
||||
return TRUE;
|
||||
}
|
||||
+ if (strcasecmp(data->content_type, "multipart") == 0) {
|
||||
+ /* It's multipart/, but without
|
||||
+ MESSAGE_PART_FLAG_MULTIPART. */
|
||||
+ return TRUE;
|
||||
+ }
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
diff --git a/src/lib-imap/test-imap-bodystructure.c b/src/lib-imap/test-imap-bodystructure.c
|
||||
index 6cb699e126..2118907e78 100644
|
||||
--- a/src/lib-imap/test-imap-bodystructure.c
|
||||
+++ b/src/lib-imap/test-imap-bodystructure.c
|
||||
@@ -556,6 +556,21 @@ static const struct {
|
||||
.bodystructure = "\"message\" \"rfc822\" NIL NIL NIL \"7bit\" 159 (NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) (\"application\" \"octet-stream\" NIL NIL NIL \"7bit\" 110 NIL NIL NIL NIL) 11 NIL NIL NIL NIL",
|
||||
.max_depth = 2,
|
||||
},
|
||||
+ {
|
||||
+ .input = "Content-Type: multipart/mixed; boundary=1\n"
|
||||
+ "\n"
|
||||
+ "--1\n"
|
||||
+ "Content-Type: multipart/mixed; boundary=2\n"
|
||||
+ "\n"
|
||||
+ "--2\n"
|
||||
+ "Content-Type: multipart/mixed; boundary=3\n"
|
||||
+ "\n"
|
||||
+ "--3\n"
|
||||
+ "\n"
|
||||
+ "body\n",
|
||||
+ .bodystructure = "(\"application\" \"octet-stream\" (\"boundary\" \"2\") NIL NIL \"7bit\" 63 NIL NIL NIL NIL) \"mixed\" (\"boundary\" \"1\") NIL NIL NIL",
|
||||
+ .max_depth = 2,
|
||||
+ },
|
||||
};
|
||||
|
||||
static void test_imap_bodystructure_truncation(void)
|
@ -1,127 +0,0 @@
|
||||
From a912198bdc38421ad84044089db84fc14c69c228 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Wed, 18 Nov 2020 21:22:45 +0200
|
||||
Subject: [PATCH] lib-imap: Fix writing BODYSTRUCTURE for truncated
|
||||
multipart/digest part
|
||||
|
||||
Fixes error while parsing BODYSTRUCTURE:
|
||||
message_part message/rfc822 flag doesn't match lines in BODYSTRUCTURE
|
||||
---
|
||||
src/lib-imap/imap-bodystructure.c | 9 +++++++++
|
||||
src/lib-imap/test-imap-bodystructure.c | 28 ++++++++++++++++++++++----
|
||||
2 files changed, 33 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/lib-imap/imap-bodystructure.c b/src/lib-imap/imap-bodystructure.c
|
||||
index bfb6e64197..5d2e5a3a84 100644
|
||||
--- a/src/lib-imap/imap-bodystructure.c
|
||||
+++ b/src/lib-imap/imap-bodystructure.c
|
||||
@@ -161,6 +161,14 @@ static bool part_is_truncated(const struct message_part *part)
|
||||
MESSAGE_PART_FLAG_MULTIPART. */
|
||||
return TRUE;
|
||||
}
|
||||
+ } else {
|
||||
+ /* No Content-Type */
|
||||
+ if (part->parent != NULL &&
|
||||
+ (part->parent->flags & MESSAGE_PART_FLAG_MULTIPART_DIGEST) != 0) {
|
||||
+ /* Parent is MESSAGE_PART_FLAG_MULTIPART_DIGEST
|
||||
+ (so this should have been message/rfc822). */
|
||||
+ return TRUE;
|
||||
+ }
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -195,6 +203,7 @@ static void part_write_body(const struct message_part *part,
|
||||
str_append_c(str, ' ');
|
||||
imap_append_string(str, data->content_subtype);
|
||||
}
|
||||
+ i_assert(text == ((part->flags & MESSAGE_PART_FLAG_TEXT) != 0));
|
||||
}
|
||||
|
||||
/* ("content type param key" "value" ...) */
|
||||
diff --git a/src/lib-imap/test-imap-bodystructure.c b/src/lib-imap/test-imap-bodystructure.c
|
||||
index 2118907e78..0f70cb0035 100644
|
||||
--- a/src/lib-imap/test-imap-bodystructure.c
|
||||
+++ b/src/lib-imap/test-imap-bodystructure.c
|
||||
@@ -381,13 +381,14 @@ static const unsigned int normalize_tests_count = N_ELEMENTS(normalize_tests);
|
||||
|
||||
static struct message_part *
|
||||
msg_parse(pool_t pool, const char *message, unsigned int max_nested_mime_parts,
|
||||
- bool parse_bodystructure)
|
||||
+ unsigned int max_total_mime_parts, bool parse_bodystructure)
|
||||
{
|
||||
const struct message_parser_settings parser_set = {
|
||||
.hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
|
||||
MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
|
||||
.flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
|
||||
.max_nested_mime_parts = max_nested_mime_parts,
|
||||
+ .max_total_mime_parts = max_total_mime_parts,
|
||||
};
|
||||
struct message_parser_ctx *parser;
|
||||
struct istream *input;
|
||||
@@ -421,7 +422,7 @@ static void test_imap_bodystructure_write(void)
|
||||
pool_t pool = pool_alloconly_create("imap bodystructure write", 1024);
|
||||
|
||||
test_begin(t_strdup_printf("imap bodystructure write [%u]", i));
|
||||
- parts = msg_parse(pool, test->message, 0, TRUE);
|
||||
+ parts = msg_parse(pool, test->message, 0, 0, TRUE);
|
||||
|
||||
imap_bodystructure_write(parts, str, TRUE);
|
||||
test_assert(strcmp(str_c(str), test->bodystructure) == 0);
|
||||
@@ -448,7 +449,7 @@ static void test_imap_bodystructure_parse(void)
|
||||
pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024);
|
||||
|
||||
test_begin(t_strdup_printf("imap bodystructure parser [%u]", i));
|
||||
- parts = msg_parse(pool, test->message, 0, FALSE);
|
||||
+ parts = msg_parse(pool, test->message, 0, 0, FALSE);
|
||||
|
||||
test_assert(imap_body_parse_from_bodystructure(test->bodystructure,
|
||||
str, &error) == 0);
|
||||
@@ -515,7 +516,7 @@ static void test_imap_bodystructure_normalize(void)
|
||||
pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024);
|
||||
|
||||
test_begin(t_strdup_printf("imap bodystructure normalize [%u]", i));
|
||||
- parts = msg_parse(pool, test->message, 0, FALSE);
|
||||
+ parts = msg_parse(pool, test->message, 0, 0, FALSE);
|
||||
|
||||
ret = imap_bodystructure_parse(test->input,
|
||||
pool, parts, &error);
|
||||
@@ -538,6 +539,7 @@ static const struct {
|
||||
const char *input;
|
||||
const char *bodystructure;
|
||||
unsigned int max_depth;
|
||||
+ unsigned int max_total;
|
||||
} truncation_tests[] = {
|
||||
{
|
||||
.input = "Content-Type: message/rfc822\n"
|
||||
@@ -571,6 +573,23 @@ static const struct {
|
||||
.bodystructure = "(\"application\" \"octet-stream\" (\"boundary\" \"2\") NIL NIL \"7bit\" 63 NIL NIL NIL NIL) \"mixed\" (\"boundary\" \"1\") NIL NIL NIL",
|
||||
.max_depth = 2,
|
||||
},
|
||||
+ {
|
||||
+ .input = "Content-Type: multipart/digest; boundary=1\n"
|
||||
+ "\n"
|
||||
+ "--1\n"
|
||||
+ "\n"
|
||||
+ "Subject: hdr1\n"
|
||||
+ "\n"
|
||||
+ "body1\n"
|
||||
+ "--1\n"
|
||||
+ "\n"
|
||||
+ "Subject: hdr2\n"
|
||||
+ "\n"
|
||||
+ "body2\n",
|
||||
+ .bodystructure = "(\"application\" \"octet-stream\" NIL NIL NIL \"7bit\" 55 NIL NIL NIL NIL) \"digest\" (\"boundary\" \"1\") NIL NIL NIL",
|
||||
+ .max_total = 2,
|
||||
+ },
|
||||
+
|
||||
};
|
||||
|
||||
static void test_imap_bodystructure_truncation(void)
|
||||
@@ -590,6 +609,7 @@ static void test_imap_bodystructure_truncation(void)
|
||||
|
||||
parts = msg_parse(pool, truncation_tests[i].input,
|
||||
truncation_tests[i].max_depth,
|
||||
+ truncation_tests[i].max_total,
|
||||
TRUE);
|
||||
|
||||
/* write out BODYSTRUCTURE and serialize message_parts */
|
53
SOURCES/dovecot-2.3.16-ftbfsbigend.patch
Normal file
53
SOURCES/dovecot-2.3.16-ftbfsbigend.patch
Normal file
@ -0,0 +1,53 @@
|
||||
commit ec4595097067a736717ef202fe8542b1b4bc2dd5
|
||||
Author: Timo Sirainen <timo.sirainen@open-xchange.com>
|
||||
Date: Tue Aug 10 12:22:08 2021 +0300
|
||||
|
||||
lib-index: Fix storing cache fields' last_used with 64bit big endian CPUs
|
||||
|
||||
diff --git a/src/lib-index/mail-cache-fields.c b/src/lib-index/mail-cache-fields.c
|
||||
index e929fb559d..429e0d234c 100644
|
||||
--- a/src/lib-index/mail-cache-fields.c
|
||||
+++ b/src/lib-index/mail-cache-fields.c
|
||||
@@ -524,6 +524,19 @@ static void copy_to_buf_byte(struct mail_cache *cache, buffer_t *dest,
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+copy_to_buf_last_used(struct mail_cache *cache, buffer_t *dest, bool add_new)
|
||||
+{
|
||||
+ size_t offset = offsetof(struct mail_cache_field, last_used);
|
||||
+#if defined(WORDS_BIGENDIAN) && SIZEOF_VOID_P == 8
|
||||
+ /* 64bit time_t with big endian CPUs: copy the last 32 bits instead of
|
||||
+ the first 32 bits (that are always 0). The 32 bits are enough until
|
||||
+ year 2106, so we're not in a hurry to use 64 bits on disk. */
|
||||
+ offset += sizeof(uint32_t);
|
||||
+#endif
|
||||
+ copy_to_buf(cache, dest, add_new, offset, sizeof(uint32_t));
|
||||
+}
|
||||
+
|
||||
static int mail_cache_header_fields_update_locked(struct mail_cache *cache)
|
||||
{
|
||||
buffer_t *buffer;
|
||||
@@ -536,9 +549,7 @@ static int mail_cache_header_fields_update_locked(struct mail_cache *cache)
|
||||
|
||||
buffer = t_buffer_create(256);
|
||||
|
||||
- copy_to_buf(cache, buffer, FALSE,
|
||||
- offsetof(struct mail_cache_field, last_used),
|
||||
- sizeof(uint32_t));
|
||||
+ copy_to_buf_last_used(cache, buffer, FALSE);
|
||||
ret = mail_cache_write(cache, buffer->data, buffer->used,
|
||||
offset + MAIL_CACHE_FIELD_LAST_USED());
|
||||
if (ret == 0) {
|
||||
@@ -599,9 +610,7 @@ void mail_cache_header_fields_get(struct mail_cache *cache, buffer_t *dest)
|
||||
buffer_append(dest, &hdr, sizeof(hdr));
|
||||
|
||||
/* we have to keep the field order for the existing fields. */
|
||||
- copy_to_buf(cache, dest, TRUE,
|
||||
- offsetof(struct mail_cache_field, last_used),
|
||||
- sizeof(uint32_t));
|
||||
+ copy_to_buf_last_used(cache, dest, TRUE);
|
||||
copy_to_buf(cache, dest, TRUE,
|
||||
offsetof(struct mail_cache_field, field_size),
|
||||
sizeof(uint32_t));
|
||||
|
353
SOURCES/dovecot-2.3.16-keeplzma.patch
Normal file
353
SOURCES/dovecot-2.3.16-keeplzma.patch
Normal file
@ -0,0 +1,353 @@
|
||||
diff -up dovecot-2.3.16/configure.ac.keeplzma dovecot-2.3.16/configure.ac
|
||||
--- dovecot-2.3.16/configure.ac.keeplzma 2021-08-06 11:25:51.000000000 +0200
|
||||
+++ dovecot-2.3.16/configure.ac 2022-02-28 13:58:02.337149927 +0100
|
||||
@@ -173,7 +173,7 @@ AS_HELP_STRING([--with-bzlib], [Build wi
|
||||
want_bzlib=auto)
|
||||
|
||||
AC_ARG_WITH(lzma,
|
||||
-AS_HELP_STRING([--with-lzma], [Build with LZMA decompression support (auto)]),
|
||||
+AS_HELP_STRING([--with-lzma], [Build with LZMA compression support (auto)]),
|
||||
TEST_WITH(lzma, $withval),
|
||||
want_lzma=auto)
|
||||
|
||||
diff -up dovecot-2.3.16/run-test-valgrind.supp.keeplzma dovecot-2.3.16/run-test-valgrind.supp
|
||||
--- dovecot-2.3.16/run-test-valgrind.supp.keeplzma 2021-08-06 11:25:51.000000000 +0200
|
||||
+++ dovecot-2.3.16/run-test-valgrind.supp 2022-02-28 13:58:02.337149927 +0100
|
||||
@@ -5,6 +5,17 @@
|
||||
obj:*/bash
|
||||
}
|
||||
{
|
||||
+ <liblzma>
|
||||
+ Memcheck:Cond
|
||||
+ obj:/lib/x86_64-linux-gnu/liblzma.so.5.*
|
||||
+ obj:/lib/x86_64-linux-gnu/liblzma.so.5.*
|
||||
+ obj:/lib/x86_64-linux-gnu/liblzma.so.5.*
|
||||
+ obj:/lib/x86_64-linux-gnu/liblzma.so.5.*
|
||||
+ obj:/lib/x86_64-linux-gnu/liblzma.so.5.*
|
||||
+ fun:lzma_stream_encoder
|
||||
+ fun:lzma_easy_encoder
|
||||
+}
|
||||
+{
|
||||
<openssl_centos6_i386_v1_0_1_compression_methods>
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
diff -up dovecot-2.3.16/src/lib-compression/compression.c.keeplzma dovecot-2.3.16/src/lib-compression/compression.c
|
||||
--- dovecot-2.3.16/src/lib-compression/compression.c.keeplzma 2021-08-06 11:25:51.000000000 +0200
|
||||
+++ dovecot-2.3.16/src/lib-compression/compression.c 2022-02-28 14:22:32.467944396 +0100
|
||||
@@ -25,6 +25,7 @@
|
||||
#endif
|
||||
#ifndef HAVE_LZMA
|
||||
# define i_stream_create_lzma NULL
|
||||
+# define o_stream_create_lzma NULL
|
||||
#endif
|
||||
#ifndef HAVE_LZ4
|
||||
# define i_stream_create_lz4 NULL
|
||||
@@ -216,7 +217,7 @@ const struct compression_handler compres
|
||||
.ext = ".xz",
|
||||
.is_compressed = is_compressed_xz,
|
||||
.create_istream = i_stream_create_lzma,
|
||||
- .create_ostream = NULL,
|
||||
+ .create_ostream = o_stream_create_lzma,
|
||||
.get_min_level = compression_get_min_level_unsupported,
|
||||
.get_default_level = compression_get_default_level_unsupported,
|
||||
.get_max_level = compression_get_max_level_unsupported,
|
||||
diff -up dovecot-2.3.16/src/lib-compression/Makefile.am.keeplzma dovecot-2.3.16/src/lib-compression/Makefile.am
|
||||
--- dovecot-2.3.16/src/lib-compression/Makefile.am.keeplzma 2021-08-06 11:25:51.000000000 +0200
|
||||
+++ dovecot-2.3.16/src/lib-compression/Makefile.am 2022-02-28 13:58:02.337149927 +0100
|
||||
@@ -13,6 +13,7 @@ libcompression_la_SOURCES = \
|
||||
istream-zlib.c \
|
||||
istream-bzlib.c \
|
||||
istream-zstd.c \
|
||||
+ ostream-lzma.c \
|
||||
ostream-lz4.c \
|
||||
ostream-zlib.c \
|
||||
ostream-bzlib.c \
|
||||
diff -up dovecot-2.3.16/src/lib-compression/ostream-lzma.c.keeplzma dovecot-2.3.16/src/lib-compression/ostream-lzma.c
|
||||
--- dovecot-2.3.16/src/lib-compression/ostream-lzma.c.keeplzma 2022-02-28 13:58:02.338149934 +0100
|
||||
+++ dovecot-2.3.16/src/lib-compression/ostream-lzma.c 2022-02-28 13:58:02.338149934 +0100
|
||||
@@ -0,0 +1,263 @@
|
||||
+/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
|
||||
+
|
||||
+#include "lib.h"
|
||||
+
|
||||
+#ifdef HAVE_LZMA
|
||||
+
|
||||
+#include "ostream-private.h"
|
||||
+#include "ostream-zlib.h"
|
||||
+#include <lzma.h>
|
||||
+
|
||||
+#define CHUNK_SIZE (1024*64)
|
||||
+
|
||||
+struct lzma_ostream {
|
||||
+ struct ostream_private ostream;
|
||||
+ lzma_stream strm;
|
||||
+
|
||||
+ unsigned char outbuf[CHUNK_SIZE];
|
||||
+ unsigned int outbuf_offset, outbuf_used;
|
||||
+
|
||||
+ bool flushed:1;
|
||||
+};
|
||||
+
|
||||
+static void o_stream_lzma_close(struct iostream_private *stream,
|
||||
+ bool close_parent)
|
||||
+{
|
||||
+ struct lzma_ostream *zstream = (struct lzma_ostream *)stream;
|
||||
+ i_assert(zstream->ostream.finished ||
|
||||
+ zstream->ostream.ostream.stream_errno != 0 ||
|
||||
+ zstream->ostream.error_handling_disabled);
|
||||
+ lzma_end(&zstream->strm);
|
||||
+ if (close_parent)
|
||||
+ o_stream_close(zstream->ostream.parent);
|
||||
+}
|
||||
+
|
||||
+static int o_stream_zlib_send_outbuf(struct lzma_ostream *zstream)
|
||||
+{
|
||||
+ ssize_t ret;
|
||||
+ size_t size;
|
||||
+
|
||||
+ if (zstream->outbuf_used == 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ size = zstream->outbuf_used - zstream->outbuf_offset;
|
||||
+ i_assert(size > 0);
|
||||
+ ret = o_stream_send(zstream->ostream.parent,
|
||||
+ zstream->outbuf + zstream->outbuf_offset, size);
|
||||
+ if (ret < 0) {
|
||||
+ o_stream_copy_error_from_parent(&zstream->ostream);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if ((size_t)ret != size) {
|
||||
+ zstream->outbuf_offset += ret;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ zstream->outbuf_offset = 0;
|
||||
+ zstream->outbuf_used = 0;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
+o_stream_lzma_send_chunk(struct lzma_ostream *zstream,
|
||||
+ const void *data, size_t size)
|
||||
+{
|
||||
+ lzma_stream *zs = &zstream->strm;
|
||||
+ int ret;
|
||||
+
|
||||
+ i_assert(zstream->outbuf_used == 0);
|
||||
+
|
||||
+ zs->next_in = (void *)data;
|
||||
+ zs->avail_in = size;
|
||||
+ while (zs->avail_in > 0) {
|
||||
+ if (zs->avail_out == 0) {
|
||||
+ /* previous block was compressed. send it and start
|
||||
+ compression for a new block. */
|
||||
+ zs->next_out = zstream->outbuf;
|
||||
+ zs->avail_out = sizeof(zstream->outbuf);
|
||||
+
|
||||
+ zstream->outbuf_used = sizeof(zstream->outbuf);
|
||||
+ if ((ret = o_stream_zlib_send_outbuf(zstream)) < 0)
|
||||
+ return -1;
|
||||
+ if (ret == 0) {
|
||||
+ /* parent stream's buffer full */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = lzma_code(zs, LZMA_RUN);
|
||||
+ switch (ret) {
|
||||
+ case LZMA_OK:
|
||||
+ break;
|
||||
+ case LZMA_MEM_ERROR:
|
||||
+ i_fatal_status(FATAL_OUTOFMEM,
|
||||
+ "lzma.write(%s): Out of memory",
|
||||
+ o_stream_get_name(&zstream->ostream.ostream));
|
||||
+ default:
|
||||
+ i_panic("lzma.write(%s) failed with unexpected code %d",
|
||||
+ o_stream_get_name(&zstream->ostream.ostream), ret);
|
||||
+ }
|
||||
+ }
|
||||
+ size -= zs->avail_in;
|
||||
+
|
||||
+ return size;
|
||||
+}
|
||||
+
|
||||
+static int o_stream_lzma_send_flush(struct lzma_ostream *zstream, bool final)
|
||||
+{
|
||||
+ lzma_stream *zs = &zstream->strm;
|
||||
+ size_t len;
|
||||
+ bool done = FALSE;
|
||||
+ int ret;
|
||||
+
|
||||
+ i_assert(zs->avail_in == 0);
|
||||
+
|
||||
+ if (zstream->flushed) {
|
||||
+ i_assert(zstream->outbuf_used == 0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if ((ret = o_stream_flush_parent_if_needed(&zstream->ostream)) <= 0)
|
||||
+ return ret;
|
||||
+ if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!final)
|
||||
+ return 1;
|
||||
+
|
||||
+ i_assert(zstream->outbuf_used == 0);
|
||||
+ do {
|
||||
+ len = sizeof(zstream->outbuf) - zs->avail_out;
|
||||
+ if (len != 0) {
|
||||
+ zs->next_out = zstream->outbuf;
|
||||
+ zs->avail_out = sizeof(zstream->outbuf);
|
||||
+
|
||||
+ zstream->outbuf_used = len;
|
||||
+ if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0)
|
||||
+ return ret;
|
||||
+ if (done)
|
||||
+ break;
|
||||
+ }
|
||||
+ ret = lzma_code(zs, LZMA_FINISH);
|
||||
+ switch (ret) {
|
||||
+ case LZMA_OK:
|
||||
+ /* still unfinished - need to call lzma_code() again */
|
||||
+ break;
|
||||
+ case LZMA_STREAM_END:
|
||||
+ /* output is fully finished */
|
||||
+ done = TRUE;
|
||||
+ break;
|
||||
+ case LZMA_MEM_ERROR:
|
||||
+ i_fatal_status(FATAL_OUTOFMEM,
|
||||
+ "lzma.write(%s): Out of memory",
|
||||
+ o_stream_get_name(&zstream->ostream.ostream));
|
||||
+ default:
|
||||
+ i_panic("lzma.write(%s) flush failed with unexpected code %d",
|
||||
+ o_stream_get_name(&zstream->ostream.ostream), ret);
|
||||
+ }
|
||||
+ } while (zs->avail_out != sizeof(zstream->outbuf));
|
||||
+
|
||||
+ if (final)
|
||||
+ zstream->flushed = TRUE;
|
||||
+ i_assert(zstream->outbuf_used == 0);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int o_stream_lzma_flush(struct ostream_private *stream)
|
||||
+{
|
||||
+ struct lzma_ostream *zstream = (struct lzma_ostream *)stream;
|
||||
+ int ret;
|
||||
+
|
||||
+ if ((ret = o_stream_lzma_send_flush(zstream, stream->finished)) < 0)
|
||||
+ return -1;
|
||||
+ else if (ret > 0)
|
||||
+ return o_stream_flush_parent(stream);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static size_t
|
||||
+o_stream_lzma_get_buffer_used_size(const struct ostream_private *stream)
|
||||
+{
|
||||
+ const struct lzma_ostream *zstream =
|
||||
+ (const struct lzma_ostream *)stream;
|
||||
+
|
||||
+ /* outbuf has already compressed data that we're trying to send to the
|
||||
+ parent stream. We're not including lzma's internal compression
|
||||
+ buffer size. */
|
||||
+ return (zstream->outbuf_used - zstream->outbuf_offset) +
|
||||
+ o_stream_get_buffer_used_size(stream->parent);
|
||||
+}
|
||||
+
|
||||
+static size_t
|
||||
+o_stream_lzma_get_buffer_avail_size(const struct ostream_private *stream)
|
||||
+{
|
||||
+ /* FIXME: not correct - this is counting compressed size, which may be
|
||||
+ too larger than uncompressed size in some situations. Fixing would
|
||||
+ require some kind of additional buffering. */
|
||||
+ return o_stream_get_buffer_avail_size(stream->parent);
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
+o_stream_lzma_sendv(struct ostream_private *stream,
|
||||
+ const struct const_iovec *iov, unsigned int iov_count)
|
||||
+{
|
||||
+ struct lzma_ostream *zstream = (struct lzma_ostream *)stream;
|
||||
+ ssize_t ret, bytes = 0;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) {
|
||||
+ /* error / we still couldn't flush existing data to
|
||||
+ parent stream. */
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < iov_count; i++) {
|
||||
+ ret = o_stream_lzma_send_chunk(zstream, iov[i].iov_base,
|
||||
+ iov[i].iov_len);
|
||||
+ if (ret < 0)
|
||||
+ return -1;
|
||||
+ bytes += ret;
|
||||
+ if ((size_t)ret != iov[i].iov_len)
|
||||
+ break;
|
||||
+ }
|
||||
+ stream->ostream.offset += bytes;
|
||||
+
|
||||
+ /* avail_in!=0 check is used to detect errors. if it's non-zero here
|
||||
+ it simply means we didn't send all the data */
|
||||
+ zstream->strm.avail_in = 0;
|
||||
+ return bytes;
|
||||
+}
|
||||
+
|
||||
+struct ostream *o_stream_create_lzma(struct ostream *output, int level)
|
||||
+{
|
||||
+ struct lzma_ostream *zstream;
|
||||
+ lzma_ret ret;
|
||||
+
|
||||
+ i_assert(level >= 1 && level <= 9);
|
||||
+
|
||||
+ zstream = i_new(struct lzma_ostream, 1);
|
||||
+ zstream->ostream.sendv = o_stream_lzma_sendv;
|
||||
+ zstream->ostream.flush = o_stream_lzma_flush;
|
||||
+ zstream->ostream.get_buffer_used_size =
|
||||
+ o_stream_lzma_get_buffer_used_size;
|
||||
+ zstream->ostream.get_buffer_avail_size =
|
||||
+ o_stream_lzma_get_buffer_avail_size;
|
||||
+ zstream->ostream.iostream.close = o_stream_lzma_close;
|
||||
+
|
||||
+ ret = lzma_easy_encoder(&zstream->strm, level, LZMA_CHECK_CRC64);
|
||||
+ switch (ret) {
|
||||
+ case LZMA_OK:
|
||||
+ break;
|
||||
+ case LZMA_MEM_ERROR:
|
||||
+ i_fatal_status(FATAL_OUTOFMEM, "lzma: Out of memory");
|
||||
+ case LZMA_OPTIONS_ERROR:
|
||||
+ i_fatal("lzma: Invalid level");
|
||||
+ default:
|
||||
+ i_fatal("lzma_easy_encoder() failed with %d", ret);
|
||||
+ }
|
||||
+
|
||||
+ zstream->strm.next_out = zstream->outbuf;
|
||||
+ zstream->strm.avail_out = sizeof(zstream->outbuf);
|
||||
+ return o_stream_create(&zstream->ostream, output,
|
||||
+ o_stream_get_fd(output));
|
||||
+}
|
||||
+#endif
|
||||
diff -up dovecot-2.3.16/src/lib-compression/ostream-zlib.h.keeplzma dovecot-2.3.16/src/lib-compression/ostream-zlib.h
|
||||
--- dovecot-2.3.16/src/lib-compression/ostream-zlib.h.keeplzma 2021-08-06 11:25:51.000000000 +0200
|
||||
+++ dovecot-2.3.16/src/lib-compression/ostream-zlib.h 2022-02-28 13:58:02.338149934 +0100
|
||||
@@ -4,6 +4,7 @@
|
||||
struct ostream *o_stream_create_gz(struct ostream *output, int level);
|
||||
struct ostream *o_stream_create_deflate(struct ostream *output, int level);
|
||||
struct ostream *o_stream_create_bz2(struct ostream *output, int level);
|
||||
+struct ostream *o_stream_create_lzma(struct ostream *output, int level);
|
||||
struct ostream *o_stream_create_lz4(struct ostream *output, int level);
|
||||
struct ostream *o_stream_create_zstd(struct ostream *output, int level);
|
||||
|
||||
diff -up dovecot-2.3.16/src/lib-compression/test-compression.c.keeplzma dovecot-2.3.16/src/lib-compression/test-compression.c
|
||||
--- dovecot-2.3.16/src/lib-compression/test-compression.c.keeplzma 2021-08-06 11:25:51.000000000 +0200
|
||||
+++ dovecot-2.3.16/src/lib-compression/test-compression.c 2022-02-28 13:58:02.338149934 +0100
|
||||
@@ -730,7 +730,6 @@ static void test_compression_int(bool au
|
||||
|
||||
for (i = 0; compression_handlers[i].name != NULL; i++) {
|
||||
if (compression_handlers[i].create_istream != NULL &&
|
||||
- compression_handlers[i].create_ostream != NULL &&
|
||||
(!autodetect ||
|
||||
compression_handlers[i].is_compressed != NULL)) T_BEGIN {
|
||||
if (compression_handlers[i].is_compressed != NULL &&
|
@ -1,6 +1,6 @@
|
||||
diff -up dovecot-2.3.8/src/auth/auth-token.c.opensslhmac dovecot-2.3.8/src/auth/auth-token.c
|
||||
--- dovecot-2.3.8/src/auth/auth-token.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/auth-token.c 2019-11-19 16:34:11.338037002 +0100
|
||||
diff -up dovecot-2.3.14/src/auth/auth-token.c.opensslhmac dovecot-2.3.14/src/auth/auth-token.c
|
||||
--- dovecot-2.3.14/src/auth/auth-token.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/auth/auth-token.c 2021-03-22 20:44:13.022912242 +0100
|
||||
@@ -161,17 +161,17 @@ void auth_token_deinit(void)
|
||||
const char *auth_token_get(const char *service, const char *session_pid,
|
||||
const char *username, const char *session_id)
|
||||
@ -26,9 +26,9 @@ diff -up dovecot-2.3.8/src/auth/auth-token.c.opensslhmac dovecot-2.3.8/src/auth/
|
||||
|
||||
return binary_to_hex(result, sizeof(result));
|
||||
}
|
||||
diff -up dovecot-2.3.8/src/auth/mech-cram-md5.c.opensslhmac dovecot-2.3.8/src/auth/mech-cram-md5.c
|
||||
--- dovecot-2.3.8/src/auth/mech-cram-md5.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/mech-cram-md5.c 2019-11-19 16:34:11.338037002 +0100
|
||||
diff -up dovecot-2.3.14/src/auth/mech-cram-md5.c.opensslhmac dovecot-2.3.14/src/auth/mech-cram-md5.c
|
||||
--- dovecot-2.3.14/src/auth/mech-cram-md5.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/auth/mech-cram-md5.c 2021-03-22 20:44:13.022912242 +0100
|
||||
@@ -51,7 +51,7 @@ static bool verify_credentials(struct cr
|
||||
{
|
||||
|
||||
@ -52,59 +52,57 @@ diff -up dovecot-2.3.8/src/auth/mech-cram-md5.c.opensslhmac dovecot-2.3.8/src/au
|
||||
|
||||
response_hex = binary_to_hex(digest, sizeof(digest));
|
||||
|
||||
diff -up dovecot-2.3.8/src/auth/mech-scram-sha1.c.opensslhmac dovecot-2.3.8/src/auth/mech-scram-sha1.c
|
||||
--- dovecot-2.3.8/src/auth/mech-scram-sha1.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/mech-scram-sha1.c 2019-11-19 16:34:11.338037002 +0100
|
||||
@@ -71,7 +71,7 @@ static const char *get_scram_server_firs
|
||||
|
||||
diff -up dovecot-2.3.14/src/auth/mech-scram.c.opensslhmac dovecot-2.3.14/src/auth/mech-scram.c
|
||||
--- dovecot-2.3.14/src/auth/mech-scram.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/auth/mech-scram.c 2021-03-22 20:44:13.022912242 +0100
|
||||
@@ -78,7 +78,7 @@ static const char *get_scram_server_firs
|
||||
static const char *get_scram_server_final(struct scram_auth_request *request)
|
||||
{
|
||||
const struct hash_method *hmethod = request->hash_method;
|
||||
- struct hmac_context ctx;
|
||||
+ struct openssl_hmac_context ctx;
|
||||
const char *auth_message;
|
||||
unsigned char server_signature[SHA1_RESULTLEN];
|
||||
unsigned char server_signature[hmethod->digest_size];
|
||||
string_t *str;
|
||||
@@ -80,10 +80,10 @@ static const char *get_scram_server_fina
|
||||
@@ -87,9 +87,9 @@ static const char *get_scram_server_fina
|
||||
request->server_first_message, ",",
|
||||
request->client_final_message_without_proof, NULL);
|
||||
|
||||
- hmac_init(&ctx, request->server_key, sizeof(request->server_key),
|
||||
+ openssl_hmac_init(&ctx, request->server_key, sizeof(request->server_key),
|
||||
&hash_method_sha1);
|
||||
- hmac_init(&ctx, request->server_key, hmethod->digest_size, hmethod);
|
||||
- hmac_update(&ctx, auth_message, strlen(auth_message));
|
||||
- hmac_final(&ctx, server_signature);
|
||||
+ openssl_hmac_init(&ctx, request->server_key, hmethod->digest_size, hmethod);
|
||||
+ openssl_hmac_update(&ctx, auth_message, strlen(auth_message));
|
||||
+ openssl_hmac_final(&ctx, server_signature);
|
||||
|
||||
str = t_str_new(MAX_BASE64_ENCODED_SIZE(sizeof(server_signature)));
|
||||
str_append(str, "v=");
|
||||
@@ -221,7 +221,7 @@ static bool parse_scram_client_first(str
|
||||
|
||||
@@ -228,7 +228,7 @@ static bool parse_scram_client_first(str
|
||||
static bool verify_credentials(struct scram_auth_request *request)
|
||||
{
|
||||
const struct hash_method *hmethod = request->hash_method;
|
||||
- struct hmac_context ctx;
|
||||
+ struct openssl_hmac_context ctx;
|
||||
const char *auth_message;
|
||||
unsigned char client_key[SHA1_RESULTLEN];
|
||||
unsigned char client_signature[SHA1_RESULTLEN];
|
||||
@@ -232,10 +232,10 @@ static bool verify_credentials(struct sc
|
||||
unsigned char client_key[hmethod->digest_size];
|
||||
unsigned char client_signature[hmethod->digest_size];
|
||||
@@ -239,9 +239,9 @@ static bool verify_credentials(struct sc
|
||||
request->server_first_message, ",",
|
||||
request->client_final_message_without_proof, NULL);
|
||||
|
||||
- hmac_init(&ctx, request->stored_key, sizeof(request->stored_key),
|
||||
+ openssl_hmac_init(&ctx, request->stored_key, sizeof(request->stored_key),
|
||||
&hash_method_sha1);
|
||||
- hmac_init(&ctx, request->stored_key, hmethod->digest_size, hmethod);
|
||||
- hmac_update(&ctx, auth_message, strlen(auth_message));
|
||||
- hmac_final(&ctx, client_signature);
|
||||
+ openssl_hmac_init(&ctx, request->stored_key, hmethod->digest_size, hmethod);
|
||||
+ openssl_hmac_update(&ctx, auth_message, strlen(auth_message));
|
||||
+ openssl_hmac_final(&ctx, client_signature);
|
||||
|
||||
const unsigned char *proof_data = request->proof->data;
|
||||
for (i = 0; i < sizeof(client_signature); i++)
|
||||
client_key[i] =
|
||||
diff -up dovecot-2.3.8/src/auth/password-scheme.c.opensslhmac dovecot-2.3.8/src/auth/password-scheme.c
|
||||
--- dovecot-2.3.8/src/auth/password-scheme.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/password-scheme.c 2019-11-19 16:34:11.339036998 +0100
|
||||
@@ -647,11 +647,11 @@ static void
|
||||
diff -up dovecot-2.3.14/src/auth/password-scheme.c.opensslhmac dovecot-2.3.14/src/auth/password-scheme.c
|
||||
--- dovecot-2.3.14/src/auth/password-scheme.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/auth/password-scheme.c 2021-03-22 20:44:13.022912242 +0100
|
||||
@@ -639,11 +639,11 @@ static void
|
||||
cram_md5_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED,
|
||||
const unsigned char **raw_password_r, size_t *size_r)
|
||||
{
|
||||
@ -118,104 +116,101 @@ diff -up dovecot-2.3.8/src/auth/password-scheme.c.opensslhmac dovecot-2.3.8/src/
|
||||
strlen(plaintext), &hash_method_md5);
|
||||
hmac_md5_get_cram_context(&ctx, context_digest);
|
||||
|
||||
diff -up dovecot-2.3.8/src/auth/password-scheme-scram.c.opensslhmac dovecot-2.3.8/src/auth/password-scheme-scram.c
|
||||
--- dovecot-2.3.8/src/auth/password-scheme-scram.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/password-scheme-scram.c 2019-11-19 16:34:11.339036998 +0100
|
||||
@@ -27,23 +27,23 @@ static void Hi(const unsigned char *str,
|
||||
diff -up dovecot-2.3.14/src/auth/password-scheme-scram.c.opensslhmac dovecot-2.3.14/src/auth/password-scheme-scram.c
|
||||
--- dovecot-2.3.14/src/auth/password-scheme-scram.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/auth/password-scheme-scram.c 2021-03-22 20:44:13.023912229 +0100
|
||||
@@ -30,23 +30,23 @@ Hi(const struct hash_method *hmethod, co
|
||||
const unsigned char *salt, size_t salt_size, unsigned int i,
|
||||
unsigned char result[SHA1_RESULTLEN])
|
||||
unsigned char *result)
|
||||
{
|
||||
- struct hmac_context ctx;
|
||||
+ struct openssl_hmac_context ctx;
|
||||
unsigned char U[SHA1_RESULTLEN];
|
||||
unsigned char U[hmethod->digest_size];
|
||||
unsigned int j, k;
|
||||
|
||||
/* Calculate U1 */
|
||||
- hmac_init(&ctx, str, str_size, &hash_method_sha1);
|
||||
- hmac_init(&ctx, str, str_size, hmethod);
|
||||
- hmac_update(&ctx, salt, salt_size);
|
||||
- hmac_update(&ctx, "\0\0\0\1", 4);
|
||||
- hmac_final(&ctx, U);
|
||||
+ openssl_hmac_init(&ctx, str, str_size, &hash_method_sha1);
|
||||
+ openssl_hmac_init(&ctx, str, str_size, hmethod);
|
||||
+ openssl_hmac_update(&ctx, salt, salt_size);
|
||||
+ openssl_hmac_update(&ctx, "\0\0\0\1", 4);
|
||||
+ openssl_hmac_final(&ctx, U);
|
||||
|
||||
memcpy(result, U, SHA1_RESULTLEN);
|
||||
memcpy(result, U, hmethod->digest_size);
|
||||
|
||||
/* Calculate U2 to Ui and Hi */
|
||||
for (j = 2; j <= i; j++) {
|
||||
- hmac_init(&ctx, str, str_size, &hash_method_sha1);
|
||||
- hmac_init(&ctx, str, str_size, hmethod);
|
||||
- hmac_update(&ctx, U, sizeof(U));
|
||||
- hmac_final(&ctx, U);
|
||||
+ openssl_hmac_init(&ctx, str, str_size, &hash_method_sha1);
|
||||
+ openssl_hmac_init(&ctx, str, str_size, hmethod);
|
||||
+ openssl_hmac_update(&ctx, U, sizeof(U));
|
||||
+ openssl_hmac_final(&ctx, U);
|
||||
for (k = 0; k < SHA1_RESULTLEN; k++)
|
||||
for (k = 0; k < hmethod->digest_size; k++)
|
||||
result[k] ^= U[k];
|
||||
}
|
||||
@@ -94,7 +94,7 @@ int scram_sha1_verify(const char *plaint
|
||||
const unsigned char *raw_password, size_t size,
|
||||
const char **error_r)
|
||||
@@ -102,7 +102,7 @@ int scram_verify(const struct hash_metho
|
||||
const char *plaintext, const unsigned char *raw_password,
|
||||
size_t size, const char **error_r)
|
||||
{
|
||||
- struct hmac_context ctx;
|
||||
+ struct openssl_hmac_context ctx;
|
||||
const char *salt_base64;
|
||||
unsigned int iter_count;
|
||||
const unsigned char *salt;
|
||||
@@ -118,10 +118,10 @@ int scram_sha1_verify(const char *plaint
|
||||
iter_count, salted_password);
|
||||
@@ -126,9 +126,9 @@ int scram_verify(const struct hash_metho
|
||||
salt, salt_len, iter_count, salted_password);
|
||||
|
||||
/* Calculate ClientKey */
|
||||
- hmac_init(&ctx, salted_password, sizeof(salted_password),
|
||||
+ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password),
|
||||
&hash_method_sha1);
|
||||
- hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);
|
||||
- hmac_update(&ctx, "Client Key", 10);
|
||||
- hmac_final(&ctx, client_key);
|
||||
+ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);
|
||||
+ openssl_hmac_update(&ctx, "Client Key", 10);
|
||||
+ openssl_hmac_final(&ctx, client_key);
|
||||
|
||||
/* Calculate StoredKey */
|
||||
sha1_get_digest(client_key, sizeof(client_key), calculated_stored_key);
|
||||
@@ -139,7 +139,7 @@ void scram_sha1_generate(const char *pla
|
||||
hash_method_get_digest(hmethod, client_key, sizeof(client_key),
|
||||
@@ -147,7 +147,7 @@ void scram_generate(const struct hash_me
|
||||
const unsigned char **raw_password_r, size_t *size_r)
|
||||
{
|
||||
string_t *str;
|
||||
- struct hmac_context ctx;
|
||||
+ struct openssl_hmac_context ctx;
|
||||
unsigned char salt[16];
|
||||
unsigned char salted_password[SHA1_RESULTLEN];
|
||||
unsigned char client_key[SHA1_RESULTLEN];
|
||||
@@ -157,10 +157,10 @@ void scram_sha1_generate(const char *pla
|
||||
unsigned char salted_password[hmethod->digest_size];
|
||||
unsigned char client_key[hmethod->digest_size];
|
||||
@@ -165,9 +165,9 @@ void scram_generate(const struct hash_me
|
||||
sizeof(salt), SCRAM_DEFAULT_ITERATE_COUNT, salted_password);
|
||||
|
||||
/* Calculate ClientKey */
|
||||
- hmac_init(&ctx, salted_password, sizeof(salted_password),
|
||||
+ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password),
|
||||
&hash_method_sha1);
|
||||
- hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);
|
||||
- hmac_update(&ctx, "Client Key", 10);
|
||||
- hmac_final(&ctx, client_key);
|
||||
+ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);
|
||||
+ openssl_hmac_update(&ctx, "Client Key", 10);
|
||||
+ openssl_hmac_final(&ctx, client_key);
|
||||
|
||||
/* Calculate StoredKey */
|
||||
sha1_get_digest(client_key, sizeof(client_key), stored_key);
|
||||
@@ -168,10 +168,10 @@ void scram_sha1_generate(const char *pla
|
||||
hash_method_get_digest(hmethod, client_key, sizeof(client_key),
|
||||
@@ -176,9 +176,9 @@ void scram_generate(const struct hash_me
|
||||
base64_encode(stored_key, sizeof(stored_key), str);
|
||||
|
||||
/* Calculate ServerKey */
|
||||
- hmac_init(&ctx, salted_password, sizeof(salted_password),
|
||||
+ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password),
|
||||
&hash_method_sha1);
|
||||
- hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);
|
||||
- hmac_update(&ctx, "Server Key", 10);
|
||||
- hmac_final(&ctx, server_key);
|
||||
+ openssl_hmac_init(&ctx, salted_password, sizeof(salted_password), hmethod);
|
||||
+ openssl_hmac_update(&ctx, "Server Key", 10);
|
||||
+ openssl_hmac_final(&ctx, server_key);
|
||||
str_append_c(str, ',');
|
||||
base64_encode(server_key, sizeof(server_key), str);
|
||||
|
||||
diff -up dovecot-2.3.8/src/lib/hmac.c.opensslhmac dovecot-2.3.8/src/lib/hmac.c
|
||||
--- dovecot-2.3.8/src/lib/hmac.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib/hmac.c 2019-11-19 17:25:28.045716181 +0100
|
||||
diff -up dovecot-2.3.14/src/lib/hmac.c.opensslhmac dovecot-2.3.14/src/lib/hmac.c
|
||||
--- dovecot-2.3.14/src/lib/hmac.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib/hmac.c 2021-03-22 20:44:13.023912229 +0100
|
||||
@@ -7,6 +7,10 @@
|
||||
* This software is released under the MIT license.
|
||||
*/
|
||||
@ -292,11 +287,11 @@ diff -up dovecot-2.3.8/src/lib/hmac.c.opensslhmac dovecot-2.3.8/src/lib/hmac.c
|
||||
+ }
|
||||
+ i_assert(no_fips);
|
||||
+ struct orig_hmac_context_priv *ctx = &_ctx->u.priv;
|
||||
int i;
|
||||
unsigned char k_ipad[64];
|
||||
unsigned char k_opad[64];
|
||||
unsigned int i;
|
||||
unsigned char k_ipad[meth->block_size];
|
||||
unsigned char k_opad[meth->block_size];
|
||||
@@ -53,9 +112,27 @@ void hmac_init(struct hmac_context *_ctx
|
||||
safe_memset(k_opad, 0, 64);
|
||||
safe_memset(k_opad, 0, meth->block_size);
|
||||
}
|
||||
|
||||
-void hmac_final(struct hmac_context *_ctx, unsigned char *digest)
|
||||
@ -453,9 +448,9 @@ diff -up dovecot-2.3.8/src/lib/hmac.c.opensslhmac dovecot-2.3.8/src/lib/hmac.c
|
||||
- safe_memset(prk, 0, sizeof(prk));
|
||||
- safe_memset(okm, 0, sizeof(okm));
|
||||
}
|
||||
diff -up dovecot-2.3.8/src/lib/hmac-cram-md5.c.opensslhmac dovecot-2.3.8/src/lib/hmac-cram-md5.c
|
||||
--- dovecot-2.3.8/src/lib/hmac-cram-md5.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib/hmac-cram-md5.c 2019-11-19 16:34:11.339036998 +0100
|
||||
diff -up dovecot-2.3.14/src/lib/hmac-cram-md5.c.opensslhmac dovecot-2.3.14/src/lib/hmac-cram-md5.c
|
||||
--- dovecot-2.3.14/src/lib/hmac-cram-md5.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib/hmac-cram-md5.c 2021-03-22 20:44:13.023912229 +0100
|
||||
@@ -9,10 +9,10 @@
|
||||
#include "md5.h"
|
||||
#include "hmac-cram-md5.h"
|
||||
@ -482,9 +477,9 @@ diff -up dovecot-2.3.8/src/lib/hmac-cram-md5.c.opensslhmac dovecot-2.3.8/src/lib
|
||||
const unsigned char *cdp;
|
||||
|
||||
struct md5_context *ctx = (void*)hmac_ctx->ctx;
|
||||
diff -up dovecot-2.3.8/src/lib/hmac-cram-md5.h.opensslhmac dovecot-2.3.8/src/lib/hmac-cram-md5.h
|
||||
--- dovecot-2.3.8/src/lib/hmac-cram-md5.h.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib/hmac-cram-md5.h 2019-11-19 16:34:11.339036998 +0100
|
||||
diff -up dovecot-2.3.14/src/lib/hmac-cram-md5.h.opensslhmac dovecot-2.3.14/src/lib/hmac-cram-md5.h
|
||||
--- dovecot-2.3.14/src/lib/hmac-cram-md5.h.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib/hmac-cram-md5.h 2021-03-22 20:44:13.023912229 +0100
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
#define CRAM_MD5_CONTEXTLEN 32
|
||||
@ -497,19 +492,19 @@ diff -up dovecot-2.3.8/src/lib/hmac-cram-md5.h.opensslhmac dovecot-2.3.8/src/lib
|
||||
const unsigned char context_digest[CRAM_MD5_CONTEXTLEN]);
|
||||
|
||||
|
||||
diff -up dovecot-2.3.8/src/lib/hmac.h.opensslhmac dovecot-2.3.8/src/lib/hmac.h
|
||||
--- dovecot-2.3.8/src/lib/hmac.h.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib/hmac.h 2019-11-19 16:34:11.339036998 +0100
|
||||
@@ -3,60 +3,97 @@
|
||||
|
||||
diff -up dovecot-2.3.14/src/lib/hmac.h.opensslhmac dovecot-2.3.14/src/lib/hmac.h
|
||||
--- dovecot-2.3.14/src/lib/hmac.h.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib/hmac.h 2021-03-22 20:44:13.023912229 +0100
|
||||
@@ -4,60 +4,97 @@
|
||||
#include "hash-method.h"
|
||||
#include "sha1.h"
|
||||
#include "sha2.h"
|
||||
+#include <openssl/objects.h>
|
||||
+#include <openssl/hmac.h>
|
||||
+#include <openssl/kdf.h>
|
||||
+#include <openssl/err.h>
|
||||
|
||||
#define HMAC_MAX_CONTEXT_SIZE 256
|
||||
#define HMAC_MAX_CONTEXT_SIZE sizeof(struct sha512_ctx)
|
||||
|
||||
-struct hmac_context_priv {
|
||||
+struct openssl_hmac_context_priv {
|
||||
@ -611,9 +606,9 @@ diff -up dovecot-2.3.8/src/lib/hmac.h.opensslhmac dovecot-2.3.8/src/lib/hmac.h
|
||||
okm_buffer, okm_len);
|
||||
return okm_buffer;
|
||||
}
|
||||
diff -up dovecot-2.3.8/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac dovecot-2.3.8/src/lib-imap-urlauth/imap-urlauth.c
|
||||
--- dovecot-2.3.8/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib-imap-urlauth/imap-urlauth.c 2019-11-19 16:34:11.339036998 +0100
|
||||
diff -up dovecot-2.3.14/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac dovecot-2.3.14/src/lib-imap-urlauth/imap-urlauth.c
|
||||
--- dovecot-2.3.14/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib-imap-urlauth/imap-urlauth.c 2021-03-22 20:44:13.023912229 +0100
|
||||
@@ -85,15 +85,15 @@ imap_urlauth_internal_generate(const cha
|
||||
const unsigned char mailbox_key[IMAP_URLAUTH_KEY_LEN],
|
||||
size_t *token_len_r)
|
||||
@ -634,10 +629,10 @@ diff -up dovecot-2.3.8/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac dovecot-2
|
||||
|
||||
*token_len_r = SHA1_RESULTLEN + 1;
|
||||
return token;
|
||||
diff -up dovecot-2.3.8/src/lib/Makefile.am.opensslhmac dovecot-2.3.8/src/lib/Makefile.am
|
||||
--- dovecot-2.3.8/src/lib/Makefile.am.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib/Makefile.am 2019-11-19 16:34:11.340036994 +0100
|
||||
@@ -323,6 +323,9 @@ headers = \
|
||||
diff -up dovecot-2.3.14/src/lib/Makefile.am.opensslhmac dovecot-2.3.14/src/lib/Makefile.am
|
||||
--- dovecot-2.3.14/src/lib/Makefile.am.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib/Makefile.am 2021-03-22 20:44:13.023912229 +0100
|
||||
@@ -352,6 +352,9 @@ headers = \
|
||||
wildcard-match.h \
|
||||
write-full.h
|
||||
|
||||
@ -647,69 +642,63 @@ diff -up dovecot-2.3.8/src/lib/Makefile.am.opensslhmac dovecot-2.3.8/src/lib/Mak
|
||||
test_programs = test-lib
|
||||
noinst_PROGRAMS = $(test_programs)
|
||||
|
||||
diff -up dovecot-2.3.8/src/lib-ntlm/ntlm-encrypt.c.opensslhmac dovecot-2.3.8/src/lib-ntlm/ntlm-encrypt.c
|
||||
--- dovecot-2.3.8/src/lib-ntlm/ntlm-encrypt.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib-ntlm/ntlm-encrypt.c 2019-11-19 16:34:11.340036994 +0100
|
||||
@@ -61,12 +61,12 @@ void ntlm_v1_hash(const char *passwd, un
|
||||
}
|
||||
diff -up dovecot-2.3.14/src/lib-oauth2/oauth2-jwt.c.opensslhmac dovecot-2.3.14/src/lib-oauth2/oauth2-jwt.c
|
||||
--- dovecot-2.3.14/src/lib-oauth2/oauth2-jwt.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib-oauth2/oauth2-jwt.c 2021-03-22 20:44:13.024912217 +0100
|
||||
@@ -106,14 +106,14 @@ oauth2_validate_hmac(const struct oauth2
|
||||
if (oauth2_lookup_hmac_key(set, azp, alg, key_id, &key, error_r) < 0)
|
||||
return -1;
|
||||
|
||||
static void
|
||||
-hmac_md5_ucs2le_string_ucase(struct hmac_context *ctx, const char *str)
|
||||
-{
|
||||
- size_t len;
|
||||
- unsigned char *wstr = t_unicode_str(str, TRUE, &len);
|
||||
-
|
||||
- hmac_update(ctx, wstr, len);
|
||||
+hmac_md5_ucs2le_string_ucase(struct openssl_hmac_context *ctx, const char *str)
|
||||
+ {
|
||||
+ size_t len;
|
||||
+ unsigned char *wstr = t_unicode_str(str, TRUE, &len);
|
||||
+
|
||||
+ openssl_hmac_update(ctx, wstr, len);
|
||||
}
|
||||
|
||||
static void ATTR_NULL(2)
|
||||
@@ -74,13 +74,13 @@ ntlm_v2_hash(const char *user, const cha
|
||||
const unsigned char *hash_v1,
|
||||
unsigned char hash[NTLMSSP_V2_HASH_SIZE])
|
||||
{
|
||||
- struct hmac_context ctx;
|
||||
- hmac_init(&ctx, key->data, key->used, method);
|
||||
- hmac_update(&ctx, blobs[0], strlen(blobs[0]));
|
||||
- hmac_update(&ctx, ".", 1);
|
||||
- hmac_update(&ctx, blobs[1], strlen(blobs[1]));
|
||||
+ struct openssl_hmac_context ctx;
|
||||
+ openssl_hmac_init(&ctx, key->data, key->used, method);
|
||||
+ openssl_hmac_update(&ctx, blobs[0], strlen(blobs[0]));
|
||||
+ openssl_hmac_update(&ctx, ".", 1);
|
||||
+ openssl_hmac_update(&ctx, blobs[1], strlen(blobs[1]));
|
||||
unsigned char digest[method->digest_size];
|
||||
|
||||
- hmac_init(&ctx, hash_v1, NTLMSSP_HASH_SIZE, &hash_method_md5);
|
||||
+ openssl_hmac_init(&ctx, hash_v1, NTLMSSP_HASH_SIZE, &hash_method_md5);
|
||||
hmac_md5_ucs2le_string_ucase(&ctx, user);
|
||||
if (target != NULL)
|
||||
hmac_md5_ucs2le_string_ucase(&ctx, target);
|
||||
- hmac_final(&ctx, hash);
|
||||
+ openssl_hmac_final(&ctx, hash);
|
||||
}
|
||||
- hmac_final(&ctx, digest);
|
||||
+ openssl_hmac_final(&ctx, digest);
|
||||
|
||||
void
|
||||
@@ -125,15 +125,15 @@ ntlmssp_v2_response(const char *user, co
|
||||
const unsigned char *blob, size_t blob_size,
|
||||
unsigned char response[NTLMSSP_V2_RESPONSE_SIZE])
|
||||
buffer_t *their_digest =
|
||||
t_base64url_decode_str(BASE64_DECODE_FLAG_NO_PADDING, blobs[2]);
|
||||
diff -up dovecot-2.3.14/src/lib-oauth2/test-oauth2-jwt.c.opensslhmac dovecot-2.3.14/src/lib-oauth2/test-oauth2-jwt.c
|
||||
--- dovecot-2.3.14/src/lib-oauth2/test-oauth2-jwt.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib-oauth2/test-oauth2-jwt.c 2021-03-22 20:46:09.524440794 +0100
|
||||
@@ -236,7 +236,7 @@ static void save_key_to(const char *algo
|
||||
static void sign_jwt_token_hs256(buffer_t *tokenbuf, buffer_t *key)
|
||||
{
|
||||
- struct hmac_context ctx;
|
||||
+ struct openssl_hmac_context ctx;
|
||||
unsigned char hash[NTLMSSP_V2_HASH_SIZE];
|
||||
|
||||
ntlm_v2_hash(user, target, hash_v1, hash);
|
||||
|
||||
- hmac_init(&ctx, hash, NTLMSSP_V2_HASH_SIZE, &hash_method_md5);
|
||||
- hmac_update(&ctx, challenge, NTLMSSP_CHALLENGE_SIZE);
|
||||
- hmac_update(&ctx, blob, blob_size);
|
||||
- hmac_final(&ctx, response);
|
||||
+ openssl_hmac_init(&ctx, hash, NTLMSSP_V2_HASH_SIZE, &hash_method_md5);
|
||||
+ openssl_hmac_update(&ctx, challenge, NTLMSSP_CHALLENGE_SIZE);
|
||||
+ openssl_hmac_update(&ctx, blob, blob_size);
|
||||
+ openssl_hmac_final(&ctx, response);
|
||||
|
||||
safe_memset(hash, 0, sizeof(hash));
|
||||
}
|
||||
diff -up dovecot-2.3.8/src/lib/pkcs5.c.opensslhmac dovecot-2.3.8/src/lib/pkcs5.c
|
||||
--- dovecot-2.3.8/src/lib/pkcs5.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib/pkcs5.c 2019-11-19 16:34:11.340036994 +0100
|
||||
i_assert(key != NULL);
|
||||
- buffer_t *sig = t_hmac_buffer(&hash_method_sha256, key->data, key->used,
|
||||
+ buffer_t *sig = openssl_t_hmac_buffer(&hash_method_sha256, key->data, key->used,
|
||||
tokenbuf);
|
||||
buffer_append(tokenbuf, ".", 1);
|
||||
base64url_encode(BASE64_ENCODE_FLAG_NO_PADDING, SIZE_MAX,
|
||||
@@ -246,7 +246,7 @@ static void sign_jwt_token_hs256(buffer_
|
||||
static void sign_jwt_token_hs384(buffer_t *tokenbuf, buffer_t *key)
|
||||
{
|
||||
i_assert(key != NULL);
|
||||
- buffer_t *sig = t_hmac_buffer(&hash_method_sha384, key->data, key->used,
|
||||
+ buffer_t *sig = openssl_t_hmac_buffer(&hash_method_sha384, key->data, key->used,
|
||||
tokenbuf);
|
||||
buffer_append(tokenbuf, ".", 1);
|
||||
base64url_encode(BASE64_ENCODE_FLAG_NO_PADDING, SIZE_MAX,
|
||||
@@ -256,7 +256,7 @@ static void sign_jwt_token_hs384(buffer_
|
||||
static void sign_jwt_token_hs512(buffer_t *tokenbuf, buffer_t *key)
|
||||
{
|
||||
i_assert(key != NULL);
|
||||
- buffer_t *sig = t_hmac_buffer(&hash_method_sha512, key->data, key->used,
|
||||
+ buffer_t *sig = openssl_t_hmac_buffer(&hash_method_sha512, key->data, key->used,
|
||||
tokenbuf);
|
||||
buffer_append(tokenbuf, ".", 1);
|
||||
base64url_encode(BASE64_ENCODE_FLAG_NO_PADDING, SIZE_MAX,
|
||||
diff -up dovecot-2.3.14/src/lib/pkcs5.c.opensslhmac dovecot-2.3.14/src/lib/pkcs5.c
|
||||
--- dovecot-2.3.14/src/lib/pkcs5.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib/pkcs5.c 2021-03-22 20:44:13.024912217 +0100
|
||||
@@ -52,7 +52,7 @@ int pkcs5_pbkdf2(const struct hash_metho
|
||||
size_t l = (length + hash->digest_size - 1)/hash->digest_size; /* same as ceil(length/hash->digest_size) */
|
||||
unsigned char dk[l * hash->digest_size];
|
||||
@ -744,10 +733,10 @@ diff -up dovecot-2.3.8/src/lib/pkcs5.c.opensslhmac dovecot-2.3.8/src/lib/pkcs5.c
|
||||
for(i = 0; i < hash->digest_size; i++)
|
||||
block[i] ^= U_c[i];
|
||||
}
|
||||
diff -up dovecot-2.3.8/src/lib/test-hmac.c.opensslhmac dovecot-2.3.8/src/lib/test-hmac.c
|
||||
--- dovecot-2.3.8/src/lib/test-hmac.c.opensslhmac 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib/test-hmac.c 2019-11-19 16:34:11.340036994 +0100
|
||||
@@ -112,11 +112,11 @@ static void test_hmac_rfc(void)
|
||||
diff -up dovecot-2.3.14/src/lib/test-hmac.c.opensslhmac dovecot-2.3.14/src/lib/test-hmac.c
|
||||
--- dovecot-2.3.14/src/lib/test-hmac.c.opensslhmac 2021-03-04 09:38:06.000000000 +0100
|
||||
+++ dovecot-2.3.14/src/lib/test-hmac.c 2021-03-22 20:44:13.024912217 +0100
|
||||
@@ -206,11 +206,11 @@ static void test_hmac_rfc(void)
|
||||
test_begin("hmac sha256 rfc4231 vectors");
|
||||
for(size_t i = 0; i < N_ELEMENTS(test_vectors); i++) {
|
||||
const struct test_vector *vec = &(test_vectors[i]);
|
||||
@ -763,7 +752,39 @@ diff -up dovecot-2.3.8/src/lib/test-hmac.c.opensslhmac dovecot-2.3.8/src/lib/tes
|
||||
test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i);
|
||||
}
|
||||
test_end();
|
||||
@@ -129,7 +129,7 @@ static void test_hmac_buffer(void)
|
||||
@@ -221,11 +221,11 @@ static void test_hmac384_rfc(void)
|
||||
test_begin("hmac sha384 rfc4231 vectors");
|
||||
for (size_t i = 0; i < N_ELEMENTS(test_vectors_hmac384); i++) {
|
||||
const struct test_vector *vec = &(test_vectors_hmac384[i]);
|
||||
- struct hmac_context ctx;
|
||||
- hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf));
|
||||
- hmac_update(&ctx, vec->data, vec->data_len);
|
||||
+ struct openssl_hmac_context ctx;
|
||||
+ openssl_hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf));
|
||||
+ openssl_hmac_update(&ctx, vec->data, vec->data_len);
|
||||
unsigned char res[SHA384_RESULTLEN];
|
||||
- hmac_final(&ctx, res);
|
||||
+ openssl_hmac_final(&ctx, res);
|
||||
test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i);
|
||||
}
|
||||
test_end();
|
||||
@@ -236,11 +236,11 @@ static void test_hmac512_rfc(void)
|
||||
test_begin("hmac sha512 rfc4231 vectors");
|
||||
for (size_t i = 0; i < N_ELEMENTS(test_vectors_hmac512); i++) {
|
||||
const struct test_vector *vec = &(test_vectors_hmac512[i]);
|
||||
- struct hmac_context ctx;
|
||||
- hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf));
|
||||
- hmac_update(&ctx, vec->data, vec->data_len);
|
||||
+ struct openssl_hmac_context ctx;
|
||||
+ openssl_hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf));
|
||||
+ openssl_hmac_update(&ctx, vec->data, vec->data_len);
|
||||
unsigned char res[SHA512_RESULTLEN];
|
||||
- hmac_final(&ctx, res);
|
||||
+ openssl_hmac_final(&ctx, res);
|
||||
test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i);
|
||||
}
|
||||
test_end();
|
||||
@@ -253,7 +253,7 @@ static void test_hmac_buffer(void)
|
||||
|
||||
buffer_t *tmp;
|
||||
|
||||
@ -772,7 +793,7 @@ diff -up dovecot-2.3.8/src/lib/test-hmac.c.opensslhmac dovecot-2.3.8/src/lib/tes
|
||||
vec->data, vec->data_len);
|
||||
|
||||
test_assert(tmp->used == vec->res_len &&
|
||||
@@ -146,7 +146,7 @@ static void test_hkdf_rfc(void)
|
||||
@@ -270,7 +270,7 @@ static void test_hkdf_rfc(void)
|
||||
buffer_set_used_size(res, 0);
|
||||
const struct test_vector_5869 *vec = &(test_vectors_5869[i]);
|
||||
const struct hash_method *m = hash_method_lookup(vec->prf);
|
||||
@ -781,7 +802,7 @@ diff -up dovecot-2.3.8/src/lib/test-hmac.c.opensslhmac dovecot-2.3.8/src/lib/tes
|
||||
vec->info, vec->info_len, res, vec->okm_len);
|
||||
test_assert_idx(memcmp(res->data, vec->okm, vec->okm_len) == 0, i);
|
||||
}
|
||||
@@ -159,7 +159,7 @@ static void test_hkdf_buffer(void)
|
||||
@@ -283,7 +283,7 @@ static void test_hkdf_buffer(void)
|
||||
test_begin("hkdf temporary buffer");
|
||||
const struct test_vector_5869 *vec = &(test_vectors_5869[0]);
|
||||
const struct hash_method *m = hash_method_lookup(vec->prf);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,56 +0,0 @@
|
||||
diff -up dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/plugins/notify/ext-notify-common.c.CVE_2020_12100ph dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/plugins/notify/ext-notify-common.c
|
||||
--- dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/plugins/notify/ext-notify-common.c.CVE_2020_12100ph 2019-10-08 10:48:14.000000000 +0200
|
||||
+++ dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/plugins/notify/ext-notify-common.c 2020-08-07 16:42:56.515389867 +0200
|
||||
@@ -148,6 +148,7 @@ static int cmd_notify_extract_body_text
|
||||
const char **body_text_r, size_t *body_size_r)
|
||||
{
|
||||
const struct sieve_extension *this_ext = renv->oprtn->ext;
|
||||
+ const struct message_parser_settings parser_set = { .flags = 0 };
|
||||
struct ext_notify_message_context *mctx;
|
||||
struct mail *mail = renv->msgdata->mail;
|
||||
struct message_parser_ctx *parser;
|
||||
@@ -181,7 +182,7 @@ static int cmd_notify_extract_body_text
|
||||
/* Initialize body decoder */
|
||||
decoder = message_decoder_init(NULL, 0);
|
||||
|
||||
- parser = message_parser_init(mctx->pool, input, 0, 0);
|
||||
+ parser = message_parser_init(mctx->pool, input, &parser_set);
|
||||
is_text = TRUE;
|
||||
save_body = FALSE;
|
||||
while ( (ret=message_parser_parse_next_block(parser, &block)) > 0 ) {
|
||||
diff -up dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/sieve-message.c.CVE_2020_12100ph dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/sieve-message.c
|
||||
--- dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/sieve-message.c.CVE_2020_12100ph 2019-10-08 10:48:14.000000000 +0200
|
||||
+++ dovecot-2.3.8/dovecot-2.3-pigeonhole-0.5.8/src/lib-sieve/sieve-message.c 2020-08-07 16:42:56.516389854 +0200
|
||||
@@ -1077,10 +1077,10 @@ static int sieve_message_parts_add_missi
|
||||
struct sieve_message_context *msgctx = renv->msgctx;
|
||||
pool_t pool = msgctx->context_pool;
|
||||
struct mail *mail = sieve_message_get_mail(renv->msgctx);
|
||||
- enum message_parser_flags mparser_flags =
|
||||
- MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS;
|
||||
- enum message_header_parser_flags hparser_flags =
|
||||
- MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP;
|
||||
+ struct message_parser_settings parser_set = {
|
||||
+ .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP,
|
||||
+ .flags = MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS,
|
||||
+ };
|
||||
ARRAY(struct sieve_message_header) headers;
|
||||
struct sieve_message_part *body_part, *header_part, *last_part;
|
||||
struct message_parser_ctx *parser;
|
||||
@@ -1117,7 +1117,7 @@ static int sieve_message_parts_add_missi
|
||||
if (iter_all) {
|
||||
t_array_init(&headers, 64);
|
||||
hdr_content = t_str_new(512);
|
||||
- hparser_flags |= MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE;
|
||||
+ parser_set.hdr_flags |= MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE;
|
||||
} else {
|
||||
i_zero(&headers);
|
||||
}
|
||||
@@ -1129,7 +1129,7 @@ static int sieve_message_parts_add_missi
|
||||
//parser = message_parser_init_from_parts(parts, input,
|
||||
// hparser_flags, mparser_flags);
|
||||
parser = message_parser_init(pool_datastack_create(),
|
||||
- input, hparser_flags, mparser_flags);
|
||||
+ input, &parser_set);
|
||||
while ( (ret=message_parser_parse_next_block
|
||||
(parser, &block)) > 0 ) {
|
||||
struct sieve_message_part **body_part_idx;
|
@ -1,224 +0,0 @@
|
||||
diff -up dovecot-2.3.8/src/lib-mail/message-decoder.c.CVE_2020_12100prereq dovecot-2.3.8/src/lib-mail/message-decoder.c
|
||||
--- dovecot-2.3.8/src/lib-mail/message-decoder.c.CVE_2020_12100prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib-mail/message-decoder.c 2020-08-07 17:48:58.320126698 +0200
|
||||
@@ -13,9 +13,6 @@
|
||||
#include "message-header-decode.h"
|
||||
#include "message-decoder.h"
|
||||
|
||||
-/* base64 takes max 4 bytes per character, q-p takes max 3. */
|
||||
-#define MAX_ENCODING_BUF_SIZE 3
|
||||
-
|
||||
struct message_decoder_context {
|
||||
enum message_decoder_flags flags;
|
||||
normalizer_func_t *normalizer;
|
||||
@@ -30,7 +27,7 @@ struct message_decoder_context {
|
||||
size_t translation_size;
|
||||
|
||||
struct qp_decoder *qp;
|
||||
- buffer_t *encoding_buf;
|
||||
+ struct base64_decoder base64_decoder;
|
||||
|
||||
char *content_type, *content_charset;
|
||||
enum message_cte message_cte;
|
||||
@@ -53,7 +50,7 @@ message_decoder_init(normalizer_func_t *
|
||||
ctx->normalizer = normalizer;
|
||||
ctx->buf = buffer_create_dynamic(default_pool, 8192);
|
||||
ctx->buf2 = buffer_create_dynamic(default_pool, 8192);
|
||||
- ctx->encoding_buf = buffer_create_dynamic(default_pool, 128);
|
||||
+ base64_decode_init(&ctx->base64_decoder, &base64_scheme, 0);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -68,7 +65,6 @@ void message_decoder_deinit(struct messa
|
||||
if (ctx->qp != NULL)
|
||||
qp_decoder_deinit(&ctx->qp);
|
||||
|
||||
- buffer_free(&ctx->encoding_buf);
|
||||
buffer_free(&ctx->buf);
|
||||
buffer_free(&ctx->buf2);
|
||||
i_free(ctx->charset_trans_charset);
|
||||
@@ -273,14 +269,9 @@ static bool message_decode_body(struct m
|
||||
struct message_block *input,
|
||||
struct message_block *output)
|
||||
{
|
||||
- struct base64_decoder b64dec;
|
||||
const unsigned char *data = NULL;
|
||||
- size_t pos = 0, size = 0;
|
||||
+ size_t pos, size = 0;
|
||||
const char *error;
|
||||
- int ret;
|
||||
-
|
||||
- if (ctx->encoding_buf->used != 0)
|
||||
- buffer_append(ctx->encoding_buf, input->data, input->size);
|
||||
|
||||
switch (ctx->message_cte) {
|
||||
case MESSAGE_CTE_UNKNOWN:
|
||||
@@ -289,12 +280,10 @@ static bool message_decode_body(struct m
|
||||
|
||||
case MESSAGE_CTE_78BIT:
|
||||
case MESSAGE_CTE_BINARY:
|
||||
- i_assert(ctx->encoding_buf->used == 0);
|
||||
data = input->data;
|
||||
- size = pos = input->size;
|
||||
+ size = input->size;
|
||||
break;
|
||||
case MESSAGE_CTE_QP: {
|
||||
- i_assert(ctx->encoding_buf->used == 0);
|
||||
buffer_set_used_size(ctx->buf, 0);
|
||||
if (ctx->qp == NULL)
|
||||
ctx->qp = qp_decoder_init(ctx->buf);
|
||||
@@ -302,45 +291,24 @@ static bool message_decode_body(struct m
|
||||
&pos, &error);
|
||||
data = ctx->buf->data;
|
||||
size = ctx->buf->used;
|
||||
- /* eat away all input. qp-decoder buffers it internally. */
|
||||
- pos = input->size;
|
||||
break;
|
||||
}
|
||||
case MESSAGE_CTE_BASE64:
|
||||
buffer_set_used_size(ctx->buf, 0);
|
||||
- base64_decode_init(&b64dec, &base64_scheme, 0);
|
||||
- if (ctx->encoding_buf->used != 0) {
|
||||
- ret = base64_decode_more(&b64dec,
|
||||
- ctx->encoding_buf->data,
|
||||
- ctx->encoding_buf->used,
|
||||
- &pos, ctx->buf);
|
||||
- } else {
|
||||
- ret = base64_decode_more(&b64dec,
|
||||
- input->data, input->size,
|
||||
- &pos, ctx->buf);
|
||||
- }
|
||||
- if (ret < 0 || base64_decode_finish(&b64dec) < 0) {
|
||||
- /* corrupted base64 data, don't bother with
|
||||
- the rest of it */
|
||||
- return FALSE;
|
||||
- }
|
||||
- if (ret == 0) {
|
||||
- /* end of base64 input */
|
||||
- pos = input->size;
|
||||
- buffer_set_used_size(ctx->encoding_buf, 0);
|
||||
+ if (!base64_decode_is_finished(&ctx->base64_decoder)) {
|
||||
+ if (base64_decode_more(&ctx->base64_decoder,
|
||||
+ input->data, input->size,
|
||||
+ &pos, ctx->buf) <= 0) {
|
||||
+ /* ignore the rest of the input in this
|
||||
+ MIME part */
|
||||
+ (void)base64_decode_finish(&ctx->base64_decoder);
|
||||
+ }
|
||||
}
|
||||
data = ctx->buf->data;
|
||||
size = ctx->buf->used;
|
||||
break;
|
||||
}
|
||||
|
||||
- if (ctx->encoding_buf->used != 0)
|
||||
- buffer_delete(ctx->encoding_buf, 0, pos);
|
||||
- else if (pos != input->size) {
|
||||
- buffer_append(ctx->encoding_buf,
|
||||
- input->data + pos, input->size - pos);
|
||||
- }
|
||||
-
|
||||
if (ctx->binary_input) {
|
||||
output->data = data;
|
||||
output->size = size;
|
||||
@@ -402,10 +370,11 @@ void message_decoder_decode_reset(struct
|
||||
{
|
||||
const char *error;
|
||||
|
||||
+ base64_decode_reset(&ctx->base64_decoder);
|
||||
+
|
||||
if (ctx->qp != NULL)
|
||||
(void)qp_decoder_finish(ctx->qp, &error);
|
||||
i_free_and_null(ctx->content_type);
|
||||
i_free_and_null(ctx->content_charset);
|
||||
ctx->message_cte = MESSAGE_CTE_78BIT;
|
||||
- buffer_set_used_size(ctx->encoding_buf, 0);
|
||||
}
|
||||
diff -up dovecot-2.3.8/src/lib-mail/test-message-decoder.c.CVE_2020_12100prereq dovecot-2.3.8/src/lib-mail/test-message-decoder.c
|
||||
--- dovecot-2.3.8/src/lib-mail/test-message-decoder.c.CVE_2020_12100prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/lib-mail/test-message-decoder.c 2020-08-07 17:50:04.612248484 +0200
|
||||
@@ -1,7 +1,8 @@
|
||||
/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
|
||||
|
||||
#include "lib.h"
|
||||
-#include "buffer.h"
|
||||
+#include "str.h"
|
||||
+#include "istream.h"
|
||||
#include "charset-utf8.h"
|
||||
#include "message-parser.h"
|
||||
#include "message-header-decode.h"
|
||||
@@ -82,6 +83,66 @@ static void test_message_decoder(void)
|
||||
test_end();
|
||||
}
|
||||
|
||||
+static void test_message_decoder_multipart(void)
|
||||
+{
|
||||
+ static const char test_message_input[] =
|
||||
+ "Content-Type: multipart/mixed; boundary=foo\n"
|
||||
+ "\n"
|
||||
+ "--foo\n"
|
||||
+ "Content-Transfer-Encoding: quoted-printable\n"
|
||||
+ "Content-Type: text/plain; charset=utf-8\n"
|
||||
+ "\n"
|
||||
+ "p=C3=A4iv=C3=A4=C3=A4\n"
|
||||
+ "\n"
|
||||
+ "--foo\n"
|
||||
+ "Content-Transfer-Encoding: base64\n"
|
||||
+ "Content-Type: text/plain; charset=utf-8\n"
|
||||
+ "\n"
|
||||
+ "ecO2dMOkIHZhYW4uCg== ignored\n"
|
||||
+ "--foo\n"
|
||||
+ "Content-Transfer-Encoding: base64\n"
|
||||
+ "Content-Type: text/plain; charset=utf-8\n"
|
||||
+ "\n"
|
||||
+ "?garbage\n"
|
||||
+ "--foo--\n";
|
||||
+ struct message_parser_ctx *parser;
|
||||
+ struct message_decoder_context *decoder;
|
||||
+ struct message_part *parts;
|
||||
+ struct message_block input, output;
|
||||
+ struct istream *istream;
|
||||
+ string_t *str_out = t_str_new(20);
|
||||
+ int ret;
|
||||
+
|
||||
+ test_begin("message decoder multipart");
|
||||
+
|
||||
+ istream = test_istream_create(test_message_input);
|
||||
+ parser = message_parser_init(pool_datastack_create(), istream, 0, 0);
|
||||
+ decoder = message_decoder_init(NULL, 0);
|
||||
+
|
||||
+ test_istream_set_allow_eof(istream, FALSE);
|
||||
+ for (size_t i = 0; i < sizeof(test_message_input); i++) {
|
||||
+ if (i == sizeof(test_message_input)-1)
|
||||
+ test_istream_set_allow_eof(istream, TRUE);
|
||||
+ test_istream_set_size(istream, i);
|
||||
+ while ((ret = message_parser_parse_next_block(parser, &input)) > 0) {
|
||||
+ if (message_decoder_decode_next_block(decoder, &input, &output) &&
|
||||
+ output.hdr == NULL && output.size > 0)
|
||||
+ str_append_data(str_out, output.data, output.size);
|
||||
+ }
|
||||
+ if (i == sizeof(test_message_input)-1)
|
||||
+ test_assert(ret == -1);
|
||||
+ else
|
||||
+ test_assert(ret == 0);
|
||||
+ }
|
||||
+ /* NOTE: qp-decoder decoder changes \n into \r\n */
|
||||
+ test_assert_strcmp(str_c(str_out), "p\xC3\xA4iv\xC3\xA4\xC3\xA4\r\ny\xC3\xB6t\xC3\xA4 vaan.\n");
|
||||
+
|
||||
+ message_decoder_deinit(&decoder);
|
||||
+ message_parser_deinit(&parser, &parts);
|
||||
+ i_stream_unref(&istream);
|
||||
+ test_end();
|
||||
+}
|
||||
+
|
||||
static void test_message_decoder_current_content_type(void)
|
||||
{
|
||||
struct message_decoder_context *ctx;
|
||||
@@ -149,6 +210,7 @@ int main(void)
|
||||
{
|
||||
static void (*const test_functions[])(void) = {
|
||||
test_message_decoder,
|
||||
+ test_message_decoder_multipart,
|
||||
test_message_decoder_current_content_type,
|
||||
NULL
|
||||
};
|
@ -1,34 +0,0 @@
|
||||
From 1c6405d3026e5ceae3d214d63945bba85251af4c Mon Sep 17 00:00:00 2001
|
||||
From: Aki Tuomi <aki.tuomi@open-xchange.com>
|
||||
Date: Mon, 18 May 2020 12:33:39 +0300
|
||||
Subject: [PATCH 2/3] lib-ntlm: Check buffer length on responses
|
||||
|
||||
Add missing check for buffer length.
|
||||
|
||||
If this is not checked, it is possible to send message which
|
||||
causes read past buffer bug.
|
||||
|
||||
Broken in c7480644202e5451fbed448508ea29a25cffc99c
|
||||
---
|
||||
src/lib-ntlm/ntlm-message.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/lib-ntlm/ntlm-message.c b/src/lib-ntlm/ntlm-message.c
|
||||
index 160b9f918c..a29413b47e 100644
|
||||
--- a/src/lib-ntlm/ntlm-message.c
|
||||
+++ b/src/lib-ntlm/ntlm-message.c
|
||||
@@ -184,6 +184,11 @@ static bool ntlmssp_check_buffer(const struct ntlmssp_buffer *buffer,
|
||||
if (length == 0 && space == 0)
|
||||
return TRUE;
|
||||
|
||||
+ if (length > data_size) {
|
||||
+ *error = "buffer length out of bounds";
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if (offset >= data_size) {
|
||||
*error = "buffer offset out of bounds";
|
||||
return FALSE;
|
||||
--
|
||||
2.11.0
|
||||
|
@ -1,234 +0,0 @@
|
||||
From bd9d2fe7da833f0e4705a8280efc56930371806b Mon Sep 17 00:00:00 2001
|
||||
From: Aki Tuomi <aki.tuomi@open-xchange.com>
|
||||
Date: Wed, 6 May 2020 13:40:36 +0300
|
||||
Subject: [PATCH 1/3] auth: mech-rpa - Fail on zero len buffer
|
||||
|
||||
---
|
||||
src/auth/mech-rpa.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/auth/mech-rpa.c b/src/auth/mech-rpa.c
|
||||
index 08298ebdd6..2de8705b4f 100644
|
||||
--- a/src/auth/mech-rpa.c
|
||||
+++ b/src/auth/mech-rpa.c
|
||||
@@ -224,7 +224,7 @@ rpa_read_buffer(pool_t pool, const unsigned char **data,
|
||||
return 0;
|
||||
|
||||
len = *p++;
|
||||
- if (p + len > end)
|
||||
+ if (p + len > end || len == 0)
|
||||
return 0;
|
||||
|
||||
*buffer = p_malloc(pool, len);
|
||||
--
|
||||
2.11.0
|
||||
|
||||
From 98c39fd633adf9b1d11a7bad58ef0784a25042e6 Mon Sep 17 00:00:00 2001
|
||||
From: Aki Tuomi <aki.tuomi@open-xchange.com>
|
||||
Date: Mon, 18 May 2020 13:08:45 +0300
|
||||
Subject: [PATCH 3/3] auth: test-mech - Add tests for RPA and NTLM bug
|
||||
|
||||
---
|
||||
src/auth/test-mech.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 66 insertions(+)
|
||||
|
||||
diff -up dovecot-2.3.8/src/auth/test-mech.c.CVE_2020_12674prereq dovecot-2.3.8/src/auth/test-mech.c
|
||||
--- dovecot-2.3.8/src/auth/test-mech.c.CVE_2020_12674prereq 2020-08-07 20:46:56.095295825 +0200
|
||||
+++ dovecot-2.3.8/src/auth/test-mech.c 2020-08-07 20:47:08.742124304 +0200
|
||||
@@ -0,0 +1,196 @@
|
||||
+/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */
|
||||
+
|
||||
+#include "lib.h"
|
||||
+#include "auth.h"
|
||||
+#include "str.h"
|
||||
+#include "auth-common.h"
|
||||
+#include "auth-request.h"
|
||||
+#include "auth-request-handler-private.h"
|
||||
+#include "auth-settings.h"
|
||||
+#include "otp.h"
|
||||
+#include "mech-otp-skey-common.h"
|
||||
+#include "settings-parser.h"
|
||||
+#include "password-scheme.h"
|
||||
+#include "test-common.h"
|
||||
+#include "test-auth.h"
|
||||
+#include "auth-token.h"
|
||||
+
|
||||
+#include <unistd.h>
|
||||
+#include <time.h>
|
||||
+
|
||||
+#define UCHAR_LEN(str) (const unsigned char *)(str), sizeof(str)-1
|
||||
+
|
||||
+extern const struct mech_module mech_oauthbearer;
|
||||
+extern const struct mech_module mech_otp;
|
||||
+extern const struct mech_module mech_ntlm;
|
||||
+extern const struct mech_module mech_rpa;
|
||||
+
|
||||
+static struct auth_settings set;
|
||||
+static struct mechanisms_register *mech_reg;
|
||||
+
|
||||
+struct test_case {
|
||||
+ const struct mech_module *mech;
|
||||
+ const unsigned char *in;
|
||||
+ size_t len;
|
||||
+ const char *username;
|
||||
+ const char *expect_error;
|
||||
+ bool success;
|
||||
+ bool set_username_before_test;
|
||||
+ bool set_cert_username;
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+verify_plain_continue_mock_callback(struct auth_request *request,
|
||||
+ verify_plain_callback_t *callback)
|
||||
+{
|
||||
+ request->passdb_success = TRUE;
|
||||
+ callback(PASSDB_RESULT_OK, request);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+request_handler_reply_mock_callback(struct auth_request *request,
|
||||
+ enum auth_client_result result,
|
||||
+ const void *auth_reply ATTR_UNUSED,
|
||||
+ size_t reply_size ATTR_UNUSED)
|
||||
+{
|
||||
+ request->failed = result != AUTH_CLIENT_RESULT_SUCCESS;
|
||||
+
|
||||
+ if (request->passdb_result == PASSDB_RESULT_OK)
|
||||
+ request->failed = FALSE;
|
||||
+ else if (request->mech == &mech_otp) {
|
||||
+ if (null_strcmp(request->user, "otp_phase_2") == 0)
|
||||
+ request->failed = FALSE;
|
||||
+ } else if (request->mech == &mech_oauthbearer) {
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+request_handler_reply_continue_mock_callback(struct auth_request *request,
|
||||
+ const void *reply,
|
||||
+ size_t reply_size)
|
||||
+{
|
||||
+ request->context = p_strndup(request->pool, reply, reply_size);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+auth_client_request_mock_callback(const char *reply ATTR_UNUSED,
|
||||
+ struct auth_client_connection *conn ATTR_UNUSED)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void test_mechs_init(void)
|
||||
+{
|
||||
+ const char *const services[] = {NULL};
|
||||
+ process_start_time = time(NULL);
|
||||
+
|
||||
+ /* Copy default settings */
|
||||
+ set = *(struct auth_settings *) auth_setting_parser_info.defaults;
|
||||
+ global_auth_settings = &set;
|
||||
+ global_auth_settings->base_dir = ".";
|
||||
+ memset((&set)->username_chars_map, 1, sizeof((&set)->username_chars_map));
|
||||
+ set.username_format = "";
|
||||
+
|
||||
+ t_array_init(&set.passdbs, 2);
|
||||
+ struct auth_passdb_settings *mock_set = t_new(struct auth_passdb_settings, 1);
|
||||
+ *mock_set = mock_passdb_set;
|
||||
+ array_push_back(&set.passdbs, &mock_set);
|
||||
+ mock_set = t_new(struct auth_passdb_settings, 1);
|
||||
+ *mock_set = mock_passdb_set;
|
||||
+ mock_set->master = TRUE;
|
||||
+ array_push_back(&set.passdbs, &mock_set);
|
||||
+ t_array_init(&set.userdbs, 1);
|
||||
+
|
||||
+ /* Disable stats */
|
||||
+ set.stats = FALSE;
|
||||
+
|
||||
+ /* For tests of digest-md5. */
|
||||
+ set.realms_arr = t_strsplit_spaces("example.com ", " ");
|
||||
+ /* For tests of mech-anonymous. */
|
||||
+ set.anonymous_username = "anonuser";
|
||||
+
|
||||
+ mech_init(global_auth_settings);
|
||||
+ mech_reg = mech_register_init(global_auth_settings);
|
||||
+ passdbs_init();
|
||||
+ userdbs_init();
|
||||
+ passdb_mock_mod_init();
|
||||
+ password_schemes_init();
|
||||
+
|
||||
+ auths_preinit(&set, pool_datastack_create(), mech_reg, services);
|
||||
+ auths_init();
|
||||
+ auth_token_init();
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void test_rpa(void)
|
||||
+{
|
||||
+ test_mechs_init();
|
||||
+ static struct auth_request_handler handler = {
|
||||
+ .callback = auth_client_request_mock_callback,
|
||||
+ .reply_callback = request_handler_reply_mock_callback,
|
||||
+ .reply_continue_callback = request_handler_reply_continue_mock_callback,
|
||||
+ .verify_plain_continue_callback = verify_plain_continue_mock_callback,
|
||||
+ };
|
||||
+
|
||||
+ const struct mech_module *mech = &mech_rpa;
|
||||
+ test_begin("test rpa");
|
||||
+ struct auth_request *req = mech->auth_new();
|
||||
+ global_auth_settings->realms_arr = t_strsplit("example.com", " ");
|
||||
+ req->set = global_auth_settings;
|
||||
+ req->service = "login";
|
||||
+ req->handler = &handler;
|
||||
+ req->mech_event = event_create(NULL);
|
||||
+ req->event = event_create(NULL);
|
||||
+ req->mech = mech;
|
||||
+ req->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
|
||||
+ auth_request_state_count[AUTH_REQUEST_STATE_MECH_CONTINUE] = 1;
|
||||
+ mech->auth_initial(req, UCHAR_LEN("\x60\x11\x06\x09\x60\x86\x48\x01\x86\xf8\x73\x01\x01\x01\x00\x04\x00\x00\x01"));
|
||||
+ mech->auth_continue(req, UCHAR_LEN("\x60\x11\x06\x09\x60\x86\x48\x01\x86\xf8\x73\x01\x01\x00\x03A@A\x00"));
|
||||
+ test_assert(req->failed == TRUE);
|
||||
+ test_assert(req->passdb_success == FALSE);
|
||||
+ event_unref(&req->mech_event);
|
||||
+ event_unref(&req->event);
|
||||
+ mech->auth_free(req);
|
||||
+ test_end();
|
||||
+}
|
||||
+
|
||||
+static void test_ntlm(void)
|
||||
+{
|
||||
+ static struct auth_request_handler handler = {
|
||||
+ .callback = auth_client_request_mock_callback,
|
||||
+ .reply_callback = request_handler_reply_mock_callback,
|
||||
+ .reply_continue_callback = request_handler_reply_continue_mock_callback,
|
||||
+ .verify_plain_continue_callback = verify_plain_continue_mock_callback,
|
||||
+ };
|
||||
+
|
||||
+ const struct mech_module *mech = &mech_ntlm;
|
||||
+ test_begin("test ntlm");
|
||||
+ struct auth_request *req = mech->auth_new();
|
||||
+ global_auth_settings->realms_arr = t_strsplit("example.com", " ");
|
||||
+ req->set = global_auth_settings;
|
||||
+ req->service = "login";
|
||||
+ req->handler = &handler;
|
||||
+ req->mech_event = event_create(NULL);
|
||||
+ req->event = event_create(NULL);
|
||||
+ req->mech = mech;
|
||||
+ req->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
|
||||
+ auth_request_state_count[AUTH_REQUEST_STATE_MECH_CONTINUE] = 1;
|
||||
+ mech->auth_initial(req, UCHAR_LEN("NTLMSSP\x00\x01\x00\x00\x00\x00\x02\x00\x00""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
|
||||
+ mech->auth_continue(req, UCHAR_LEN("NTLMSSP\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00""AA\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00""orange""\x00"));
|
||||
+ test_assert(req->failed == TRUE);
|
||||
+ test_assert(req->passdb_success == FALSE);
|
||||
+ event_unref(&req->mech_event);
|
||||
+ event_unref(&req->event);
|
||||
+ mech->auth_free(req);
|
||||
+ test_end();
|
||||
+}
|
||||
+
|
||||
+int main(void)
|
||||
+{
|
||||
+ static void (*const test_functions[])(void) = {
|
||||
+ test_rpa,
|
||||
+ test_ntlm,
|
||||
+ NULL
|
||||
+ };
|
||||
+
|
||||
+ return test_run(test_functions);
|
||||
+}
|
@ -1,345 +0,0 @@
|
||||
diff -up dovecot-2.3.8/src/auth/Makefile.am.CVE_2020_12674prereq dovecot-2.3.8/src/auth/Makefile.am
|
||||
--- dovecot-2.3.8/src/auth/Makefile.am.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/Makefile.am 2020-08-07 20:46:56.095295825 +0200
|
||||
@@ -38,6 +38,7 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/lib-oauth2 \
|
||||
-I$(top_srcdir)/src/lib-ssl-iostream \
|
||||
-I$(top_srcdir)/src/lib-lua \
|
||||
+ -I$(top_srcdir)/src/lib-dcrypt \
|
||||
-DAUTH_MODULE_DIR=\""$(auth_moduledir)"\" \
|
||||
-DPKG_LIBEXECDIR=\""$(pkglibexecdir)"\" \
|
||||
-DPKG_RUNDIR=\""$(rundir)"\" \
|
||||
@@ -248,7 +249,8 @@ libstats_auth_la_SOURCES = auth-stats.c
|
||||
test_programs = \
|
||||
test-libpassword \
|
||||
test-auth-cache \
|
||||
- test-auth
|
||||
+ test-auth \
|
||||
+ test-mech
|
||||
|
||||
noinst_PROGRAMS = $(test_programs)
|
||||
|
||||
@@ -288,6 +290,13 @@ test_auth_SOURCES = \
|
||||
test_auth_LDADD = $(test_libs) $(auth_libs) $(AUTH_LIBS)
|
||||
test_auth_DEPENDENCIES = $(pkglibexec_PROGRAMS) $(test_libs)
|
||||
|
||||
+test_mech_SOURCES = \
|
||||
+ test-mock.c \
|
||||
+ test-mech.c
|
||||
+
|
||||
+test_mech_LDADD = $(test_libs) $(auth_libs) $(AUTH_LIBS)
|
||||
+test_mech_DEPENDENCIES = $(pkglibexec_PROGRAMS) $(test_libs)
|
||||
+
|
||||
check-local:
|
||||
for bin in $(test_programs); do \
|
||||
if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \
|
||||
diff -up dovecot-2.3.8/src/auth/passdb.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/passdb.h
|
||||
--- dovecot-2.3.8/src/auth/passdb.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/passdb.h 2020-08-07 20:35:16.295684287 +0200
|
||||
@@ -24,6 +24,8 @@ enum passdb_result {
|
||||
|
||||
typedef void verify_plain_callback_t(enum passdb_result result,
|
||||
struct auth_request *request);
|
||||
+typedef void verify_plain_continue_callback_t(struct auth_request *request,
|
||||
+ verify_plain_callback_t *callback);
|
||||
typedef void lookup_credentials_callback_t(enum passdb_result result,
|
||||
const unsigned char *credentials,
|
||||
size_t size,
|
||||
diff -up dovecot-2.3.8/src/auth/auth-request-handler-private.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request-handler-private.h
|
||||
--- dovecot-2.3.8/src/auth/auth-request-handler-private.h.CVE_2020_12674prereq 2020-08-07 20:35:16.295684287 +0200
|
||||
+++ dovecot-2.3.8/src/auth/auth-request-handler-private.h 2020-08-07 20:35:16.295684287 +0200
|
||||
@@ -0,0 +1,27 @@
|
||||
+#ifndef AUTH_REQUEST_HANDLER_PRIVATE_H
|
||||
+#define AUTH_REQUEST_HANDLER_PRIVATE_H
|
||||
+
|
||||
+struct auth_request;
|
||||
+struct auth_client_connection;
|
||||
+
|
||||
+struct auth_request_handler {
|
||||
+ int refcount;
|
||||
+ pool_t pool;
|
||||
+ HASH_TABLE(void *, struct auth_request *) requests;
|
||||
+
|
||||
+ unsigned int connect_uid, client_pid;
|
||||
+
|
||||
+ auth_client_request_callback_t *callback;
|
||||
+ struct auth_client_connection *conn;
|
||||
+
|
||||
+ auth_master_request_callback_t *master_callback;
|
||||
+ auth_request_handler_reply_callback_t *reply_callback;
|
||||
+ auth_request_handler_reply_continue_callback_t *reply_continue_callback;
|
||||
+ verify_plain_continue_callback_t *verify_plain_continue_callback;
|
||||
+
|
||||
+ bool destroyed:1;
|
||||
+ bool token_auth:1;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#endif
|
||||
diff -up dovecot-2.3.8/src/auth/auth-request-handler.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request-handler.h
|
||||
--- dovecot-2.3.8/src/auth/auth-request-handler.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/auth-request-handler.h 2020-08-07 20:35:16.295684287 +0200
|
||||
@@ -17,6 +17,17 @@ auth_client_request_callback_t(const cha
|
||||
typedef void
|
||||
auth_master_request_callback_t(const char *reply, struct auth_master_connection *conn);
|
||||
|
||||
+typedef void
|
||||
+auth_request_handler_reply_callback_t(struct auth_request *request,
|
||||
+ enum auth_client_result result,
|
||||
+ const void *auth_reply,
|
||||
+ size_t reply_size);
|
||||
+typedef void
|
||||
+auth_request_handler_reply_continue_callback_t(struct auth_request *request,
|
||||
+ const void *reply,
|
||||
+ size_t reply_size);
|
||||
+
|
||||
+
|
||||
struct auth_request_handler *
|
||||
auth_request_handler_create(bool token_auth, auth_client_request_callback_t *callback,
|
||||
struct auth_client_connection *conn,
|
||||
diff -up dovecot-2.3.8/src/auth/test-mock.c.CVE_2020_12674prereq dovecot-2.3.8/src/auth/test-mock.c
|
||||
--- dovecot-2.3.8/src/auth/test-mock.c.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/test-mock.c 2020-08-07 20:35:16.296684273 +0200
|
||||
@@ -28,14 +28,22 @@ static void passdb_mock_verify_plain(str
|
||||
callback(PASSDB_RESULT_OK, request);
|
||||
}
|
||||
|
||||
+static void passdb_mock_lookup_credentials(struct auth_request *request,
|
||||
+ lookup_credentials_callback_t *callback)
|
||||
+{
|
||||
+ passdb_handle_credentials(PASSDB_RESULT_OK, "password", "PLAIN",
|
||||
+ callback, request);
|
||||
+}
|
||||
+
|
||||
static struct passdb_module_interface mock_interface = {
|
||||
.name = "mock",
|
||||
.init = passdb_mock_init,
|
||||
.deinit = passdb_mock_deinit,
|
||||
.verify_plain = passdb_mock_verify_plain,
|
||||
+ .lookup_credentials = passdb_mock_lookup_credentials,
|
||||
};
|
||||
|
||||
-static struct auth_passdb_settings set = {
|
||||
+struct auth_passdb_settings mock_passdb_set = {
|
||||
.name = "mock",
|
||||
.driver = "mock",
|
||||
.args = "",
|
||||
@@ -95,7 +103,7 @@ void passdb_mock_mod_deinit(void)
|
||||
struct auth_passdb *passdb_mock(void)
|
||||
{
|
||||
struct auth_passdb *ret = i_new(struct auth_passdb, 1);
|
||||
- ret->set = &set;
|
||||
+ ret->set = &mock_passdb_set;
|
||||
ret->passdb = mock_passdb_mod;
|
||||
return ret;
|
||||
}
|
||||
diff -up dovecot-2.3.8/src/auth/test-auth.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/test-auth.h
|
||||
--- dovecot-2.3.8/src/auth/test-auth.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/test-auth.h 2020-08-07 20:35:16.296684273 +0200
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
struct auth_passdb;
|
||||
|
||||
+extern struct auth_passdb_settings mock_passdb_set;
|
||||
+
|
||||
void test_auth_request_var_expand(void);
|
||||
void test_db_dict_parse_cache_key(void);
|
||||
void test_username_filter(void);
|
||||
diff -up dovecot-2.3.8/src/auth/auth-request.c.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request.c
|
||||
--- dovecot-2.3.8/src/auth/auth-request.c.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/auth-request.c 2020-08-07 20:35:16.295684287 +0200
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "auth-cache.h"
|
||||
#include "auth-request.h"
|
||||
#include "auth-request-handler.h"
|
||||
+#include "auth-request-handler-private.h"
|
||||
#include "auth-request-stats.h"
|
||||
#include "auth-client-connection.h"
|
||||
#include "auth-master-connection.h"
|
||||
@@ -67,9 +68,6 @@ static void
|
||||
auth_request_userdb_import(struct auth_request *request, const char *args);
|
||||
|
||||
static
|
||||
-void auth_request_verify_plain_continue(struct auth_request *request,
|
||||
- verify_plain_callback_t *callback);
|
||||
-static
|
||||
void auth_request_lookup_credentials_policy_continue(struct auth_request *request,
|
||||
lookup_credentials_callback_t *callback);
|
||||
static
|
||||
@@ -307,10 +307,12 @@ void auth_request_success_continue(struct auth_policy_check_ctx *ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
- stats = auth_request_stats_get(request);
|
||||
- stats->auth_success_count++;
|
||||
- if (request->master_user != NULL)
|
||||
- stats->auth_master_success_count++;
|
||||
+ if (request->set->stats) {
|
||||
+ stats = auth_request_stats_get(request);
|
||||
+ stats->auth_success_count++;
|
||||
+ if (request->master_user != NULL)
|
||||
+ stats->auth_master_success_count++;
|
||||
+ }
|
||||
|
||||
auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED);
|
||||
auth_request_refresh_last_access(request);
|
||||
@@ -324,8 +326,10 @@ void auth_request_fail(struct auth_request *request)
|
||||
|
||||
i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
|
||||
|
||||
- stats = auth_request_stats_get(request);
|
||||
- stats->auth_failure_count++;
|
||||
+ if (request->set->stats) {
|
||||
+ stats = auth_request_stats_get(request);
|
||||
+ stats->auth_failure_count++;
|
||||
+ }
|
||||
|
||||
auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED);
|
||||
auth_request_refresh_last_access(request);
|
||||
@@ -1233,7 +1231,7 @@ void auth_request_policy_penalty_finish(
|
||||
|
||||
switch(ctx->type) {
|
||||
case AUTH_POLICY_CHECK_TYPE_PLAIN:
|
||||
- auth_request_verify_plain_continue(ctx->request, ctx->callback_plain);
|
||||
+ ctx->request->handler->verify_plain_continue_callback(ctx->request, ctx->callback_plain);
|
||||
return;
|
||||
case AUTH_POLICY_CHECK_TYPE_LOOKUP:
|
||||
auth_request_lookup_credentials_policy_continue(ctx->request, ctx->callback_lookup);
|
||||
@@ -1284,7 +1282,8 @@ void auth_request_verify_plain(struct au
|
||||
request->user_changed_by_lookup = FALSE;
|
||||
|
||||
if (request->policy_processed || !request->set->policy_check_before_auth) {
|
||||
- auth_request_verify_plain_continue(request, callback);
|
||||
+ request->handler->verify_plain_continue_callback(request,
|
||||
+ callback);
|
||||
} else {
|
||||
ctx = p_new(request->pool, struct auth_policy_check_ctx, 1);
|
||||
ctx->request = request;
|
||||
@@ -1294,10 +1293,9 @@ void auth_request_verify_plain(struct au
|
||||
}
|
||||
}
|
||||
|
||||
-static
|
||||
-void auth_request_verify_plain_continue(struct auth_request *request,
|
||||
- verify_plain_callback_t *callback) {
|
||||
-
|
||||
+void auth_request_default_verify_plain_continue(struct auth_request *request,
|
||||
+ verify_plain_callback_t *callback)
|
||||
+{
|
||||
struct auth_passdb *passdb;
|
||||
enum passdb_result result;
|
||||
const char *cache_key, *error;
|
||||
diff -up dovecot-2.3.8/src/auth/auth-request-handler.c.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request-handler.c
|
||||
--- dovecot-2.3.8/src/auth/auth-request-handler.c.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/auth-request-handler.c 2020-08-07 20:35:16.295684287 +0200
|
||||
@@ -17,32 +17,28 @@
|
||||
#include "auth-client-connection.h"
|
||||
#include "auth-master-connection.h"
|
||||
#include "auth-request-handler.h"
|
||||
+#include "auth-request-handler-private.h"
|
||||
#include "auth-policy.h"
|
||||
|
||||
#define AUTH_FAILURE_DELAY_CHECK_MSECS 500
|
||||
-
|
||||
-struct auth_request_handler {
|
||||
- int refcount;
|
||||
- pool_t pool;
|
||||
- HASH_TABLE(void *, struct auth_request *) requests;
|
||||
-
|
||||
- unsigned int connect_uid, client_pid;
|
||||
-
|
||||
- auth_client_request_callback_t *callback;
|
||||
- struct auth_client_connection *conn;
|
||||
-
|
||||
- auth_master_request_callback_t *master_callback;
|
||||
-
|
||||
- bool destroyed:1;
|
||||
- bool token_auth:1;
|
||||
-};
|
||||
-
|
||||
static ARRAY(struct auth_request *) auth_failures_arr;
|
||||
static struct aqueue *auth_failures;
|
||||
static struct timeout *to_auth_failures;
|
||||
|
||||
static void auth_failure_timeout(void *context) ATTR_NULL(1);
|
||||
|
||||
+
|
||||
+static void
|
||||
+auth_request_handler_default_reply_callback(struct auth_request *request,
|
||||
+ enum auth_client_result result,
|
||||
+ const void *auth_reply,
|
||||
+ size_t reply_size);
|
||||
+
|
||||
+static void
|
||||
+auth_request_handler_default_reply_continue(struct auth_request *request,
|
||||
+ const void *reply,
|
||||
+ size_t reply_size);
|
||||
+
|
||||
struct auth_request_handler *
|
||||
auth_request_handler_create(bool token_auth, auth_client_request_callback_t *callback,
|
||||
struct auth_client_connection *conn,
|
||||
@@ -61,6 +57,12 @@ auth_request_handler_create(bool token_a
|
||||
handler->conn = conn;
|
||||
handler->master_callback = master_callback;
|
||||
handler->token_auth = token_auth;
|
||||
+ handler->reply_callback =
|
||||
+ auth_request_handler_default_reply_callback;
|
||||
+ handler->reply_continue_callback =
|
||||
+ auth_request_handler_default_reply_continue;
|
||||
+ handler->verify_plain_continue_callback =
|
||||
+ auth_request_default_verify_plain_continue;
|
||||
return handler;
|
||||
}
|
||||
|
||||
@@ -355,6 +363,16 @@ void auth_request_handler_reply(struct a
|
||||
enum auth_client_result result,
|
||||
const void *auth_reply, size_t reply_size)
|
||||
{
|
||||
+ struct auth_request_handler *handler = request->handler;
|
||||
+ handler->reply_callback(request, result, auth_reply, reply_size);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+auth_request_handler_default_reply_callback(struct auth_request *request,
|
||||
+ enum auth_client_result result,
|
||||
+ const void *auth_reply,
|
||||
+ size_t reply_size)
|
||||
+{
|
||||
struct auth_request_handler *handler = request->handler;
|
||||
string_t *str;
|
||||
int ret;
|
||||
@@ -407,6 +425,14 @@ void auth_request_handler_reply(struct a
|
||||
void auth_request_handler_reply_continue(struct auth_request *request,
|
||||
const void *reply, size_t reply_size)
|
||||
{
|
||||
+ request->handler->reply_continue_callback(request, reply, reply_size);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+auth_request_handler_default_reply_continue(struct auth_request *request,
|
||||
+ const void *reply,
|
||||
+ size_t reply_size)
|
||||
+{
|
||||
auth_request_handler_reply(request, AUTH_CLIENT_RESULT_CONTINUE,
|
||||
reply, reply_size);
|
||||
}
|
||||
@@ -703,6 +729,7 @@ static void auth_str_append_userdb_extra
|
||||
auth_str_add_keyvalue(dest, "master_user",
|
||||
request->master_user);
|
||||
}
|
||||
+ auth_str_add_keyvalue(dest, "auth_mech", request->mech->mech_name);
|
||||
if (*request->set->anonymous_username != '\0' &&
|
||||
strcmp(request->user, request->set->anonymous_username) == 0) {
|
||||
/* this is an anonymous login, either via ANONYMOUS
|
||||
diff -up dovecot-2.3.8/src/auth/auth-request.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request.h
|
||||
--- dovecot-2.3.8/src/auth/auth-request.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200
|
||||
+++ dovecot-2.3.8/src/auth/auth-request.h 2020-08-07 20:35:16.295684287 +0200
|
||||
@@ -295,6 +295,8 @@ void auth_request_set_credentials(struct
|
||||
set_credentials_callback_t *callback);
|
||||
void auth_request_userdb_callback(enum userdb_result result,
|
||||
struct auth_request *request);
|
||||
+void auth_request_default_verify_plain_continue(struct auth_request *request,
|
||||
+ verify_plain_callback_t *callback);
|
||||
|
||||
void auth_request_refresh_last_access(struct auth_request *request);
|
||||
void auth_str_append(string_t *dest, const char *key, const char *value);
|
@ -1,73 +0,0 @@
|
||||
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
|
||||
index 011dea9050..8baf622e59 100644
|
||||
--- a/src/lib-mail/message-parser.c
|
||||
+++ b/src/lib-mail/message-parser.c
|
||||
@@ -138,6 +138,7 @@ message_part_append(struct message_parser_ctx *ctx)
|
||||
struct message_part *parent = ctx->part;
|
||||
struct message_part *part;
|
||||
|
||||
+ i_assert(!ctx->preparsed);
|
||||
i_assert(parent != NULL);
|
||||
i_assert((parent->flags & (MESSAGE_PART_FLAG_MULTIPART |
|
||||
MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0);
|
||||
@@ -171,12 +172,14 @@ static void message_part_finish(struct message_parser_ctx *ctx)
|
||||
{
|
||||
struct message_part **const *parent_next_partp;
|
||||
|
||||
- i_assert(ctx->nested_parts_count > 0);
|
||||
- ctx->nested_parts_count--;
|
||||
+ if (!ctx->preparsed) {
|
||||
+ i_assert(ctx->nested_parts_count > 0);
|
||||
+ ctx->nested_parts_count--;
|
||||
|
||||
- parent_next_partp = array_back(&ctx->next_part_stack);
|
||||
- array_pop_back(&ctx->next_part_stack);
|
||||
- ctx->next_part = *parent_next_partp;
|
||||
+ parent_next_partp = array_back(&ctx->next_part_stack);
|
||||
+ array_pop_back(&ctx->next_part_stack);
|
||||
+ ctx->next_part = *parent_next_partp;
|
||||
+ }
|
||||
|
||||
message_size_add(&ctx->part->parent->body_size, &ctx->part->body_size);
|
||||
message_size_add(&ctx->part->parent->body_size, &ctx->part->header_size);
|
||||
diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c
|
||||
index 13984f939e..a00f0d6200 100644
|
||||
--- a/src/lib-mail/test-message-parser.c
|
||||
+++ b/src/lib-mail/test-message-parser.c
|
||||
@@ -178,9 +178,10 @@ static void test_message_parser_small_blocks(void)
|
||||
static void test_message_parser_stop_early(void)
|
||||
{
|
||||
struct message_parser_ctx *parser;
|
||||
- struct istream *input;
|
||||
+ struct istream *input, *input2;
|
||||
struct message_part *parts;
|
||||
struct message_block block;
|
||||
+ const char *error;
|
||||
unsigned int i;
|
||||
pool_t pool;
|
||||
int ret;
|
||||
@@ -198,6 +199,24 @@ static void test_message_parser_stop_early(void)
|
||||
&block)) > 0) ;
|
||||
test_assert(ret == 0);
|
||||
message_parser_deinit(&parser, &parts);
|
||||
+
|
||||
+ /* test preparsed - first re-parse everything with a stream
|
||||
+ that sees EOF at this position */
|
||||
+ input2 = i_stream_create_from_data(test_msg, i);
|
||||
+ parser = message_parser_init(pool, input2, &set_empty);
|
||||
+ while ((ret = message_parser_parse_next_block(parser,
|
||||
+ &block)) > 0) ;
|
||||
+ test_assert(ret == -1);
|
||||
+ message_parser_deinit(&parser, &parts);
|
||||
+
|
||||
+ /* now parse from the parts */
|
||||
+ i_stream_seek(input2, 0);
|
||||
+ parser = message_parser_init_from_parts(parts, input2, &set_empty);
|
||||
+ while ((ret = message_parser_parse_next_block(parser,
|
||||
+ &block)) > 0) ;
|
||||
+ test_assert(ret == -1);
|
||||
+ test_assert(message_parser_deinit_from_parts(&parser, &parts, &error) == 0);
|
||||
+ i_stream_unref(&input2);
|
||||
}
|
||||
|
||||
i_stream_unref(&input);
|
@ -1,20 +0,0 @@
|
||||
diff -up dovecot-2.3.8/src/lib-storage/index/index-mail-binary.c.blockcount dovecot-2.3.8/src/lib-storage/index/index-mail-binary.c
|
||||
--- dovecot-2.3.8/src/lib-storage/index/index-mail-binary.c.blockcount 2020-12-02 11:34:10.229027593 +0100
|
||||
+++ dovecot-2.3.8/src/lib-storage/index/index-mail-binary.c 2020-12-02 11:36:47.328933276 +0100
|
||||
@@ -339,13 +339,14 @@ blocks_count_lines(struct binary_ctx *ct
|
||||
i_stream_skip(full_input, skip);
|
||||
cur_block_offset += skip;
|
||||
|
||||
- if (cur_block->input->eof) {
|
||||
+ if (i_stream_read_eof(cur_block->input)) {
|
||||
/* go to the next block */
|
||||
- if (++block_idx == block_count) {
|
||||
+ if (block_idx+1 == block_count) {
|
||||
i_assert(i_stream_read_eof(full_input));
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
+ block_idx++;
|
||||
cur_block++;
|
||||
cur_block_offset = 0;
|
||||
}
|
@ -3,9 +3,9 @@
|
||||
Summary: Secure imap and pop3 server
|
||||
Name: dovecot
|
||||
Epoch: 1
|
||||
Version: 2.3.8
|
||||
Version: 2.3.16
|
||||
%global prever %{nil}
|
||||
Release: 9%{?dist}
|
||||
Release: 2%{?dist}
|
||||
#dovecot itself is MIT, a few sources are PD, pigeonhole is LGPLv2
|
||||
License: MIT and LGPLv2
|
||||
Group: System Environment/Daemons
|
||||
@ -14,7 +14,7 @@ URL: http://www.dovecot.org/
|
||||
Source: http://www.dovecot.org/releases/2.3/%{name}-%{version}%{?prever}.tar.gz
|
||||
Source1: dovecot.init
|
||||
Source2: dovecot.pam
|
||||
%global pigeonholever 0.5.8
|
||||
%global pigeonholever 0.5.16
|
||||
Source8: http://pigeonhole.dovecot.org/releases/2.3/dovecot-2.3-pigeonhole-%{pigeonholever}.tar.gz
|
||||
Source9: dovecot.sysconfig
|
||||
Source10: dovecot.tmpfilesd
|
||||
@ -43,39 +43,9 @@ Patch13: dovecot-2.2.36-bigkey.patch
|
||||
# hard to break circular dependency between lib and lib-dcrypt
|
||||
Patch14: dovecot-2.3.6-opensslhmac.patch
|
||||
|
||||
# from upstream, for dovecot < 2.3.10.1
|
||||
Patch15: dovecot-2.3.10-smtppre.patch
|
||||
Patch16: dovecot-2.3.10-CVE_2020_10957,10958,10967.patch
|
||||
|
||||
# from upstream, for dovecot <= 2.3.10.1
|
||||
Patch17: dovecot-2.3.8-CVE_2020_12100prereq.patch
|
||||
Patch18: dovecot-2.3.8-CVE_2020_12100.patch
|
||||
Patch19: dovecot-2.3.8-CVE_2020_12100ph.patch
|
||||
Patch20: dovecot-2.3.8-CVE_2020_12673.patch
|
||||
Patch21: dovecot-2.3.8-CVE_2020_12674prereq.patch
|
||||
Patch22: dovecot-2.3.8-CVE_2020_12674.patch
|
||||
|
||||
# from upstream, for dovecot <= 2.3.11.3, rhbz#1894418
|
||||
Patch23: dovecot-2.3.8-blockcount.patch
|
||||
|
||||
# from upstream, for dovecot < 2.3.11.3, rhbz#1888111
|
||||
Patch24: dovecot-2.3.8-a668d767.patch
|
||||
Patch25: dovecot-2.3.13-CVE_2020_25275-part1.patch
|
||||
Patch26: dovecot-2.3.13-CVE_2020_25275-part2.patch
|
||||
Patch27: dovecot-2.3.13-CVE_2020_25275-part3.patch
|
||||
Patch28: dovecot-2.3.13-CVE_2020_25275-part4.patch
|
||||
Patch29: dovecot-2.3.13-CVE_2020_25275-part5.patch
|
||||
Patch30: dovecot-2.3.13-CVE_2020_25275-part6.patch
|
||||
Patch31: dovecot-2.3.13-CVE_2020_25275-part7.patch
|
||||
Patch32: dovecot-2.3.13-CVE_2020_25275-part8.patch
|
||||
Patch33: dovecot-2.3.13-CVE_2020_25275regr-part1.patch
|
||||
Patch34: dovecot-2.3.13-CVE_2020_25275regr-part2.patch
|
||||
Patch35: dovecot-2.3.13-CVE_2020_25275regr-part3.patch
|
||||
Patch36: dovecot-2.3.13-CVE_2020_24386-prereq1.patch
|
||||
Patch37: dovecot-2.3.13-CVE_2020_24386-part1.patch
|
||||
Patch38: dovecot-2.3.13-CVE_2020_24386-part2.patch
|
||||
Patch39: dovecot-2.3.13-CVE_2020_24386-part3.patch
|
||||
Patch40: dovecot-2.3.13-CVE_2020_24386-part4.patch
|
||||
# from upstream, for dovecot < 2.3.17, s390x FTBFS fix
|
||||
Patch15: dovecot-2.3.16-ftbfsbigend.patch
|
||||
Patch16: dovecot-2.3.16-keeplzma.patch
|
||||
|
||||
Source15: prestartscript
|
||||
|
||||
@ -181,32 +151,8 @@ This package provides the development files for dovecot.
|
||||
%patch11 -p1 -b .aclfix
|
||||
%patch13 -p1 -b .bigkey
|
||||
%patch14 -p1 -b .opensslhmac
|
||||
%patch15 -p1 -b .smtppre
|
||||
%patch16 -p1 -b .CVE_2020_10957,10958,10967
|
||||
%patch17 -p1 -b .CVE_2020_12100prereq
|
||||
%patch18 -p1 -b .CVE_2020_12100
|
||||
%patch19 -p1 -b .CVE_2020_12100ph
|
||||
%patch20 -p1 -b .CVE_2020_12673
|
||||
%patch21 -p1 -b .CVE_2020_12674prereq
|
||||
%patch22 -p1 -b .CVE_2020_12674
|
||||
%patch23 -p1 -b .blockcount
|
||||
%patch24 -p1 -b .a668d767
|
||||
%patch25 -p1 -b .CVE_2020_25275-part1
|
||||
%patch26 -p1 -b .CVE_2020_25275-part2
|
||||
%patch27 -p1 -b .CVE_2020_25275-part3
|
||||
%patch28 -p1 -b .CVE_2020_25275-part4
|
||||
%patch29 -p1 -b .CVE_2020_25275-part5
|
||||
%patch30 -p1 -b .CVE_2020_25275-part6
|
||||
%patch31 -p1 -b .CVE_2020_25275-part7
|
||||
%patch32 -p1 -b .CVE_2020_25275-part8
|
||||
%patch33 -p1 -b .CVE_2020_25275regr-part1
|
||||
%patch34 -p1 -b .CVE_2020_25275regr-part2
|
||||
%patch35 -p1 -b .CVE_2020_25275regr-part3
|
||||
%patch36 -p1 -b .CVE_2020_24386-prereq1
|
||||
%patch37 -p1 -b .CVE_2020_24386-part1
|
||||
%patch38 -p1 -b .CVE_2020_24386-part2
|
||||
%patch39 -p1 -b .CVE_2020_24386-part3
|
||||
%patch40 -p1 -b .CVE_2020_24386-part4
|
||||
%patch15 -p1 -b .ftbfsbigend
|
||||
%patch16 -p1 -b .keeplzma
|
||||
pushd dovecot-2*3-pigeonhole-%{pigeonholever}
|
||||
|
||||
popd
|
||||
@ -226,6 +172,7 @@ autoreconf -I . -fiv #required for aarch64 support
|
||||
%configure \
|
||||
INSTALL_DATA="install -c -p -m644" \
|
||||
--with-rundir=%{_rundir}/%{name} \
|
||||
--with-systemd \
|
||||
--docdir=%{_docdir}/%{name} \
|
||||
--disable-static \
|
||||
--disable-rpath \
|
||||
@ -427,6 +374,7 @@ make check
|
||||
%{_bindir}/doveadm
|
||||
%{_bindir}/doveconf
|
||||
%{_bindir}/dsync
|
||||
%{_bindir}/dovecot-sysreport
|
||||
|
||||
|
||||
%if %{?fedora}0 > 140 || %{?rhel}0 > 60
|
||||
@ -448,6 +396,7 @@ make check
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-logging.conf
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-mail.conf
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-master.conf
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-metrics.conf
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/10-ssl.conf
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/15-lda.conf
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/15-mailboxes.conf
|
||||
@ -467,8 +416,6 @@ make check
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-sql.conf.ext
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-static.conf.ext
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-system.conf.ext
|
||||
%config(noreplace) %{_sysconfdir}/dovecot/conf.d/auth-vpopmail.conf.ext
|
||||
|
||||
%config(noreplace) %{_sysconfdir}/pam.d/dovecot
|
||||
%config(noreplace) %{ssldir}/dovecot-openssl.cnf
|
||||
|
||||
@ -509,10 +456,11 @@ make check
|
||||
%{_libexecdir}/%{name}
|
||||
%exclude %{_libexecdir}/%{name}/managesieve*
|
||||
|
||||
%attr(0755,root,dovecot) %ghost /var/run/dovecot
|
||||
%dir %attr(0755,root,dovecot) %ghost /var/run/dovecot
|
||||
%attr(0750,root,dovenull) %ghost /var/run/dovecot/login
|
||||
%attr(0750,root,dovenull) %ghost /var/run/dovecot/token-login
|
||||
%attr(0755,root,root) %ghost /var/run/dovecot/empty
|
||||
|
||||
%attr(0750,dovecot,dovecot) /var/lib/dovecot
|
||||
|
||||
%{_datadir}/%{name}
|
||||
@ -569,6 +517,13 @@ make check
|
||||
%{_libdir}/%{name}/dict/libdriver_pgsql.so
|
||||
|
||||
%changelog
|
||||
* Wed Dec 08 2021 Michal Hlavinka <mhlavink@redhat.com> - 1:2.3.16-2
|
||||
- do not disable xz/lzma for now despite being deprecated
|
||||
|
||||
* Wed Dec 08 2021 Michal Hlavinka <mhlavink@redhat.com> - 1:2.3.16-1
|
||||
- dovecot updated to 2.3.16, pigeonhole to 0.5.16
|
||||
- fix CVE-2021-33515 plaintext commands injection (#1980014)
|
||||
|
||||
* Wed Feb 03 2021 Michal Hlavinka <mhlavink@redhat.com> - 1:2.3.8-9
|
||||
- fix CVE-2020-24386 IMAP hibernation function allows mail access (#1913534)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user