1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
$NetBSD: patch-src_imapcommon.c,v 1.3 2020/04/16 14:03:29 manu Exp $
Build fixes for OpenSSL 1.1.1
SASL PLAIN Support. Patch submitted upstream
http://sourceforge.net/tracker/?func=detail&aid=3610674&group_id=311&atid=300311
--- src/imapcommon.c.orig 2010-07-26 09:08:47.000000000 +0200
+++ src/imapcommon.c 2020-04-16 15:49:08.132245848 +0200
@@ -397,18 +397,19 @@
ITD_Struct Server;
int rc;
unsigned int Expiration;
- EVP_MD_CTX mdctx;
+ EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
int md_len;
Expiration = PC_Struct.cache_expiration_time;
memset( &Server, 0, sizeof Server );
/* need to md5 the passwd regardless, so do that now */
- EVP_DigestInit(&mdctx, EVP_md5());
- EVP_DigestUpdate(&mdctx, Password, strlen(Password));
- EVP_DigestFinal(&mdctx, md5pw, &md_len);
+ EVP_DigestInit(mdctx, EVP_md5());
+ EVP_DigestUpdate(mdctx, Password, strlen(Password));
+ EVP_DigestFinal(mdctx, md5pw, &md_len);
+ EVP_MD_CTX_free(mdctx);
/* see if we have a reusable connection available */
ICC_Active = NULL;
HashIndex = Hash( Username, HASH_TABLE_SIZE );
@@ -689,13 +690,96 @@
}
#endif /* HAVE_LIBSSL */
+ /*
+ * If configured to do so, use SASL PLAIN instead of IMAP LOGIN
+ */
+ if ( PC_Struct.auth_sasl_mech &&
+ !strcmp( PC_Struct.auth_sasl_mech, "plain" ) )
+ {
+ /*
+ * Build SASL AUTH PLAIN string:
+ * username\0username\0password
+ */
+ char *ptr_username;
+ unsigned int username_size;
+ char *ptr_password;
+ unsigned int password_size;
+ unsigned int total_size;
+ unsigned int AuthBufIndex;
+ char AuthBuf[BUFSIZE];
+ char EncodedAuthBuf[BUFSIZE];
+
+ /*
+ * Strip quotes From username
+ */
+ ptr_username = Username;
+ username_size = strlen( Username );
+ if ( *ptr_username == '"' && *(ptr_username + username_size - 1) == '"' )
+ {
+ ++ptr_username;
+ username_size = username_size - 2;
+ }
+
+ /*
+ * Same with password
+ */
+ ptr_password = Password;
+ password_size = strlen( Password );
+ if ( *ptr_password == '"' && *(ptr_password + password_size - 1) == '"' )
+ {
+ ++ptr_password;
+ password_size = password_size - 2;
+ }
+
+ /*
+ * Make sure output buffer is big enough ( +3 for three \0 )
+ */
+ total_size = username_size + username_size + password_size + 3;
+ if ( total_size > sizeof(AuthBuf) ) {
+ syslog( LOG_INFO,
+ "LOGIN: '%s' (%s:%s) failed: PLAIN AUTH needs %d/%d bytes",
+ Username, ClientAddr, portstr, total_size, sizeof(AuthBuf));
+ goto fail;
+ }
+
+ /*
+ * Prepare the buffer
+ */
+ AuthBufIndex = 0;
+
+ memcpy( AuthBuf + AuthBufIndex, ptr_username, username_size );
+ AuthBufIndex += username_size;
+ AuthBuf[AuthBufIndex++] = '\0';
+
+ memcpy( AuthBuf + AuthBufIndex, ptr_username, username_size );
+ AuthBufIndex += username_size;
+ AuthBuf[AuthBufIndex++] = '\0';
+
+ memcpy( AuthBuf + AuthBufIndex, ptr_password, password_size );
+ AuthBufIndex += password_size;
+ AuthBuf[AuthBufIndex++] = '\0';
+
+ EVP_EncodeBlock( EncodedAuthBuf, AuthBuf, AuthBufIndex );
+
+ snprintf( SendBuf, BufLen, "A0001 AUTHENTICATE PLAIN %s\r\n", EncodedAuthBuf );
+
+ /* syslog( LOG_INFO, "sending auth plain '%s'", EncodedAuthBuf ); */
+
+ if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 )
+ {
+ syslog( LOG_INFO,
+ "LOGIN: '%s' (%s:%s) failed: IMAP_Write() failed attempting to send AUTHENTICATE command to IMAP server: %s",
+ Username, ClientAddr, portstr, strerror( errno ) );
+ goto fail;
+ }
+ }
/*
* Send the login command off to the IMAP server. Have to treat a literal
* password different.
*/
- if ( LiteralPasswd )
+ else if ( LiteralPasswd )
{
snprintf( SendBuf, BufLen, "A0001 LOGIN %s {%d}\r\n",
Username, strlen( Password ) );
if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 )
|