Codebase list cyrus-sasl2 / 88958ac
Add patch to fix login to dovecot imapd 2.x (Closes: #715040) Ondřej Surý 9 years ago
2 changed file(s) with 177 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 From 98b21c0aa01d4ef1e05158a79dc3e291e53bee81 Mon Sep 17 00:00:00 2001
1 From: Sebastian Pipping <sebastian@pipping.org>
2 Date: Fri, 5 Jul 2013 18:34:50 +0200
3 Subject: [PATCH] 2.1.26: Allow "* CAPABILITY" lines in IMAP login reply (v4)
4
5 ---
6 saslauthd/auth_rimap.c | 125 +++++++++++++++++++++++++++++++++++++++++++------
7 1 file changed, 111 insertions(+), 14 deletions(-)
8
9 --- cyrus-sasl2.orig/saslauthd/auth_rimap.c
10 +++ cyrus-sasl2/saslauthd/auth_rimap.c
11 @@ -3,6 +3,7 @@
12
13 /* COPYRIGHT
14 * Copyright (c) 1998 Messaging Direct Ltd.
15 + * Copyright (c) 2013 Sebastian Pipping <sebastian@pipping.org>
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 @@ -91,6 +92,9 @@ static struct addrinfo *ai = NULL; /* re
20 #define TAG "saslauthd" /* IMAP command tag */
21 #define LOGIN_CMD (TAG " LOGIN ") /* IMAP login command (with tag) */
22 #define LOGOUT_CMD (TAG " LOGOUT ") /* IMAP logout command (with tag)*/
23 +#define LOGIN_REPLY_GOOD (TAG " OK") /* Expected IMAP login reply, good edition (with tag) */
24 +#define LOGIN_REPLY_BAD (TAG " NO") /* Expected IMAP login reply, bad edition (with tag) */
25 +#define LOGIN_REPLY_CAP "* CAPABILITY" /* Expected IMAP login reply, capabilities edition */
26 #define NETWORK_IO_TIMEOUT 30 /* network I/O timeout (seconds) */
27 #define RESP_LEN 1000 /* size of read response buffer */
28
29 @@ -278,6 +282,109 @@ auth_rimap_init (
30
31 /* END FUNCTION: auth_rimap_init */
32
33 +typedef enum _t_login_status {
34 + LOGIN_STATUS_UNKNOWN,
35 +
36 + LOGIN_STATUS_ACCEPTED,
37 + LOGIN_STATUS_REJECTED,
38 + LOGIN_STATUS_MALFORMED
39 +} t_login_status;
40 +
41 +/* FUNCTION: warn_malformed_imap_login_reply */
42 +void
43 +warn_malformed_imap_login_reply(
44 + /* PARAMETERS */
45 + const char * server_reply /* I: plaintext server reply */
46 + /* END PARAMETERS */
47 + )
48 +{
49 + syslog(LOG_WARNING, "auth_rimap: unexpected response to auth request: %s", server_reply);
50 +}
51 +
52 +/* END FUNCTION: warn_malformed_imap_login_reply */
53 +
54 +/* FUNCTION: process_login_reply */
55 +
56 +/* SYNOPSIS
57 + * Classify IMAP server reply into accepted, rejected or malformed.
58 + * END SYNOPSIS */
59 +
60 +t_login_status
61 +process_login_reply(
62 + /* PARAMETERS */
63 + char * server_reply, /* I/O: plaintext server reply */
64 + const char * login /* I : plaintext authenticator */
65 + /* END PARAMETERS */
66 + )
67 +{
68 + /* VARIABLES */
69 + t_login_status res = LOGIN_STATUS_UNKNOWN;
70 + char * line_first = server_reply;
71 + char * line_after_last;
72 + /* END VARIABLES */
73 +
74 + for (;;) {
75 + /* find line boundary */
76 + line_after_last = strpbrk(line_first, "\x0a\x0d");
77 + if (line_after_last == NULL) {
78 + warn_malformed_imap_login_reply(line_first);
79 + return LOGIN_STATUS_MALFORMED;
80 + }
81 +
82 + /* handle single line */
83 + {
84 + /* terminate line (reverted later) */
85 + const char backup = line_after_last[0];
86 + line_after_last[0] = '\0';
87 +
88 + /* classify current line */
89 + if (strncmp(line_first, LOGIN_REPLY_GOOD, sizeof(LOGIN_REPLY_GOOD) - 1) == 0) {
90 + res = LOGIN_STATUS_ACCEPTED;
91 + } else if (strncmp(line_first, LOGIN_REPLY_BAD, sizeof(LOGIN_REPLY_BAD) - 1) == 0) {
92 + res = LOGIN_STATUS_REJECTED;
93 + } else if (strncmp(line_first, LOGIN_REPLY_CAP, sizeof(LOGIN_REPLY_CAP) - 1) == 0) {
94 + /* keep looking for ".. OK" or ".. NO" */
95 + } else {
96 + res = LOGIN_STATUS_MALFORMED;
97 + }
98 +
99 + /* report current line */
100 + if (res == LOGIN_STATUS_MALFORMED) {
101 + warn_malformed_imap_login_reply(line_first);
102 + } else if (flags & VERBOSE) {
103 + syslog(LOG_DEBUG, "auth_rimap: [%s] %s", login, line_first);
104 + }
105 +
106 + /* revert termination */
107 + line_after_last[0] = backup;
108 + }
109 +
110 + /* are we done? */
111 + if (res != LOGIN_STATUS_UNKNOWN) {
112 + return res;
113 + }
114 +
115 + /* forward to next line */
116 + while ((line_after_last[0] == '\x0a')
117 + || (line_after_last[0] == '\x0d')) {
118 + line_after_last++;
119 + }
120 +
121 + /* no more lines? */
122 + if (line_after_last[0] == '\0') {
123 + warn_malformed_imap_login_reply("");
124 + return LOGIN_STATUS_MALFORMED;
125 + }
126 +
127 + /* prepare for next round */
128 + line_first = line_after_last;
129 + }
130 +
131 + assert(! "cannot be reached");
132 +}
133 +
134 +/* END FUNCTION: process_login_reply */
135 +
136 /* FUNCTION: auth_rimap */
137
138 /* SYNOPSIS
139 @@ -318,6 +425,7 @@ auth_rimap (
140 char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
141 int saved_errno;
142 int niflags;
143 + t_login_status login_status = LOGIN_STATUS_MALFORMED;
144 /* END VARIABLES */
145
146 /* sanity checks */
147 @@ -533,25 +641,14 @@ auth_rimap (
148 }
149
150 rbuf[rc] = '\0'; /* tie off response */
151 - c = strpbrk(rbuf, "\r\n");
152 - if (c != NULL) {
153 - *c = '\0'; /* tie off line termination */
154 - }
155 + login_status = process_login_reply(rbuf, login);
156
157 - if (!strncmp(rbuf, TAG " OK", sizeof(TAG " OK")-1)) {
158 - if (flags & VERBOSE) {
159 - syslog(LOG_DEBUG, "auth_rimap: [%s] %s", login, rbuf);
160 - }
161 + if (login_status == LOGIN_STATUS_ACCEPTED) {
162 return strdup("OK remote authentication successful");
163 }
164 - if (!strncmp(rbuf, TAG " NO", sizeof(TAG " NO")-1)) {
165 - if (flags & VERBOSE) {
166 - syslog(LOG_DEBUG, "auth_rimap: [%s] %s", login, rbuf);
167 - }
168 + if (login_status == LOGIN_STATUS_REJECTED) {
169 return strdup("NO remote server rejected your credentials");
170 }
171 - syslog(LOG_WARNING, "auth_rimap: unexpected response to auth request: %s",
172 - rbuf);
173 return strdup(RESP_UNEXPECTED);
174
175 }
2828 0045_revert_upstream_soname_bump.patch
2929 0046_fix_void_return.patch
3030 properly-create-libsasl2.pc.patch
31 bug715040.patch