Hi all, attached is a patch which tries to eliminate some duplicated code from libimap: - replace the custom implementation for base64 encoding and decoding by the respective glib functions - use libnetclient to calculate the CRAM-MD5 authentication message.
I verified the changed implementation against a local dovecot instance, for both "cram-md5" and "plain" authentication. Opinions? Cheers, Albrecht. --- Patch details: - Makefile.am: ensure libnetclient is built before libbalsa, so the imap test code can link properly - libbalsa/imap/Makefile.am: add libnetclient to include path, link test app against it - imap/auth-cram.c: use net_client_cram_calc(), and wipe sensitive data before free - libbalsa/imap/imap-auth.c: g_base64_encode() instead of custom function - libbalsa/imap/util.[hc]: remove custom base64 encode and decode stuff
diff --git a/Makefile.am b/Makefile.am
index 7a412a3..09285f9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
#intl dir needed for tarball --disable-nls build.
DISTCHECK_CONFIGURE_FLAGS="--disable-extra-mimeicons"
-SUBDIRS = po sounds images doc libbalsa libnetclient libinit_balsa src ui
+SUBDIRS = po sounds images doc libnetclient libbalsa libinit_balsa src ui
# set tar in case it is not set by automake or make
man_MANS=balsa.1
diff --git a/libbalsa/imap/Makefile.am b/libbalsa/imap/Makefile.am
index 875aaf1..ea9d16a 100644
--- a/libbalsa/imap/Makefile.am
+++ b/libbalsa/imap/Makefile.am
@@ -11,6 +11,7 @@ imap_tst_SOURCES = imap_tst.c
imap_tst_LDADD = \
libimap.a \
+ ${top_srcdir}/libnetclient/libnetclient.a \
$(BALSA_LIBS)
#libimap_la_SOURCES =
@@ -41,6 +42,7 @@ EXTRA_DIST = \
libimap-marshal.list
AM_CPPFLAGS = -I${top_builddir} -I${top_srcdir} -I${top_srcdir}/libbalsa \
+ -I${top_srcdir}/libnetclient \
-I${top_srcdir}/libbalsa/imap \
$(BALSA_CFLAGS)
diff --git a/libbalsa/imap/auth-cram.c b/libbalsa/imap/auth-cram.c
index 6d95fbc..c56e11a 100644
--- a/libbalsa/imap/auth-cram.c
+++ b/libbalsa/imap/auth-cram.c
@@ -27,7 +27,7 @@
#include <glib.h>
#include "imap-auth.h"
-#include "util.h"
+#include "net-client-utils.h"
#include "imap_private.h"
@@ -37,11 +37,11 @@
ImapResult
imap_auth_cram(ImapMboxHandle* handle)
{
- char ibuf[LONG_STRING*2], obuf[LONG_STRING];
+ char ibuf[LONG_STRING*2];
+ gchar *auth_buf;
unsigned cmdno;
- int len, rc, ok;
+ int rc, ok;
char *user = NULL, *pass = NULL;
- gchar *digest;
if (!imap_mbox_handle_can_do(handle, IMCAP_ACRAM_MD5))
return IMAP_AUTH_UNAVAIL;
@@ -75,37 +75,16 @@ imap_auth_cram(ImapMboxHandle* handle)
return IMAP_AUTH_FAILURE;
}
imap_mbox_gets(handle, ibuf, sizeof(ibuf)); /* check error */
- if ((len = lit_conv_from_base64(obuf, ibuf)) <0) {
- g_warning("Error decoding base64 response(%s), digit=%d:%d[%c]).\n",
- ibuf, len, ibuf[-len-1],ibuf[-len-1]);
- return IMAP_AUTH_FAILURE;
- }
-
- obuf[len] = '\0';
+ auth_buf = net_client_cram_calc(ibuf, G_CHECKSUM_MD5, user, pass);
+ g_free(user);
+ memset(pass, 0, strlen(pass));
+ g_free(pass);
- /* The client makes note of the data and then responds with a string
- * consisting of the user name, a space, and a 'digest'. The latter is
- * computed by applying the keyed MD5 algorithm from [KEYED-MD5] where the
- * key is a shared secret and the digested text is the timestamp (including
- * angle-brackets).
- *
- * Note: The user name shouldn't be quoted. Since the digest can't contain
- * spaces, there is no ambiguity. Some servers get this wrong, we'll work
- * around them when the bug report comes in. Until then, we'll remain
- * blissfully RFC-compliant.
- */
- digest = g_compute_hmac_for_string(G_CHECKSUM_MD5, (const guchar *) pass, strlen(pass), obuf, -1);
- g_snprintf (obuf, sizeof (obuf), "%s %s", user, digest);
- g_free(digest);
- /* XXX - ibuf must be long enough to store the base64 encoding of obuf,
- * plus the additional debris
- */
-
- lit_conv_to_base64(ibuf, obuf, strlen (obuf), sizeof(ibuf)-2);
- strncat (ibuf, "\r\n", sizeof (ibuf) - strlen(ibuf) - 1);
- imap_handle_write(handle, ibuf, strlen(ibuf));
+ imap_handle_write(handle, auth_buf, strlen(auth_buf));
+ imap_handle_write(handle, "\r\n", 2U);
imap_handle_flush(handle);
- g_free(user); g_free(pass); /* FIXME: clean passwd first */
+ memset(auth_buf, 0, strlen(auth_buf));
+ g_free(auth_buf);
do
rc = imap_cmd_step (handle, cmdno);
while (rc == IMR_UNTAGGED);
diff --git a/libbalsa/imap/imap-auth.c b/libbalsa/imap/imap-auth.c
index 35de1ff..adaa7d4 100644
--- a/libbalsa/imap/imap-auth.c
+++ b/libbalsa/imap/imap-auth.c
@@ -114,7 +114,7 @@ imap_auth_sasl(ImapMboxHandle* handle, ImapCapability cap,
{
char *msg = NULL, *msg64;
ImapResponse rc;
- int msglen, msg64len;
+ int msglen;
unsigned cmdno;
gboolean sasl_ir;
@@ -127,9 +127,7 @@ imap_auth_sasl(ImapMboxHandle* handle, ImapCapability cap,
return IMAP_AUTH_CANCELLED;
}
- msg64len = 2*(msglen+2);
- msg64 = g_malloc(msg64len);
- lit_conv_to_base64(msg64, msg, msglen, msg64len);
+ msg64 = g_base64_encode((const guchar *) msg, msglen);
g_free(msg);
if(sasl_ir) { /* save one RTT */
diff --git a/libbalsa/imap/util.c b/libbalsa/imap/util.c
index a24748b..c9bd089 100644
--- a/libbalsa/imap/util.c
+++ b/libbalsa/imap/util.c
@@ -133,112 +133,6 @@ imap_next_word(char *s)
return s;
}
-#define BAD -1
-#define base64val(c) Index_64[(unsigned int)(c)]
-static char B64Chars[64] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
- 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '+', '/'
-};
-
-static int Index_64[128] = {
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
- 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
- -1, 0, 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,-1, -1,-1,-1,-1,
- -1,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,-1, -1,-1,-1,-1
-};
-
-/* raw bytes to null-terminated base 64 string */
-void
-lit_conv_to_base64(char *out, const char *in, size_t len, size_t olen)
-{
- unsigned char in0, in1, in2;
-
- while (len >= 3 && olen > 10)
- {
- in0 = in[0];
- *out++ = B64Chars[in0 >> 2];
- in1 = in[1];
- *out++ = B64Chars[((in0 << 4) & 0x30) | (in1 >> 4)];
- in2 = in[2];
- *out++ = B64Chars[((in1 << 2) & 0x3c) | (in2 >> 6)];
- *out++ = B64Chars[in2 & 0x3f];
- olen -= 4;
- len -= 3;
- in += 3;
- }
-
- /* clean up remainder */
- if (len > 0 && olen > 4)
- {
- unsigned char fragment;
-
- in0 = in[0];
- *out++ = B64Chars[in0 >> 2];
- fragment = (in0 << 4) & 0x30;
- if (len > 1) {
- in1 = in[1];
- fragment |= in1 >> 4;
- *out++ = B64Chars[fragment];
- *out++ = B64Chars[(in1 << 2) & 0x3c];
- } else {
- *out++ = B64Chars[fragment];
- *out++ = '=';
- }
- *out++ = '=';
- }
- *out = '\0';
-}
-
-
-/* Convert '\0'-terminated base 64 string to raw bytes.
- * Returns length of returned buffer, or -1 on error */
-int
-lit_conv_from_base64(char *out, const char *in)
-{
- int len = 0, idx=0;
- register unsigned char digit1, digit2, digit3, digit4;
-
- do {
- digit1 = in[idx];
- if (digit1 > 127 || base64val (digit1) == BAD)
- return -1-idx;
- digit2 = in[idx+1];
- if (digit2 > 127 || base64val (digit2) == BAD)
- return -2-idx;
- digit3 = in[idx+2];
- if (digit3 > 127 || ((digit3 != '=') && (base64val (digit3) == BAD)))
- return -3-idx;
- digit4 = in[idx+3];
- if (digit4 > 127 || ((digit4 != '=') && (base64val (digit4) == BAD)))
- return -4-idx;
- idx += 4;
-
- /* digits are already sanity-checked */
- *out++ = (base64val(digit1) << 2) | (base64val(digit2) >> 4);
- len++;
- if (digit3 != '=')
- {
- *out++ = ((base64val(digit2) << 4) & 0xf0) | (base64val(digit3) >> 2);
- len++;
- if (digit4 != '=')
- {
- *out++ = ((base64val(digit3) << 6) & 0xc0) | base64val(digit4);
- len++;
- }
- }
- }
- while (in[idx] && in[idx] != 13 && digit4 != '=');
-
- return len;
-}
-
/* ===================================================================
* UTF-7 conversion routines as in RFC 2192
diff --git a/libbalsa/imap/util.h b/libbalsa/imap/util.h
index c748b13..583399d 100644
--- a/libbalsa/imap/util.h
+++ b/libbalsa/imap/util.h
@@ -22,10 +22,6 @@ void imap_unquote_string(char *s);
char* imap_next_word(char *s);
char* imap_skip_atom(char *s);
-void lit_conv_to_base64(char *out, const char *in,
- size_t len, size_t olen);
-int lit_conv_from_base64(char *out, const char *in);
-
char* imap_mailbox_to_utf8(const char *src);
char* imap_utf8_to_mailbox(const char *src);
pgpVPq6GxjMlf.pgp
Description: PGP signature
_______________________________________________ balsa-list mailing list [email protected] https://mail.gnome.org/mailman/listinfo/balsa-list
