aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2006-06-23 20:15:28 +0200
committerWilmer van der Gaast <wilmer@gaast.net>2006-06-23 20:15:28 +0200
commit812a41362a9316da1734fdaa8b1aad36bde9cb5c (patch)
treeac6aac55781de07e9e7e99ddfb2b8b74ab1debb2
parent00ab35016e3646aa936ae0c3d7a8531ec68d6f24 (diff)
Added saner base64 encoding function (actually, moved the one from libyahoo2.c
to core, with some changes), which I need for the XML format password garbling.
-rw-r--r--protocols/yahoo/libyahoo2.c28
-rw-r--r--util.c89
-rw-r--r--util.h1
3 files changed, 41 insertions, 77 deletions
diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c
index c691f18b..ee0f2f0e 100644
--- a/protocols/yahoo/libyahoo2.c
+++ b/protocols/yahoo/libyahoo2.c
@@ -694,34 +694,10 @@ static void yahoo_packet_dump(unsigned char *data, int len)
}
}
-static char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789._";
-static void to_y64(unsigned char *out, const unsigned char *in, int inlen)
/* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
+static void to_y64(unsigned char *out, const unsigned char *in, int inlen)
{
- for (; inlen >= 3; inlen -= 3)
- {
- *out++ = base64digits[in[0] >> 2];
- *out++ = base64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
- *out++ = base64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)];
- *out++ = base64digits[in[2] & 0x3f];
- in += 3;
- }
- if (inlen > 0)
- {
- unsigned char fragment;
-
- *out++ = base64digits[in[0] >> 2];
- fragment = (in[0] << 4) & 0x30;
- if (inlen > 1)
- fragment |= in[1] >> 4;
- *out++ = base64digits[fragment];
- *out++ = (inlen < 2) ? '-'
- : base64digits[(in[1] << 2) & 0x3c];
- *out++ = '-';
- }
- *out = '\0';
+ return base64_encode_real(in, inlen, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-");
}
static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, int length)
diff --git a/util.c b/util.c
index dfa0906b..d8d6a4c7 100644
--- a/util.c
+++ b/util.c
@@ -83,61 +83,48 @@ char *add_cr(char *text)
return ret;
}
-static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/";
-
-/* XXX Find bug */
char *tobase64(const char *text)
{
- char *out = NULL;
- const char *c;
- unsigned int tmp = 0;
- int len = 0, n = 0;
-
- c = text;
-
- while (*c) {
- tmp = tmp << 8;
- tmp += *c;
- n++;
-
- if (n == 3) {
- out = g_realloc(out, len + 4);
- out[len] = alphabet[(tmp >> 18) & 0x3f];
- out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
- out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
- out[len + 3] = alphabet[tmp & 0x3f];
- len += 4;
- tmp = 0;
- n = 0;
- }
- c++;
+ char *out;
+ int len;
+
+ len = strlen(text);
+ out = g_malloc((len + 2) /* the == padding */
+ / 3 /* every 3-byte block */
+ * 4 /* becomes a 4-byte one */
+ + 1); /* and of course, ASCIIZ! */
+
+ base64_encode_real(text, len, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");
+
+ return out;
+}
+
+void base64_encode_real(const unsigned char *in, int inlen, unsigned char *out, char *b64digits)
+{
+ for (; inlen >= 3; inlen -= 3)
+ {
+ *out++ = b64digits[in[0] >> 2];
+ *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
+ *out++ = b64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)];
+ *out++ = b64digits[in[2] & 0x3f];
+ in += 3;
}
- switch (n) {
-
- case 2:
- tmp <<= 8;
- out = g_realloc(out, len + 5);
- out[len] = alphabet[(tmp >> 18) & 0x3f];
- out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
- out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
- out[len + 3] = '=';
- out[len + 4] = 0;
- break;
- case 1:
- tmp <<= 16;
- out = g_realloc(out, len + 5);
- out[len] = alphabet[(tmp >> 18) & 0x3f];
- out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
- out[len + 2] = '=';
- out[len + 3] = '=';
- out[len + 4] = 0;
- break;
- case 0:
- out = g_realloc(out, len + 1);
- out[len] = 0;
- break;
+ if (inlen > 0)
+ {
+ *out++ = b64digits[in[0] >> 2];
+ if (inlen > 1)
+ {
+ *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
+ *out++ = b64digits[((in[1]<<2) & 0x3c)];
+ }
+ else
+ {
+ *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
+ *out++ = b64digits[64];
+ }
+ *out++ = b64digits[64];
}
- return out;
+ *out = '\0';
}
char *normalize(const char *s)
diff --git a/util.h b/util.h
index 8e13d9dd..c7eec19b 100644
--- a/util.h
+++ b/util.h
@@ -30,6 +30,7 @@ G_MODULE_EXPORT void strip_linefeed( gchar *text );
G_MODULE_EXPORT char *add_cr( char *text );
G_MODULE_EXPORT char *strip_newlines(char *source);
G_MODULE_EXPORT char *tobase64( const char *text );
+G_MODULE_EXPORT void base64_encode_real( const unsigned char *in, int inlen, unsigned char *out, char *b64digits );
G_MODULE_EXPORT char *normalize( const char *s );
G_MODULE_EXPORT void info_string_append( GString *str, char *newline, char *name, char *value );