base64 functions with SASL in INN
Julien ÉLIE
julien at trigofacile.com
Fri Jun 19 18:12:56 UTC 2009
Hi,
http://www.kb.cert.org/vuls/id/238019
http://www.kb.cert.org/vuls/id/RGII-7RYLZQ
Cyrus SASL added a null character to the end of the output of sasl_encode64().
According to <https://bugzilla.redhat.com/show_bug.cgi?id=501452>, we need
in imap_connection.c:
inbase64 = xmalloc(outlen * 2 + 10);
/* convert to base64 */
saslresult = sasl_encode64(out, outlen,
- inbase64, outlen*2, (unsigned *) &inbase64len);
+ inbase64, outlen*2 + 1, (unsigned *) &inbase64len);
if (saslresult != SASL_OK) return RET_FAIL;
/* append endline */
strlcpy(inbase64 + inbase64len, "\r\n", outlen * 2 + 10 - inbase64len);
inbase64len+=2;
But I believe it should be "outlen*2 + 10" (and thus, there was already a bug).
I note that if a string has a length of n, the maximum length of its base64
conversion including the null terminator is (n/3+1)*4+1 so:
(n/3+1)*4+1 <= 2n+k
is equivalent to
2x >= 15-3k
which is true for all x if and only if k>=5.
I therefore believe "+6" is enough with the NULL character. But well,
we can keep "+10".
We also need that fix in nnrpd:
Index: innfeed/imap_connection.c
===================================================================
--- innfeed/imap_connection.c (révision 8509)
+++ innfeed/imap_connection.c (copie de travail)
@@ -2425,7 +2425,7 @@
/* convert to base64 */
saslresult = sasl_encode64(out, outlen,
- inbase64, outlen*2, (unsigned *) &inbase64len);
+ inbase64, outlen*2 + 10, (unsigned *) &inbase64len);
if (saslresult != SASL_OK) return RET_FAIL;
Index: nnrpd/sasl.c
===================================================================
--- nnrpd/sasl.c (révision 8509)
+++ nnrpd/sasl.c (copie de travail)
@@ -32,7 +32,8 @@
{ SASL_CB_LIST_END, NULL, NULL }
};
-#define BASE64_BUF_SIZE 21848 /* Per RFC 2222bis: ((16K / 3) + 1) * 4. */
+#define BASE64_BUF_SIZE 21848 /* Per RFC 4422: (E(n/3) + 1) * 4
+ where n = 16 kB = 16384 bytes. */
/*
@@ -189,9 +190,11 @@
while (r == SASL_CONTINUE || (r == SASL_OK && serveroutlen != 0)) {
if (serveroutlen != 0) {
- /* Encode the server challenge. */
+ /* Encode the server challenge.
+ * In sasl_encode64() calls, the fourth argument is the length
+ * of the third including the null terminator. */
r1 = sasl_encode64(serverout, serveroutlen,
- base64, BASE64_BUF_SIZE, NULL);
+ base64, BASE64_BUF_SIZE+1, NULL);
if (r1 != SASL_OK)
r = r1;
}
If I understand well, only sasl_encode64() calls need to have "+1".
sasl_decode64() are not affected by the change.
Is it fine?
--
Julien ÉLIE
« L'homme a imaginé le cercle avant de savoir que la terre était ronde.
Ça prouve quand même une certaine faculté d'invention. » (Jacques Sternberg)
More information about the inn-workers
mailing list