summaryrefslogtreecommitdiff
path: root/net-im
diff options
context:
space:
mode:
authorJason Wever <weeve@gentoo.org>2003-10-05 21:08:26 +0000
committerJason Wever <weeve@gentoo.org>2003-10-05 21:08:26 +0000
commit313fdf0461a321873da8ba12c0fa51acbff43fee (patch)
tree93189988479d5547411ebe9b2874e25615781ec9 /net-im
parentRevision bump, adds the yahoo patch from bitlbee's website. (diff)
downloadgentoo-2-313fdf0461a321873da8ba12c0fa51acbff43fee.tar.gz
gentoo-2-313fdf0461a321873da8ba12c0fa51acbff43fee.tar.bz2
gentoo-2-313fdf0461a321873da8ba12c0fa51acbff43fee.zip
Revision bump, adds the yahoo patch from bitlbee's website.
Diffstat (limited to 'net-im')
-rw-r--r--net-im/bitlbee/ChangeLog8
-rw-r--r--net-im/bitlbee/Manifest4
-rw-r--r--net-im/bitlbee/bitlbee-0.80-r2.ebuild64
-rw-r--r--net-im/bitlbee/files/digest-bitlbee-0.80-r21
-rw-r--r--net-im/bitlbee/files/yahoo.diff919
5 files changed, 993 insertions, 3 deletions
diff --git a/net-im/bitlbee/ChangeLog b/net-im/bitlbee/ChangeLog
index 6117b2f98d52..6fdb4d86353f 100644
--- a/net-im/bitlbee/ChangeLog
+++ b/net-im/bitlbee/ChangeLog
@@ -1,6 +1,12 @@
# ChangeLog for net-im/bitlbee
# Copyright 2000-2003 Gentoo Technologies, Inc.; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/net-im/bitlbee/ChangeLog,v 1.15 2003/10/01 19:59:22 taviso Exp $
+# $Header: /var/cvsroot/gentoo-x86/net-im/bitlbee/ChangeLog,v 1.16 2003/10/05 21:08:22 weeve Exp $
+
+*bitlbee-0.80-r2 (05 Oct 2003)
+
+ 05 Oct 2003; Jason Wever <weeve@gentoo.org> bitlbee-0.80-r2.ebuild,
+ files/yahoo.diff:
+ Revision bump, adds the yahoo patch from bitlbee's website.
01 Oct 2003; Tavis Ormandy <taviso@gentoo.org> bitlbee-0.80-r1.ebuild:
Stable on alpha
diff --git a/net-im/bitlbee/Manifest b/net-im/bitlbee/Manifest
index 093e98a71d90..7fd00d0b37fb 100644
--- a/net-im/bitlbee/Manifest
+++ b/net-im/bitlbee/Manifest
@@ -1,4 +1,4 @@
-MD5 da14a0ca97481a7c8b4f211088a1f4cb ChangeLog 2235
+MD5 2bb8d733c2900cc2ec41b4fca7604339 ChangeLog 2419
MD5 b870fd31387b2c349eca82cb901b870e bitlbee-0.72.ebuild 1089
MD5 494046f3b577301770f06c6e4bc06c5d bitlbee-0.73-r1.ebuild 1329
MD5 2436faed029fde54669d7c71fda8dd4d bitlbee-0.73.ebuild 1089
@@ -6,7 +6,7 @@ MD5 c5dcd7f7f902927880a7e10011bc8f66 bitlbee-0.74a.ebuild 1327
MD5 c4f5a4975c9788e23b9f2590fcebbdaa bitlbee-0.80-r1.ebuild 1450
MD5 0395435f5921975e399b54e471ea6541 bitlbee-0.80.ebuild 1305
MD5 fc51bd6f3a89c98a4a447e9b1725e488 metadata.xml 465
-MD5 defe161404c6409524496f74bd2baa0d bitlbee-0.80-r2.ebuild 1481
+MD5 85996dfc72437a4c0c148be20eb18cb4 bitlbee-0.80-r2.ebuild 1489
MD5 6668146d14da88ef8240b49671db3e9b files/yahoo.diff 25463
MD5 348ecbcec9cf34e7164b0f0189ea5963 files/bitlbee-0.80-xinetd.patch 730
MD5 144e462c0af1d82a3412a237519b32ca files/bitlbee-xinetd.patch 519
diff --git a/net-im/bitlbee/bitlbee-0.80-r2.ebuild b/net-im/bitlbee/bitlbee-0.80-r2.ebuild
new file mode 100644
index 000000000000..a60af3835350
--- /dev/null
+++ b/net-im/bitlbee/bitlbee-0.80-r2.ebuild
@@ -0,0 +1,64 @@
+# Copyright 1999-2003 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/net-im/bitlbee/bitlbee-0.80-r2.ebuild,v 1.1 2003/10/05 21:08:22 weeve Exp $
+
+inherit eutils
+
+DESCRIPTION="Bitlbee is an irc to IM gateway that support mutliple IM protocols"
+HOMEPAGE="http://www.lintux.cx/bitlbee.html"
+SRC_URI="http://www.lintux.cx/downloads/${P}.tar.gz"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86 sparc alpha"
+IUSE=""
+
+DEPEND="virtual/glibc"
+
+src_unpack() {
+ unpack ${P}.tar.gz
+
+ # Patch the default xinetd file to add/adjust values to Gentoo defaults
+ cd ${S}/doc
+ epatch ${FILESDIR}/${P}-xinetd.patch
+ cd ${S}
+ epatch ${FILESDIR}/yahoo.diff
+}
+
+src_compile() {
+ econf --datadir=/usr/share/bitlbee --etcdir=/etc
+ emake || die "make failed"
+
+ # make bitlbeed forking server
+ cd utils
+ [ -n "${CC}" ] \
+ && ${CC} ${CFLAGS} bitlbeed.c -o bitlbeed \
+ || gcc ${CFLAGS} bitlbeed.c -o bitlbeed
+
+}
+
+src_install() {
+ mkdir -p ${D}/var/lib/bitlbee
+ make install DESTDIR=${D} || die "install failed"
+
+ dodoc COPYING
+ dodoc doc/{AUTHORS,CHANGES,CREDITS,FAQ,README,TODO}
+ dohtml -A sgml doc/*.sgml
+ doman doc/bitlbee.8
+
+ dobin utils/bitlbeed
+
+ insinto /etc/xinetd.d
+ newins doc/bitlbee.xinetd bitlbee
+
+ exeinto /etc/init.d
+ newexe ${FILESDIR}/bitlbeed.init bitlbeed || die
+
+ insinto /etc/conf.d
+ newins ${FILESDIR}/bitlbeed.confd bitlbeed || die
+}
+
+pkg_postinst() {
+ chown nobody:nobody /var/lib/bitlbee
+ chmod 700 /var/lib/bitlbee
+}
diff --git a/net-im/bitlbee/files/digest-bitlbee-0.80-r2 b/net-im/bitlbee/files/digest-bitlbee-0.80-r2
new file mode 100644
index 000000000000..84df83fac49a
--- /dev/null
+++ b/net-im/bitlbee/files/digest-bitlbee-0.80-r2
@@ -0,0 +1 @@
+MD5 96d947bef8c6c40c865beaeee59737eb bitlbee-0.80.tar.gz 351775
diff --git a/net-im/bitlbee/files/yahoo.diff b/net-im/bitlbee/files/yahoo.diff
new file mode 100644
index 000000000000..3f7e4bcf7dcf
--- /dev/null
+++ b/net-im/bitlbee/files/yahoo.diff
@@ -0,0 +1,919 @@
+diff -uNr bitlbee-0.80/protocols/yahoo/sha.h y/bitlbee-0.81/protocols/yahoo/sha.h
+--- bitlbee-0.80/protocols/yahoo/sha.h Thu Jan 1 01:00:00 1970
++++ y/bitlbee-0.81/protocols/yahoo/sha.h Tue Sep 30 20:44:20 2003
+@@ -0,0 +1,22 @@
++#if (SIZEOF_INT == 4)
++typedef unsigned int uint32;
++#elif (SIZEOF_SHORT == 4)
++typedef unsigned short uint32;
++#else
++typedef unsigned int uint32;
++#endif /* HAVEUINT32 */
++
++int strprintsha(char *dest, int *hashval);
++
++typedef struct {
++ unsigned long H[5];
++ unsigned long W[80];
++ int lenW;
++ unsigned long sizeHi,sizeLo;
++} SHA_CTX;
++
++void shaInit(SHA_CTX *ctx);
++void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len);
++void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]);
++void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]);
++
+diff -uNr bitlbee-0.80/protocols/yahoo/yahoo.c y/bitlbee-0.81/protocols/yahoo/yahoo.c
+--- bitlbee-0.80/protocols/yahoo/yahoo.c Wed May 21 11:37:04 2003
++++ y/bitlbee-0.81/protocols/yahoo/yahoo.c Wed Oct 1 21:41:00 2003
+@@ -38,6 +38,7 @@
+ #include <sys/stat.h>
+ #include <ctype.h>
+ #include "nogaim.h"
++#include "sha.h"
+ #include "proxy.h"
+ #include "md5.h"
+
+@@ -52,7 +53,7 @@
+ #define USEROPT_PAGERPORT 4
+ #define YAHOO_PAGER_PORT 5050
+
+-#define YAHOO_PROTO_VER 0x0900
++#define YAHOO_PROTO_VER 0x000b
+
+ enum yahoo_service { /* these are easier to see in hex */
+ YAHOO_SERVICE_LOGON = 1,
+@@ -73,7 +74,7 @@
+ YAHOO_SERVICE_ADDIDENT, /* 0x10 */
+ YAHOO_SERVICE_ADDIGNORE,
+ YAHOO_SERVICE_PING,
+- YAHOO_SERVICE_GROUPRENAME,
++ YAHOO_SERVICE_GOTGROUPRENAME,
+ YAHOO_SERVICE_SYSMESSAGE = 0x14,
+ YAHOO_SERVICE_PASSTHROUGH2 = 0x16,
+ YAHOO_SERVICE_CONFINVITE = 0x18,
+@@ -89,12 +90,30 @@
+ YAHOO_SERVICE_GAMELOGOFF,
+ YAHOO_SERVICE_GAMEMSG = 0x2a,
+ YAHOO_SERVICE_FILETRANSFER = 0x46,
++ YAHOO_SERVICE_VOICECHAT = 0x4A,
+ YAHOO_SERVICE_NOTIFY = 0x4B,
++ YAHOO_SERVICE_VERIFY,
++ YAHOO_SERVICE_P2PFILEXFER,
++ YAHOO_SERVICE_PEEPTOPEER = 0x4F,
++ YAHOO_SERVICE_WEBCAM,
+ YAHOO_SERVICE_AUTHRESP = 0x54,
+ YAHOO_SERVICE_LIST = 0x55,
+ YAHOO_SERVICE_AUTH = 0x57,
+ YAHOO_SERVICE_ADDBUDDY = 0x83,
+- YAHOO_SERVICE_REMBUDDY = 0x84
++ YAHOO_SERVICE_REMBUDDY = 0x84,
++ YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0*/
++ YAHOO_SERVICE_REJECTCONTACT,
++ YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */
++ /* YAHOO_SERVICE_??? = 0x8A, */
++ YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/
++ YAHOO_SERVICE_CHATGOTO,
++ YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */
++ YAHOO_SERVICE_CHATLEAVE,
++ YAHOO_SERVICE_CHATEXIT = 0x9b,
++ YAHOO_SERVICE_CHATADDINVITE = 0x9d,
++ YAHOO_SERVICE_CHATLOGOUT = 0xa0,
++ YAHOO_SERVICE_CHATPING,
++ YAHOO_SERVICE_COMMENT = 0xa8
+ };
+
+ enum yahoo_status {
+@@ -114,8 +133,12 @@
+ YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */
+ YAHOO_STATUS_TYPING = 0x16
+ };
++
++
+ #define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */
+
++static void yahoo_close(struct gaim_connection *gc);
++
+ struct yahoo_data {
+ int fd;
+ guchar *rxqueue;
+@@ -185,6 +208,8 @@
+
+ return len;
+ }
++static struct prpl *my_protocol = NULL;
++
+
+ /* sometimes i wish prpls could #include things from other prpls. then i could just
+ * use the routines from libfaim and not have to admit to knowing how they work. */
+@@ -376,21 +401,20 @@
+ break;
+ case 13: /* in pager? */
+ if (pkt->service == YAHOO_SERVICE_LOGOFF ||
+- strtol(pair->value, NULL, 10) == 0) {
+- serv_got_update(gc, name, 0, 0, 0, 0, 0, 0);
++ strtol(pair->value, NULL, 10) == 0) { serv_got_update(gc, gc->username, 0, 0, 0, 0, 0, 0);
+ break;
+ }
+- if (g_hash_table_lookup(yd->games, name))
++ if (g_hash_table_lookup(yd->games, gc->username))
+ gamestate = YAHOO_STATUS_GAME;
+ if (state == YAHOO_STATUS_AVAILABLE)
+- serv_got_update(gc, name, 1, 0, 0, 0, gamestate, 0);
++ serv_got_update(gc, gc->username, 1, 0, 0, 0, gamestate, 0);
+ else
+- serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE | gamestate, 0);
++ serv_got_update(gc, gc->username, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE | gamestate, 0);
+ if (state == YAHOO_STATUS_CUSTOM) {
+- gpointer val = g_hash_table_lookup(yd->hash, name);
++ gpointer val = g_hash_table_lookup(yd->hash, gc->username);
+ if (val) {
+ g_free(val);
+- g_hash_table_insert(yd->hash, name,
++ g_hash_table_insert(yd->hash, gc->username,
+ msg ? g_strdup(msg) : g_malloc0(1));
+ } else
+ g_hash_table_insert(yd->hash, g_strdup(name),
+@@ -581,16 +605,16 @@
+ show_got_added(gc, id, who, NULL, msg);
+ if (name) {
+ if (state == YAHOO_STATUS_AVAILABLE)
+- serv_got_update(gc, name, 1, 0, 0, 0, 0, 0);
++ serv_got_update(gc, gc->username, 1, 0, 0, 0, 0, 0);
+ else if (state == YAHOO_STATUS_IDLE)
+- serv_got_update(gc, name, 1, 0, 0, time(NULL) - 600, (state << 2), 0);
++ serv_got_update(gc, gc->username, 1, 0, 0, time(NULL) - 600, (state << 2), 0);
+ else
+- serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE, 0);
++ serv_got_update(gc, gc->username, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE, 0);
+ if (state == YAHOO_STATUS_CUSTOM) {
+- gpointer val = g_hash_table_lookup(yd->hash, name);
++ gpointer val = g_hash_table_lookup(yd->hash, gc->username);
+ if (val) {
+ g_free(val);
+- g_hash_table_insert(yd->hash, name,
++ g_hash_table_insert(yd->hash,gc->username,
+ msg ? g_strdup(msg) : g_malloc0(1));
+ } else
+ g_hash_table_insert(yd->hash, g_strdup(name),
+@@ -630,12 +654,523 @@
+ *out = '\0';
+ }
+
++
++static void yahoo_process_auth_new(struct gaim_connection *gc, const char *seed)
++{
++ struct yahoo_packet *pack = NULL;
++ 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];
++ const 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, gc->password, strlen(gc->password));
++ md5_finish(&ctx, result);
++ to_y64(password_hash, result, 16);
++
++ md5_init(&ctx);
++ crypt_result = yahoo_crypt(gc->password, "$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, gc->username);
++ yahoo_packet_hash(pack, 6, resp_6);
++ yahoo_packet_hash(pack, 96, resp_96);
++ yahoo_packet_hash(pack, 1, gc->username);
++ yahoo_send_packet(yd, pack);
++ yahoo_packet_free(pack);
++
++ free(password_hash);
++ free(crypt_hash);
++}
++
++
++
++
++static void yahoo_process_auth_old(struct gaim_connection *gc, const char *seed)
++{
++ struct yahoo_packet *pack;
++ 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(gc->username));
++ char *hash_string_c = g_malloc(50 + strlen(gc->username));
++
++ char checksum;
++
++ int sv;
++
++ char result6[25];
++ char result96[25];
++
++ sv = seed[15];
++ sv = sv % 8;
++
++ md5_init(&ctx);
++ md5_append(&ctx, gc->password, strlen(gc->password));
++ md5_finish(&ctx, result);
++ to_y64(password_hash, result, 16);
++
++ md5_init(&ctx);
++ crypt_result = yahoo_crypt(gc->password, "$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(gc->username) + 50,
++ "%c%s%s%s", checksum, gc->username, seed, password_hash);
++ g_snprintf(hash_string_c, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, gc->username, seed, crypt_hash);
++ break;
++ case 2:
++ case 7:
++ checksum = seed[seed[15] % 16];
++ g_snprintf(hash_string_p, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, seed, password_hash, gc->username);
++ g_snprintf(hash_string_c, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, seed, crypt_hash, gc->username);
++ break;
++ case 3:
++ checksum = seed[seed[1] % 16];
++ g_snprintf(hash_string_p, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, gc->username, password_hash, seed);
++ g_snprintf(hash_string_c, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, gc->username, crypt_hash, seed);
++ break;
++ case 4:
++ checksum = seed[seed[3] % 16];
++ g_snprintf(hash_string_p, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, password_hash, seed, gc->username);
++ g_snprintf(hash_string_c, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, crypt_hash, seed, gc->username);
++ break;
++ case 0:
++ case 5:
++ checksum = seed[seed[7] % 16];
++ g_snprintf(hash_string_p, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, password_hash, gc->username, seed);
++ g_snprintf(hash_string_c, strlen(gc->username) + 50,
++ "%c%s%s%s", checksum, crypt_hash, gc->username, 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, gc->username);
++ yahoo_packet_hash(pack, 6, result6);
++ yahoo_packet_hash(pack, 96, result96);
++ yahoo_packet_hash(pack, 1, gc->username);
++
++ yahoo_send_packet(yd, pack);
++
++ g_free(hash_string_p);
++ g_free(hash_string_c);
++
++ yahoo_packet_free(pack);
++
++}
++
++
+ static void yahoo_process_auth(struct gaim_connection *gc, struct yahoo_packet *pkt)
+ {
+ char *seed = NULL;
+ char *sn = NULL;
+ GSList *l = pkt->hash;
+- struct yahoo_data *yd = gc->proto_data;
++ int m = 1;
++
+
+ while (l) {
+ struct yahoo_pair *pair = l->data;
+@@ -643,122 +1178,44 @@
+ 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;
+-
+- /* 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 = g_malloc(25);
+- char *crypt_hash = g_malloc(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 = g_malloc(25);
+- char *result96 = g_malloc(25);
+-
+- sv = seed[15];
+- sv = sv % 8;
+-
+- md5_init(&ctx);
+- md5_append(&ctx, gc->password, strlen(gc->password));
+- md5_finish(&ctx, result);
+- to_y64(password_hash, result, 16);
+-
+- md5_init(&ctx);
+- crypt_result = yahoo_crypt(gc->password, "$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(sn) + 50,
+- "%c%s%s%s", checksum, gc->username, seed, password_hash);
+- g_snprintf(hash_string_c, strlen(sn) + 50,
+- "%c%s%s%s", checksum, gc->username, seed, crypt_hash);
+- 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, gc->username);
+- g_snprintf(hash_string_c, strlen(sn) + 50,
+- "%c%s%s%s", checksum, seed, crypt_hash, gc->username);
+- break;
+- case 3:
+- checksum = seed[seed[1] % 16];
+- g_snprintf(hash_string_p, strlen(sn) + 50,
+- "%c%s%s%s", checksum, gc->username, password_hash, seed);
+- g_snprintf(hash_string_c, strlen(sn) + 50,
+- "%c%s%s%s", checksum, gc->username, 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, gc->username);
+- g_snprintf(hash_string_c, strlen(sn) + 50,
+- "%c%s%s%s", checksum, crypt_hash, seed, gc->username);
+- break;
++ switch (m) {
+ case 0:
+- case 5:
+- checksum = seed[seed[7] % 16];
+- g_snprintf(hash_string_p, strlen(sn) + 50,
+- "%c%s%s%s", checksum, password_hash, gc->username, seed);
+- g_snprintf(hash_string_c, strlen(sn) + 50,
+- "%c%s%s%s", checksum, crypt_hash, gc->username, seed);
++ yahoo_process_auth_old(gc, seed);
+ break;
++ case 1:
++ yahoo_process_auth_new(gc, seed);
++ break;
++ default:
++ 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, gc->username);
+- yahoo_packet_hash(pack, 6, result6);
+- yahoo_packet_hash(pack, 96, result96);
+- yahoo_packet_hash(pack, 1, gc->username);
+-
+- yahoo_send_packet(yd, pack);
+-
+- g_free(result6);
+- g_free(result96);
+- g_free(password_hash);
+- g_free(crypt_hash);
+- g_free(hash_string_p);
+- g_free(hash_string_c);
++ }
++}
+
+- yahoo_packet_free(pack);
++static void yahoo_process_authresp(struct gaim_connection *gc, struct
++yahoo_packet *pkt)
++{
++ GSList *l = pkt->hash;
++ int err = 0;
++
++ while (l) {
++ struct yahoo_pair *pair = l->data;
++
++ if (pair->key == 66)
++ err = strtol(pair->value, NULL, 10);
++
++ l = l->next;
+ }
++
++
+ }
+
++
+ static void yahoo_packet_process(struct gaim_connection *gc, struct yahoo_packet *pkt)
+ {
+ switch (pkt->service)
+@@ -781,6 +1238,9 @@
+ case YAHOO_SERVICE_NEWMAIL:
+ // yahoo_process_mail(gc, pkt);
+ break;
++ case YAHOO_SERVICE_AUTHRESP:
++ yahoo_process_authresp(gc, pkt);
++ break;
+ case YAHOO_SERVICE_NEWCONTACT:
+ yahoo_process_contact(gc, pkt);
+ break;
+@@ -795,18 +1255,20 @@
+ }
+ }
+
++
+ static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond)
+ {
+ struct gaim_connection *gc = data;
+ struct yahoo_data *yd = gc->proto_data;
+ char buf[1024];
+ int len;
++
+
+ len = read(yd->fd, buf, sizeof(buf));
+
+ if (len <= 0) {
+ hide_login_progress_error(gc, "Unable to read");
+- signoff(gc);
++ yahoo_close(gc);
+ return;
+ }
+
+@@ -857,6 +1319,7 @@
+ }
+ }
+
++
+ static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond)
+ {
+ struct gaim_connection *gc = data;
+@@ -878,10 +1341,10 @@
+ yd->fd = source;
+
+ pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0);
+-
+ yahoo_packet_hash(pkt, 1, gc->username);
+ yahoo_send_packet(yd, pkt);
+
++
+ yahoo_packet_free(pkt);
+
+ gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc);
+@@ -894,17 +1357,14 @@
+ set_login_progress(gc, 1, "Connecting");
+
+ yd->fd = -1;
+- yd->hash = g_hash_table_new(g_str_hash, g_str_equal);
++ yd->hash= g_hash_table_new(g_str_hash, g_str_equal);
+ yd->games = g_hash_table_new(g_str_hash, g_str_equal);
++ if (!g_strncasecmp(user->proto_opt[USEROPT_PAGERHOST], "cs.yahoo.com", strlen("cs.yahoo.com"))) {
++ /* Figured out the new auth method -- cs.yahoo.com likes to disconnect on buddy remove and add now */
++ g_snprintf(user->proto_opt[USEROPT_PAGERHOST], strlen("scs.yahoo.com") + 1, "scs.yahoo.com");
++// save_prefs();
++ }
+
+-
+- if (!g_strncasecmp(user->proto_opt[USEROPT_PAGERHOST], "cs.yahoo.com", strlen("cs.yahoo.com"))) {
+- /* Figured out the new auth method -- cs.yahoo.com likes to disconnect on buddy remove and add now */
+- g_snprintf(user->proto_opt[USEROPT_PAGERHOST], strlen("scs.yahoo.com") + 1, "scs.yahoo.com");
+-// save_prefs();
+- }
+-
+-
+ if (proxy_connect(user->proto_opt[USEROPT_PAGERHOST][0] ?
+ user->proto_opt[USEROPT_PAGERHOST] : YAHOO_PAGER_HOST,
+ user->proto_opt[USEROPT_PAGERPORT][0] ?
+@@ -1186,8 +1646,6 @@
+ yahoo_send_packet(yd, pkt);
+ yahoo_packet_free(pkt);
+ }
+-
+-static struct prpl *my_protocol = NULL;
+
+ void yahoo_init(struct prpl *ret) {
+ ret->protocol = PROTO_YAHOO;