Index: lib/arc.c
===================================================================
--- lib/arc.c	(revision d07c3a8cde47096ad69db7139d410dfee29e509b)
+++ lib/arc.c	(revision ddcf491fa460fea612c240589c50da864dad6668)
@@ -131,15 +131,37 @@
    
    Both functions return the number of bytes in the result string.
+   
+   Note that if you use the pad_to argument, you will need zero-termi-
+   nation to find back the original string length after decryption. So
+   it shouldn't be used if your string contains \0s by itself!
 */
 
-int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password )
+int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to )
 {
 	struct arc_state *st;
 	unsigned char *key;
-	int key_len, i;
+	char *padded = NULL;
+	int key_len, i, padded_len;
 	
 	key_len = strlen( password ) + ARC_IV_LEN;
 	if( clear_len <= 0 )
 		clear_len = strlen( clear );
+	
+	/* Pad the string to the closest multiple of pad_to. This makes it
+	   impossible to see the exact length of the password. */
+	if( pad_to > 0 && ( clear_len % pad_to ) > 0 )
+	{
+		padded_len = clear_len + pad_to - ( clear_len % pad_to );
+		padded = g_malloc( padded_len );
+		memcpy( padded, clear, clear_len );
+		
+		/* First a \0 and then random data, so we don't have to do
+		   anything special when decrypting. */
+		padded[clear_len] = 0;
+		random_bytes( (unsigned char*) padded + clear_len + 1, padded_len - clear_len - 1 );
+		
+		clear = padded;
+		clear_len = padded_len;
+	}
 	
 	/* Prepare buffers and the key + IV */
@@ -161,4 +183,5 @@
 	
 	g_free( st );
+	g_free( padded );
 	
 	return clear_len + ARC_IV_LEN;
Index: lib/arc.h
===================================================================
--- lib/arc.h	(revision d07c3a8cde47096ad69db7139d410dfee29e509b)
+++ lib/arc.h	(revision ddcf491fa460fea612c240589c50da864dad6668)
@@ -31,6 +31,6 @@
 };
 
-struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );
+G_GNUC_MALLOC struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );
 unsigned char arc_getbyte( struct arc_state *st );
-int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password );
+int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to );
 int arc_decode( unsigned char *crypt, int crypt_len, char **clear, char *password );
Index: storage_xml.c
===================================================================
--- storage_xml.c	(revision d07c3a8cde47096ad69db7139d410dfee29e509b)
+++ storage_xml.c	(revision ddcf491fa460fea612c240589c50da864dad6668)
@@ -428,5 +428,5 @@
 		int pass_len;
 		
-		pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password );
+		pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 );
 		pass_b64 = base64_encode( pass_cr, pass_len );
 		g_free( pass_cr );
Index: tests/check_arc.c
===================================================================
--- tests/check_arc.c	(revision d07c3a8cde47096ad69db7139d410dfee29e509b)
+++ tests/check_arc.c	(revision ddcf491fa460fea612c240589c50da864dad6668)
@@ -7,5 +7,5 @@
 #include "arc.h"
 
-char *password = "TotT";
+char *password = "ArcVier";
 
 char *clear_tests[] =
@@ -14,4 +14,5 @@
 	"ItllBeBitlBee",
 	"One more boring password",
+	"Hoi hoi",
 	NULL
 };
@@ -28,5 +29,5 @@
 		int len;
 		
-		len = arc_encode( clear_tests[i], 0, &crypted, password );
+		len = arc_encode( clear_tests[i], 0, &crypted, password, 12 );
 		len = arc_decode( crypted, len, &decrypted, password );
 		
@@ -41,25 +42,33 @@
 struct
 {
-	unsigned char crypted[24];
+	unsigned char crypted[30];
 	int len;
 	char *decrypted;
 } decrypt_tests[] = {
+	/* One block with padding. */
 	{
 		{
-			0xc3, 0x0d, 0x43, 0xc3, 0xee, 0x80, 0xe2, 0x8c, 0x0b, 0x29, 0x32, 0x7e,
-			0x38, 0x05, 0x82, 0x10, 0x21, 0x1c, 0x4a, 0x00, 0x2c
-		}, 21, "Debugging sucks"
+			0x3f, 0x79, 0xb0, 0xf5, 0x91, 0x56, 0xd2, 0x1b, 0xd1, 0x4b, 0x67, 0xac,
+			0xb1, 0x31, 0xc9, 0xdb, 0xf9, 0xaa
+		}, 18, "short pass"
 	},
+	
+	/* Two blocks with padding. */
 	{
 		{
-			0xb0, 0x00, 0x57, 0x0d, 0x0d, 0x0d, 0x70, 0xe1, 0xc0, 0x00, 0xa4, 0x25,
-			0x7d, 0xbe, 0x03, 0xcc, 0x24, 0xd1, 0x0c
-		}, 19, "Testing rocks"
+			0xf9, 0xa6, 0xec, 0x5d, 0xc7, 0x06, 0xb8, 0x6b, 0x63, 0x9f, 0x2d, 0xb5,
+			0x7d, 0xaa, 0x32, 0xbb, 0xd8, 0x08, 0xfd, 0x81, 0x2e, 0xca, 0xb4, 0xd7,
+			0x2f, 0x36, 0x9c, 0xac, 0xa0, 0xbc
+		}, 30, "longer password"
 	},
+
+	/* This string is exactly two "blocks" long, to make sure unpadded strings also decrypt
+	   properly. */
 	{
 		{
-			0xb6, 0x92, 0x59, 0xe4, 0xf9, 0xc1, 0x7a, 0xf6, 0xf3, 0x18, 0xea, 0x28,
-			0x73, 0x6d, 0xb3, 0x0a, 0x6f, 0x0a, 0x2b, 0x43, 0x57, 0xe9, 0x3e, 0x63
-		}, 24, "OSCAR is creepy..."
+			0x95, 0x4d, 0xcf, 0x4d, 0x5e, 0x6c, 0xcf, 0xef, 0xb9, 0x80, 0x00, 0xef,
+			0x25, 0xe9, 0x17, 0xf6, 0x29, 0x6a, 0x82, 0x79, 0x1c, 0xca, 0x68, 0xb5,
+			0x4e, 0xd0, 0xc1, 0x41, 0x8e, 0xe6
+		}, 30, "OSCAR is really creepy.."
 	},
 	{ "", 0, NULL }
@@ -80,5 +89,5 @@
 		
 		fail_if( strcmp( decrypt_tests[i].decrypted, decrypted ) != 0,
-		         "%s didn't decrypt properly", clear_tests[i] );
+		         "`%s' didn't decrypt properly", decrypt_tests[i].decrypted );
 		
 		g_free( decrypted );
