changeset 6986:6290e7aeabfe

[gaim-migrate @ 7542] So. Yahoo works again. That's cool. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Sun, 28 Sep 2003 01:05:28 +0000
parents 0e5a5e5e07f0
children 0f6673c1ae38
files src/protocols/yahoo/yahoo.c src/sha.c src/sha.h
diffstat 3 files changed, 527 insertions(+), 341 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/yahoo/yahoo.c	Sat Sep 27 23:42:22 2003 +0000
+++ b/src/protocols/yahoo/yahoo.c	Sun Sep 28 01:05:28 2003 +0000
@@ -35,6 +35,7 @@
 #include "util.h"
 #include "html.h"
 
+#include "sha.h"
 #include "yahoo.h"
 #include "yahoochat.h"
 #include "md5.h"
@@ -849,132 +850,551 @@
 	*out = '\0';
 }
 
+static void yahoo_process_auth_old(GaimConnection *gc, const char *seed)
+{
+	struct yahoo_packet *pack;
+	GaimAccount *account = gaim_connection_get_account(gc);
+	const char *name = normalize(gaim_account_get_username(account));
+	const char *pass = gaim_account_get_password(account);
+	struct yahoo_data *yd = gc->proto_data;
+
+	/* So, Yahoo has stopped supporting its older clients in India, and undoubtedly
+	 * will soon do so in the rest of the world.
+	 *
+	 * The new clients use this authentication method.  I warn you in advance, it's
+	 * bizzare, convoluted, inordinately complicated.  It's also no more secure than
+	 * crypt() was.  The only purpose this scheme could serve is to prevent third
+	 * part clients from connecting to their servers.
+	 *
+	 * Sorry, Yahoo.
+	 */
+		
+	md5_byte_t result[16];
+	md5_state_t ctx;
+		
+	char *crypt_result;
+	char password_hash[25];
+	char crypt_hash[25];
+	char *hash_string_p = g_malloc(50 + strlen(name));
+	char *hash_string_c = g_malloc(50 + strlen(name));
+		
+	char checksum;
+	
+	int sv;
+	
+	char result6[25];
+	char result96[25];
+
+	sv = seed[15];
+	sv = sv % 8;
+
+	md5_init(&ctx);
+	md5_append(&ctx, pass, strlen(pass));
+	md5_finish(&ctx, result);
+	to_y64(password_hash, result, 16);
+		
+	md5_init(&ctx);
+	crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$");  
+	md5_append(&ctx, crypt_result, strlen(crypt_result));
+	md5_finish(&ctx, result);
+	to_y64(crypt_hash, result, 16);
+
+	switch (sv) {
+	case 1:
+	case 6:
+		checksum = seed[seed[9] % 16];
+		g_snprintf(hash_string_p, strlen(name) + 50,
+			   "%c%s%s%s", checksum, name, seed, password_hash);
+		g_snprintf(hash_string_c, strlen(name) + 50,
+			   "%c%s%s%s", checksum, name, seed, crypt_hash);
+		break;
+	case 2:
+	case 7:
+		checksum = seed[seed[15] % 16];
+		g_snprintf(hash_string_p, strlen(name) + 50,
+			   "%c%s%s%s", checksum, seed, password_hash, name);
+		g_snprintf(hash_string_c, strlen(name) + 50,
+			   "%c%s%s%s", checksum, seed, crypt_hash, name);
+		break;
+	case 3:
+		checksum = seed[seed[1] % 16];
+		g_snprintf(hash_string_p, strlen(name) + 50,
+			   "%c%s%s%s", checksum, name, password_hash, seed);
+		g_snprintf(hash_string_c, strlen(name) + 50,
+			   "%c%s%s%s", checksum, name, crypt_hash, seed);
+		break;
+	case 4:
+		checksum = seed[seed[3] % 16];
+		g_snprintf(hash_string_p, strlen(name) + 50,
+			   "%c%s%s%s", checksum, password_hash, seed, name);
+		g_snprintf(hash_string_c, strlen(name) + 50,
+			   "%c%s%s%s", checksum, crypt_hash, seed, name);
+		break;
+	case 0:
+	case 5:
+		checksum = seed[seed[7] % 16];
+			g_snprintf(hash_string_p, strlen(name) + 50,
+                                   "%c%s%s%s", checksum, password_hash, name, seed);
+                        g_snprintf(hash_string_c, strlen(name) + 50,
+				   "%c%s%s%s", checksum, crypt_hash, name, seed);
+			break;
+	}
+		
+	md5_init(&ctx);  
+	md5_append(&ctx, hash_string_p, strlen(hash_string_p));
+	md5_finish(&ctx, result);
+	to_y64(result6, result, 16);
+	
+	md5_init(&ctx);  
+	md5_append(&ctx, hash_string_c, strlen(hash_string_c));
+	md5_finish(&ctx, result);
+	to_y64(result96, result, 16);
+
+	pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP,	YAHOO_STATUS_AVAILABLE, 0);
+	yahoo_packet_hash(pack, 0, name);
+	yahoo_packet_hash(pack, 6, result6);
+	yahoo_packet_hash(pack, 96, result96);
+	yahoo_packet_hash(pack, 1, name);
+		
+	yahoo_send_packet(yd, pack);
+	
+	g_free(hash_string_p);
+	g_free(hash_string_c);
+	
+	yahoo_packet_free(pack);
+	
+}
+
+static void yahoo_process_auth_new(GaimConnection *gc, const char *seed)
+{
+	struct yahoo_packet *pack = NULL;
+	GaimAccount *account = gaim_connection_get_account(gc);
+	const char *name = normalize(gaim_account_get_username(account));
+	const char *pass = gaim_account_get_password(account);
+	struct yahoo_data *yd = gc->proto_data;
+
+	md5_byte_t         result[16];
+	md5_state_t        ctx;
+	
+	SHA_CTX            ctx1;
+	SHA_CTX            ctx2;
+
+	char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ";
+	char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop";
+	
+	char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5";
+	char *operand_lookup = "+|&%/*^-";
+	char *delimit_lookup = ",;";
+	
+	char *password_hash = g_malloc0(25);
+	char *crypt_hash = g_malloc0(25);
+	char *crypt_result = NULL;
+	char pass_hash_xor1[64];
+	char pass_hash_xor2[64];
+	char crypt_hash_xor1[64];
+	char crypt_hash_xor2[64];
+	char resp_6[100];
+	char resp_96[100];
+
+	unsigned char digest1[20];
+	unsigned char digest2[20];
+	unsigned char magic_key_char[4];
+	unsigned char *magic_ptr;
+
+	unsigned int  magic[64];
+	unsigned int  magic_work;
+	unsigned int  value = 0;
+	
+	int x;
+	int cnt = 0;
+	int magic_cnt = 0;
+	int magic_len;
+	int times = 0;
+	
+	memset(&pass_hash_xor1, 0, 64);
+	memset(&pass_hash_xor2, 0, 64);
+	memset(&crypt_hash_xor1, 0, 64);
+	memset(&crypt_hash_xor2, 0, 64);
+	memset(&digest1, 0, 20);
+	memset(&digest2, 0, 20);
+	memset(&magic, 0, 64);
+	memset(&resp_6, 0, 100);
+	memset(&resp_96, 0, 100);
+	memset(&magic_key_char, 0, 4);
+
+	/* 
+	 * Magic: Phase 1.  Generate what seems to be a 30 
+	 * byte value (could change if base64
+	 * ends up differently?  I don't remember and I'm 
+	 * tired, so use a 64 byte buffer.
+	 */
+
+	magic_ptr = seed;
+	
+	while (*magic_ptr != (int)NULL) {
+		char *loc;
+		
+		/* Ignore parentheses.  */
+		
+		if (*magic_ptr == '(' || *magic_ptr == ')') {
+			magic_ptr++;
+			continue;
+		}
+		
+		/* Characters and digits verify against 
+		   the challenge lookup.
+		*/
+		
+		if (isalpha(*magic_ptr) || isdigit(*magic_ptr)) {
+			loc = strchr(challenge_lookup, *magic_ptr);
+			if (!loc) {
+				/* This isn't good */
+			}
+			
+			/* Get offset into lookup table and lsh 3. */
+			
+			magic_work = loc - challenge_lookup;
+			magic_work <<= 3;
+			
+			magic_ptr++;
+			continue;
+		} else {
+			unsigned int local_store;
+			
+			loc = strchr(operand_lookup, *magic_ptr);
+			if (!loc) {
+				/* Also not good. */
+			}
+			
+			local_store = loc - operand_lookup;
+					
+			/* Oops; how did this happen? */
+			if (magic_cnt >= 64) 
+				break;
+					
+			magic[magic_cnt++] = magic_work | local_store;
+			magic_ptr++;
+			continue;
+		}
+	}
+	
+	magic_len = magic_cnt;
+	magic_cnt = 0;
+	
+	/* Magic: Phase 2.  Take generated magic value and 
+	 * sprinkle fairy dust on the values. */
+	
+	for (magic_cnt = magic_len-2; magic_cnt >= 0; magic_cnt--) {
+		unsigned char byte1;
+		unsigned char byte2;
+		
+		/* Bad.  Abort.
+		 */
+		if ((magic_cnt + 1 > magic_len) || 
+		    (magic_cnt > magic_len))
+			break;
+		
+		byte1 = magic[magic_cnt];
+		byte2 = magic[magic_cnt+1];
+
+		byte1 *= 0xcd;
+		byte1 ^= byte2;
+		
+		magic[magic_cnt+1] = byte1;
+	}
+	
+	/* Magic: Phase 3.  Final phase; this gives us our 
+	 * key. */
+	
+	magic_cnt = 1;
+	
+	for (;;) {
+		unsigned int cl = magic[magic_cnt] & 0xff;
+		unsigned int bl = magic[magic_cnt+1] & 0xff;
+		
+		if (!bl || !cl)
+			break;
+		
+		if (magic_cnt > magic_len)
+			break;
+		
+		if (cl <= 0x7f)
+			bl = cl;
+		else {
+			if (cl >= 0x0e0) {
+				cl = cl & 0x0f;
+				cl = cl << 6;
+				bl = bl & 0x3f;
+				bl = cl + bl;
+				bl = bl << 6;
+			} else {
+				cl = cl & 0x1f;
+				cl = cl << 6;
+				bl = cl;
+			}
+			
+			cl = magic[magic_cnt+2];
+			
+			if (!cl)
+				break;
+			
+			cl = cl & 0x3f;
+			bl = bl + cl;
+		}
+		
+		/* Result is bl.
+		 */
+		
+		magic_cnt += 3;
+
+ 		if (times == 0) {
+			value |= (bl & 0xff) << 8; 
+			value |= (bl & 0xff00) >> 8;           
+		} else { 
+			value |= (bl & 0xff) << 24; 
+			value |= (bl & 0xff00) << 8;           
+			break; 
+		} 
+		
+		times++;
+	}
+	
+	/* Dump magic key into a char for SHA1 action. */
+	 	
+	memcpy(&magic_key_char[0], &value, sizeof(int));
+
+	/* Get password and crypt hashes as per usual. */
+	md5_init(&ctx);
+	md5_append(&ctx, pass,  strlen(pass));
+	md5_finish(&ctx, result);
+	to_y64(password_hash, result, 16);
+	
+	md5_init(&ctx);
+	crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$");  
+	md5_append(&ctx, crypt_result, strlen(crypt_result));
+	md5_finish(&ctx, result);
+	to_y64(crypt_hash, result, 16);
+	
+	/* Our first authentication response is based off 
+	 * of the password hash. */
+	
+	for (x = 0; x < (int)strlen(password_hash); x++) 
+		pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36;
+	
+	if (cnt < 64) 
+		memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt);
+	
+	cnt = 0;
+	
+	for (x = 0; x < (int)strlen(password_hash); x++) 
+		pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c;
+	
+	if (cnt < 64) 
+		memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt);
+	
+	shaInit(&ctx1);
+	shaInit(&ctx2);
+	
+	/* The first context gets the password hash XORed 
+	 * with 0x36 plus a magic value
+	 * which we previously extrapolated from our 
+	 * challenge. */
+	
+	shaUpdate(&ctx1, pass_hash_xor1, 64);
+	shaUpdate(&ctx1, magic_key_char, 4);
+	shaFinal(&ctx1, digest1);
+	
+	 /* The second context gets the password hash XORed 
+	  * with 0x5c plus the SHA-1 digest
+	  * of the first context. */
+	
+	shaUpdate(&ctx2, pass_hash_xor2, 64);
+	shaUpdate(&ctx2, digest1, 20);
+	shaFinal(&ctx2, digest2);
+	
+	/* Now that we have digest2, use it to fetch 
+	 * characters from an alphabet to construct
+	 * our first authentication response. */
+	
+	for (x = 0; x < 20; x += 2) {
+		unsigned int    val = 0;
+		unsigned int    lookup = 0;
+		char            byte[6];
+		
+		memset(&byte, 0, 6);
+		
+		/* First two bytes of digest stuffed 
+		 *  together.
+		 */
+		
+		val = digest2[x];
+		val <<= 8;
+		val += digest2[x+1];
+		
+		lookup = (val >> 0x0b);
+		lookup &= 0x1f;
+		if (lookup >= strlen(alphabet1))
+			break;
+		sprintf(byte, "%c", alphabet1[lookup]);
+		strcat(resp_6, byte);
+		strcat(resp_6, "=");
+		
+		lookup = (val >> 0x06);
+		lookup &= 0x1f;
+		if (lookup >= strlen(alphabet2))
+			break;
+		sprintf(byte, "%c", alphabet2[lookup]);
+		strcat(resp_6, byte);
+		
+		lookup = (val >> 0x01);
+		lookup &= 0x1f;
+		if (lookup >= strlen(alphabet2))
+			break;
+		sprintf(byte, "%c", alphabet2[lookup]);
+		strcat(resp_6, byte);
+		
+		lookup = (val & 0x01);
+		if (lookup >= strlen(delimit_lookup))
+			break;
+		sprintf(byte, "%c", delimit_lookup[lookup]);
+		strcat(resp_6, byte);
+	}
+	
+	/* Our second authentication response is based off 
+	 * of the crypto hash. */
+	
+	cnt = 0;
+	memset(&digest1, 0, 20);
+	memset(&digest2, 0, 20);
+	
+	for (x = 0; x < (int)strlen(crypt_hash); x++) 
+		crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36;
+	
+	if (cnt < 64) 
+		memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt);
+	
+	cnt = 0;
+	
+	for (x = 0; x < (int)strlen(crypt_hash); x++) 
+		crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c;
+	
+	if (cnt < 64) 
+		memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt);
+	
+	shaInit(&ctx1);
+	shaInit(&ctx2);
+	
+	/* The first context gets the password hash XORed 
+	 * with 0x36 plus a magic value
+	 * which we previously extrapolated from our 
+	 * challenge. */
+	
+	shaUpdate(&ctx1, crypt_hash_xor1, 64);
+	shaUpdate(&ctx1, magic_key_char, 4);
+	shaFinal(&ctx1, digest1);
+	
+	/* The second context gets the password hash XORed 
+	 * with 0x5c plus the SHA-1 digest
+	 * of the first context. */
+	
+	shaUpdate(&ctx2, crypt_hash_xor2, 64);
+	shaUpdate(&ctx2, digest1, 20);
+	shaFinal(&ctx2, digest2);
+	
+	/* Now that we have digest2, use it to fetch 
+	 * characters from an alphabet to construct
+	 * our first authentication response.  */
+	
+	for (x = 0; x < 20; x += 2) {
+		unsigned int val = 0;
+		unsigned int lookup = 0;
+		
+		char byte[6];
+		
+		memset(&byte, 0, 6);
+		
+		/* First two bytes of digest stuffed 
+		 *  together. */
+		
+		val = digest2[x];
+		val <<= 8;
+		val += digest2[x+1];
+		
+		lookup = (val >> 0x0b);
+		lookup &= 0x1f;
+		if (lookup >= strlen(alphabet1))
+			break;
+		sprintf(byte, "%c", alphabet1[lookup]);
+		strcat(resp_96, byte);
+		strcat(resp_96, "=");
+		
+		lookup = (val >> 0x06);
+		lookup &= 0x1f;
+		if (lookup >= strlen(alphabet2))
+			break;
+		sprintf(byte, "%c", alphabet2[lookup]);
+		strcat(resp_96, byte);
+		
+		lookup = (val >> 0x01);
+		lookup &= 0x1f;
+		if (lookup >= strlen(alphabet2))
+			break;
+		sprintf(byte, "%c", alphabet2[lookup]);
+		strcat(resp_96, byte);
+		
+		lookup = (val & 0x01);
+		if (lookup >= strlen(delimit_lookup))
+			break;
+		sprintf(byte, "%c", delimit_lookup[lookup]);
+		strcat(resp_96, byte);
+	}
+	
+	pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP,	YAHOO_STATUS_AVAILABLE, 0);
+	yahoo_packet_hash(pack, 0, name);
+	yahoo_packet_hash(pack, 6, resp_6);
+	yahoo_packet_hash(pack, 96, resp_96);
+	yahoo_packet_hash(pack, 1, name);
+	yahoo_send_packet(yd, pack);
+	yahoo_packet_free(pack);
+
+	free(password_hash);
+	free(crypt_hash);
+}
+
 static void yahoo_process_auth(GaimConnection *gc, struct yahoo_packet *pkt)
 {
 	char *seed = NULL;
 	char *sn   = NULL;
 	GSList *l = pkt->hash;
-	struct yahoo_data *yd = gc->proto_data;
-	GaimAccount *account = gaim_connection_get_account(gc);
+	int m = 1;
 
+	
 	while (l) {
 		struct yahoo_pair *pair = l->data;
 		if (pair->key == 94)
 			seed = pair->value;
 		if (pair->key == 1)
 			sn = pair->value;
+		if (pair->key == 13)
+			m = atoi(pair->value);
 		l = l->next;
 	}
 	
 	if (seed) {
-		struct yahoo_packet *pack;
-		const char *name = normalize(gaim_account_get_username(account));
-		const char *pass = gaim_account_get_password(account);
-
-		/* So, Yahoo has stopped supporting its older clients in India, and undoubtedly
-		 * will soon do so in the rest of the world.
-		 *
-		 * The new clients use this authentication method.  I warn you in advance, it's
-		 * bizzare, convoluted, inordinately complicated.  It's also no more secure than
-		 * crypt() was.  The only purpose this scheme could serve is to prevent third
-		 * part clients from connecting to their servers.
-		 *
-		 * Sorry, Yahoo.
-		 */
-		
-		md5_byte_t result[16];
-		md5_state_t ctx;
-		
-		char *crypt_result;
-		char password_hash[25];
-		char crypt_hash[25];
-		char *hash_string_p = g_malloc(50 + strlen(sn));
-		char *hash_string_c = g_malloc(50 + strlen(sn));
-		
-		char checksum;
-		
-		int sv;
-		
-		char result6[25];
-		char result96[25];
-
-		sv = seed[15];
-		sv = sv % 8;
-
-		md5_init(&ctx);
-		md5_append(&ctx, pass, strlen(pass));
-		md5_finish(&ctx, result);
-		to_y64(password_hash, result, 16);
-		
-		md5_init(&ctx);
-		crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$");  
-		md5_append(&ctx, crypt_result, strlen(crypt_result));
-		md5_finish(&ctx, result);
-		to_y64(crypt_hash, result, 16);
-
-		switch (sv) {
+		switch (m) {
+		case 0:
+			yahoo_process_auth_old(gc, seed);
+			break;
 		case 1:
-		case 6:
-			checksum = seed[seed[9] % 16];
-			g_snprintf(hash_string_p, strlen(sn) + 50,
-                                   "%c%s%s%s", checksum, name, seed, password_hash);
-                        g_snprintf(hash_string_c, strlen(sn) + 50,
-				   "%c%s%s%s", checksum, name, seed, crypt_hash);
+			yahoo_process_auth_new(gc, seed);
 			break;
-		case 2:
-		case 7:
-			checksum = seed[seed[15] % 16];
-			g_snprintf(hash_string_p, strlen(sn) + 50,
-                                   "%c%s%s%s", checksum, seed, password_hash, name);
-                        g_snprintf(hash_string_c, strlen(sn) + 50,
-                                   "%c%s%s%s", checksum, seed, crypt_hash, name);
-			break;
-		case 3:
-			checksum = seed[seed[1] % 16];
-			g_snprintf(hash_string_p, strlen(sn) + 50,
-                                   "%c%s%s%s", checksum, name, password_hash, seed);
-                        g_snprintf(hash_string_c, strlen(sn) + 50,
-                                   "%c%s%s%s", checksum, name, crypt_hash, seed);
-			break;
-		case 4:
-			checksum = seed[seed[3] % 16];
-			g_snprintf(hash_string_p, strlen(sn) + 50,
-				   "%c%s%s%s", checksum, password_hash, seed, name);
-			g_snprintf(hash_string_c, strlen(sn) + 50,
-				   "%c%s%s%s", checksum, crypt_hash, seed, name);
-			break;
-		case 0:
-		case 5:
-			checksum = seed[seed[7] % 16];
-			g_snprintf(hash_string_p, strlen(sn) + 50,
-                                   "%c%s%s%s", checksum, password_hash, name, seed);
-                        g_snprintf(hash_string_c, strlen(sn) + 50,
-				   "%c%s%s%s", checksum, crypt_hash, name, seed);
-			break;
+		default:
+			gaim_notify_error(gc, "", _("Failed Yahoo! Authentication"),
+					  _("The Yahoo server has requested the use of an unrecognized "
+					    "authentication method.  This version of Gaim will likely not be able"
+					    "to successfully sign on to Yahoo.  Check " GAIM_WEBSITE " for updates."));
+			yahoo_process_auth_new(gc, seed); /* Can't hurt to try it anyway. */
 		}
-		
-		md5_init(&ctx);  
-		md5_append(&ctx, hash_string_p, strlen(hash_string_p));
-		md5_finish(&ctx, result);
-		to_y64(result6, result, 16);
-
-		md5_init(&ctx);  
-		md5_append(&ctx, hash_string_c, strlen(hash_string_c));
-		md5_finish(&ctx, result);
-		to_y64(result96, result, 16);
-
-		pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP,	YAHOO_STATUS_AVAILABLE, 0);
-		yahoo_packet_hash(pack, 0, name);
-		yahoo_packet_hash(pack, 6, result6);
-		yahoo_packet_hash(pack, 96, result96);
-		yahoo_packet_hash(pack, 1, name);
-		
-		yahoo_send_packet(yd, pack);
-		
-		g_free(hash_string_p);
-		g_free(hash_string_c);
-
-		yahoo_packet_free(pack);
 	}
 }
 
--- a/src/sha.c	Sat Sep 27 23:42:22 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-/* 
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- * 
- * The Original Code is SHA 180-1 Reference Implementation (Compact version)
- * 
- * The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research.  Portions created by Paul Kocher are 
- * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
- * Rights Reserved.
- * 
- * Contributor(s):
- *
- */
-
-#include "sha.h"
-#include "string.h"
-#include "stdio.h"
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-typedef struct {
-	unsigned long H[5];
-	unsigned long W[80];
-	int lenW;
-	unsigned long sizeHi, sizeLo;
-} j_SHA_CTX;
-
-static void shaHashBlock(j_SHA_CTX *ctx);
-
-void shaInit(j_SHA_CTX *ctx) {
-  int i;
-
-  ctx->lenW = 0;
-  ctx->sizeHi = ctx->sizeLo = 0;
-
-  /* Initialize H with the magic constants (see FIPS180 for constants)
-   */
-  ctx->H[0] = 0x67452301L;
-  ctx->H[1] = 0xefcdab89L;
-  ctx->H[2] = 0x98badcfeL;
-  ctx->H[3] = 0x10325476L;
-  ctx->H[4] = 0xc3d2e1f0L;
-
-  for (i = 0; i < 80; i++)
-    ctx->W[i] = 0;
-}
-
-
-void shaUpdate(j_SHA_CTX *ctx, unsigned char *dataIn, int len) {
-  int i;
-
-  /* Read the data into W and process blocks as they get full
-   */
-  for (i = 0; i < len; i++) {
-    ctx->W[ctx->lenW / 4] <<= 8;
-    ctx->W[ctx->lenW / 4] |= (unsigned long)dataIn[i];
-    if ((++ctx->lenW) % 64 == 0) {
-      shaHashBlock(ctx);
-      ctx->lenW = 0;
-    }
-    ctx->sizeLo += 8;
-    ctx->sizeHi += (ctx->sizeLo < 8);
-  }
-}
-
-
-void shaFinal(j_SHA_CTX *ctx, unsigned char hashout[20]) {
-  unsigned char pad0x80 = 0x80;
-  unsigned char pad0x00 = 0x00;
-  unsigned char padlen[8];
-  int i;
-
-  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
-   */
-  padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
-  padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
-  padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
-  padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
-  padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
-  padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
-  padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
-  padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
-  shaUpdate(ctx, &pad0x80, 1);
-  while (ctx->lenW != 56)
-    shaUpdate(ctx, &pad0x00, 1);
-  shaUpdate(ctx, padlen, 8);
-
-  /* Output hash
-   */
-  for (i = 0; i < 20; i++) {
-    hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
-    ctx->H[i / 4] <<= 8;
-  }
-
-  /*
-   *  Re-initialize the context (also zeroizes contents)
-   */
-  shaInit(ctx); 
-}
-
-
-void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) {
-  j_SHA_CTX ctx;
-
-  shaInit(&ctx);
-  shaUpdate(&ctx, dataIn, len);
-  shaFinal(&ctx, hashout);
-}
-
-
-#define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL)
-
-static void shaHashBlock(j_SHA_CTX *ctx) {
-  int t;
-  unsigned long A,B,C,D,E,TEMP;
-
-  for (t = 16; t <= 79; t++)
-    ctx->W[t] =
-      SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
-
-  A = ctx->H[0];
-  B = ctx->H[1];
-  C = ctx->H[2];
-  D = ctx->H[3];
-  E = ctx->H[4];
-
-  for (t = 0; t <= 19; t++) {
-    TEMP = (SHA_ROTL(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 20; t <= 39; t++) {
-    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 40; t <= 59; t++) {
-    TEMP = (SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 60; t <= 79; t++) {
-    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-
-  ctx->H[0] += A;
-  ctx->H[1] += B;
-  ctx->H[2] += C;
-  ctx->H[3] += D;
-  ctx->H[4] += E;
-}
-
-/*----------------------------------------------------------------------------
- *
- * This code added by Thomas "temas" Muldowney for Jabber compatability
- *
- *---------------------------------------------------------------------------*/
-char *shahash(char *str)
-{
-    static char final[41];
-    char *pos;
-    unsigned char hashval[20];
-    int x;
-
-    if(!str || strlen(str) == 0)
-        return NULL;
-
-    shaBlock((unsigned char *)str, strlen(str), hashval);
-
-    pos = final;
-    for(x=0;x<20;x++)
-    {
-        snprintf(pos, 3, "%02x", hashval[x]);
-        pos += 2;
-    }
-    return (char *)final;
-}
-
-void shahash_r(const char* str, char hashbuf[41])
-{
-    int x;
-    char *pos;
-    unsigned char hashval[20];
-    
-    if(!str || strlen(str) == 0)
-        return;
-
-    shaBlock((unsigned char *)str, strlen(str), hashval);
-
-    pos = hashbuf;
-    for(x=0;x<20;x++)
-    {
-        snprintf(pos, 3, "%02x", hashval[x]);
-        pos += 2;
-    }
-
-    return;
-}
--- a/src/sha.h	Sat Sep 27 23:42:22 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/**
- * @file sha.h SHA1 Hash functions
- *
- * gaim
- *
- * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef _GAIM_JABBER_SHA_H_
-#define _GAIM_JABBER_SHA_H_
-
-char *shahash(char *str);
-void shahash_r(const char* str, char hashbuf[41]);
-
-#endif /* _GAIM_JABBER_JID_H_ */