File kopete_yahoo_login.patch of Package kdenetwork3

Index: kopete/protocols/yahoo/libkyahoo/client.h
===================================================================
--- kopete/protocols/yahoo/libkyahoo/client.h.orig	2007-05-14 11:40:07.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/client.h	2010-01-14 21:33:55.000000000 +0300
@@ -27,7 +27,7 @@
 #include "transfer.h"
 #include "yahootypes.h"
 
-#define YMSG_PROGRAM_VERSION_STRING "7,5,0,33"
+#define YMSG_PROGRAM_VERSION_STRING "8.1.0.209"
 
 class QString;
 class QTimer;
Index: kopete/protocols/yahoo/libkyahoo/client.cpp
===================================================================
--- kopete/protocols/yahoo/libkyahoo/client.cpp.orig	2007-10-08 13:49:09.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/client.cpp	2010-01-14 21:33:55.000000000 +0300
@@ -258,7 +258,7 @@ void Client::slotLoginResponse( int resp
 			changeStatus( d->statusOnConnect, d->statusMessageOnConnect, Yahoo::StatusTypeAway );
 		d->statusMessageOnConnect = QString::null;
 		setStatus( d->statusOnConnect );
-		m_pingTimer->start( 60 * 1000 );
+		m_pingTimer->start( 60 * 60 * 1000 );
 		initTasks();
 	} else {
 		d->active = false;
Index: kopete/protocols/yahoo/libkyahoo/logintask.h
===================================================================
--- kopete/protocols/yahoo/libkyahoo/logintask.h.orig	2006-10-01 21:26:34.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/logintask.h	2010-01-14 21:33:55.000000000 +0300
@@ -27,6 +27,11 @@
 class QString;
 class YMSGTransfer;
 
+namespace KIO
+{
+    class Job;
+}
+
 /**
 @author Duncan Mac-Vicar
 */
@@ -58,6 +63,15 @@ protected:
 	void sendAuthResp_pre_0x0b(const QString &sn, const QString &seed);
 	void handleAuthResp(YMSGTransfer *transfer);
 	void parseCookies( YMSGTransfer *transfer );
+	void sendAuthSixteenStage1(const QString &sn, const QString &seed);
+	void sendAuthSixteenStage2(const QString &token);
+	void sendAuthSixteenStage3(const QString &cryptString);
+protected slots:
+	void handleAuthSixteenStage1Data(KIO::Job*, const QByteArray &data);
+	void handleAuthSixteenStage1Result(KIO::Job*);
+	void handleAuthSixteenStage2Data(KIO::Job*, const QByteArray &data);
+	void handleAuthSixteenStage2Result(KIO::Job*);
+
 signals:
 	void haveSessionID( uint );
 	void haveCookies();
@@ -70,6 +84,10 @@ private:
 	QString m_cCookie;
 	QString m_loginCookie;
 	QString m_verificationWord;
+	QString m_stage1Data;
+	QString m_stage2Data;
+	QString m_challengeString;
+	uint m_sessionID;
 };
 
 #endif
Index: kopete/protocols/yahoo/libkyahoo/logintask.cpp
===================================================================
--- kopete/protocols/yahoo/libkyahoo/logintask.cpp.orig	2006-10-01 21:26:34.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/logintask.cpp	2010-01-14 21:33:55.000000000 +0300
@@ -26,7 +26,13 @@
 #include "yahootypes.h"
 #include "client.h"
 #include <qstring.h>
+#include <qurl.h>
 #include <kdebug.h>
+#include <kio/global.h>
+#include <kio/job.h>
+#include <kio/jobclasses.h>
+#include <kurl.h>
+#include <kmdcodec.h>
 #include <stdlib.h>
 extern "C"
 {
@@ -67,6 +73,9 @@ bool LoginTask::take(Transfer* transfer)
 
 	YMSGTransfer *t = static_cast<YMSGTransfer *>(transfer);
 
+	if( t->service() == Yahoo::ServicePing )
+		return true;
+
 	switch (mState)
 	{
 		case (InitialState):
@@ -101,6 +110,9 @@ bool LoginTask::forMe(Transfer* transfer
 	if (!t)
 		return false;
 
+	if( t->service() == Yahoo::ServicePing )
+		return true;
+
 	switch (mState)
 	{
 		case (InitialState):
@@ -133,7 +145,7 @@ void LoginTask::onGo()
 	if (mState == InitialState)
 		sendVerify();
 	else
-			client()->notifyError( "Error in login procedure.", "take called while not in initial state", Client::Debug );
+			client()->notifyError( "Error in login procedure.", "onGo called while not in initial state", Client::Debug );
 }
 
 void LoginTask::reset()
@@ -170,53 +182,204 @@ void LoginTask::sendAuthResp(YMSGTransfe
 	
 	QString sn = t->firstParam( 1 );
 	QString seed = t->firstParam( 94 );
+	m_challengeString = seed;
 	QString version_s = t->firstParam( 13 );
-	uint sessionID = t->id();
+	m_sessionID = t->id();
 	int version = version_s.toInt();
 	
 	switch (version)
 	{
 		case 0:
-		kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " Version pre 0x0b "<< version_s << endl;	
+		case 1:
+		case 2:
+		    kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " Using version 16 authorization" << endl;
+		    sendAuthSixteenStage1(sn, seed);
 		break;
 		default:
-		kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " Version 0x0b "<< version_s << endl;
-		sendAuthResp_0x0b(sn, seed, sessionID);
+		    kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " Unknown authentication method used !" << endl << " Attempting current authentication anyways" << endl;
+		    sendAuthSixteenStage1(sn, seed);
 		break;
 	}	
 	mState = SentAuthResp;
 
-	emit haveSessionID( sessionID );
+	emit haveSessionID( m_sessionID );
 }
 
 void LoginTask::sendAuthResp_0x0b(const QString &sn, const QString &seed, uint sessionID)
 {
+	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl;
+}
+
+void LoginTask::sendAuthSixteenStage1(const QString &sn, const QString &seed)
+{
+	const QString YahooTokenUrl = "https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=&login=%1&passwd=%2&chal=%3";
 	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " with seed " << seed << endl;
-	char *resp_6 = (char *) malloc(100);
-	char *resp_96 = (char *) malloc(100);
-	authresp_0x0b(seed.latin1(), sn.latin1(), (client()->password()).latin1(), resp_6, resp_96);
-	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "resp_6: " << resp_6 << " resp_69: " << resp_96 << endl;
-	YMSGTransfer *t = new YMSGTransfer(Yahoo::ServiceAuthResp, m_stateOnConnect);
-	t->setId( sessionID );
-	t->setParam( 0 , sn.local8Bit());
-	t->setParam( 6 , resp_6);
-	t->setParam( 96 , resp_96);
-	t->setParam( 59 , "B\\tfckeert1kk1nl&b=2" );	// ???
-	t->setParam( 135 , "7,0,0,437" );	// Client version
-	t->setParam( 148 , -60 );
-	t->setParam( 244 , 524223 );
-	t->setParam( 1 , sn.local8Bit());
+	m_stage1Data = QString::null;
+	/* construct a URL from the seed and request tokens */
+	QString urlEncodedPass = client()->password();
+	QUrl::encode(urlEncodedPass);
+	QString fullUrl = YahooTokenUrl.arg(sn, urlEncodedPass, seed);
+	KURL tokenUrl(fullUrl);
+	KIO::Job* job = KIO::get(tokenUrl, true, false);
+	connect(job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+	        this, SLOT(handleAuthSixteenStage1Data(KIO::Job*, const QByteArray&)));
+	connect(job, SIGNAL(result(KIO::Job*)),
+	        this, SLOT(handleAuthSixteenStage1Result(KIO::Job*)));
+}
+
+void LoginTask::handleAuthSixteenStage1Data(KIO::Job* job, const QByteArray &data)
+{
+	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " with data " << data << endl;
+	m_stage1Data.append(data);
+}
+
+void LoginTask::handleAuthSixteenStage1Result(KIO::Job* job)
+{
+	int responseNumber = -1;
+	QString token;
+	int error = job->error();
+	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " error: " << error << endl;
+	if (error == 0)
+	{
+		QStringList responses = QStringList::split("\r\n", m_stage1Data);
+		responseNumber = responses[0].toInt();
+		if (responses.count() >= 3)
+		{
+			token = responses[1];
+			token.remove("ymsgr=");
+			kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "response is:" << responseNumber << endl;
+			kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "token is:" << token << endl;
+		}
 
-	if( !m_verificationWord.isEmpty() )
+		if (responseNumber != 0)
 	{
-		t->setParam( 227 , m_verificationWord.local8Bit() );
-		m_verificationWord = QString::null;
+			switch(responseNumber)
+	{
+			case -1:
+				/* error in the received stream */
+				emit loginResponse(Yahoo::LoginSock, QString());
+				kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "unknown error logging in" << endl;
+				break;
+			case 1212:
+				/* password incorrect */
+				emit loginResponse(Yahoo::LoginPasswd, QString());
+				kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "password incorrect" << endl;
+				break;
+			case 1213:
+				/* security lock */
+				emit loginResponse(Yahoo::LoginLock, QString());
+				kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "user locked" << endl;
+				break;
+			case 1235:
+				/* username does not exist */
+				emit loginResponse(Yahoo::LoginUname, QString());
+				kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "user does not exist" << endl;
+				break;
+			case 1214:
+			case 1236:
+				emit loginResponse(Yahoo::LoginVerify, QString());
+				break;
+			case 100: /* username or password missing */
+				/*FIXME handle this */
+				break;
+			default:
+				/* FIXME unknown error. handle it! */
+				break;
+			}
+	}
+		else
+		{
+			/* start stage 2 here */
+			sendAuthSixteenStage2(token);
 	}
+	}
+}
 
-	free(resp_6);
-	free(resp_96);
-	send(t);
+void LoginTask::sendAuthSixteenStage2(const QString &token)
+{
+	const QString YahooLoginUrl = "https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=&token=%1";
+	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " with token " << token << endl;
+	m_stage2Data = QString::null;
+	QString fullUrl = YahooLoginUrl.arg(token);
+	KURL loginUrl(fullUrl);
+	KIO::Job* job = KIO::get(loginUrl, true, false);
+	connect(job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+	        this, SLOT(handleAuthSixteenStage2Data(KIO::Job*, const QByteArray&)));
+	connect(job, SIGNAL(result(KIO::Job*)),
+	        this, SLOT(handleAuthSixteenStage2Result(KIO::Job*)));
+}
 
+void LoginTask::handleAuthSixteenStage2Data(KIO::Job* job, const QByteArray &data)
+{
+	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " with data " << data << endl;
+	m_stage2Data.append(data);
+}
+
+void LoginTask::handleAuthSixteenStage2Result(KIO::Job* job)
+{
+	QString crumb;
+	int responseNumber = -1;
+	int error = job->error();
+	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "error:" << error << endl;
+	if (error == 0)
+	{
+		QStringList responses = QStringList::split("\r\n", m_stage2Data);
+		kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << responses << endl;
+		responseNumber = responses[0].toInt();
+		if (responseNumber == 0)
+		{
+			crumb = responses[1];
+			crumb.remove("crumb=");
+			m_yCookie = responses[2].remove(0,2); /* remove Y= */
+			m_tCookie = responses[3].remove(0,2); /* remove T= */
+		}
+
+		if (responseNumber != 0)
+		{
+			switch(responseNumber)
+			{
+			case -1:
+				emit loginResponse(Yahoo::LoginSock, QString());
+				break;
+			case 100:
+				emit loginResponse(Yahoo::LoginSock, QString());
+				break;
+			default: /* try to login anyways */
+				break;
+			}
+		}
+		else
+		{
+			QString cryptString = crumb;
+			cryptString.append(m_challengeString);
+			sendAuthSixteenStage3(cryptString);
+		}
+	}
+}
+
+void LoginTask::sendAuthSixteenStage3(const QString &cryptString)
+{
+	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " with crypt string " << cryptString << endl;
+
+	KMD5 md5(cryptString.ascii());
+	QCString cryptStringHash = md5.base64Digest();
+	cryptStringHash = cryptStringHash.replace('+', '.');
+	cryptStringHash = cryptStringHash.replace('/', '_');
+	cryptStringHash = cryptStringHash.replace('=', '-');
+
+	YMSGTransfer *t = new YMSGTransfer(Yahoo::ServiceAuthResp, m_stateOnConnect);
+	t->setId( m_sessionID );
+   	t->setParam( 1, client()->userId().local8Bit());
+	t->setParam( 0 , client()->userId().local8Bit());
+	t->setParam( 277, m_yCookie.local8Bit() );
+	t->setParam( 278, m_tCookie.local8Bit() );
+	t->setParam( 307, cryptStringHash );
+	t->setParam( 244, 2097087 );
+	t->setParam( 2 , client()->userId().local8Bit());
+	t->setParam( 2, 1 ); // Both parameter 2s wind up in the packet
+	t->setParam( 135, YMSG_PROGRAM_VERSION_STRING );
+
+	send(t);
 }
 
 void LoginTask::sendAuthResp_pre_0x0b(const QString &/*sn*/, const QString &/*seed*/)
Index: kopete/protocols/yahoo/libkyahoo/ymsgtransfer.h
===================================================================
--- kopete/protocols/yahoo/libkyahoo/ymsgtransfer.h.orig	2006-10-01 21:26:34.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/ymsgtransfer.h	2010-01-14 21:33:55.000000000 +0300
@@ -56,6 +56,8 @@ public:
 	void setStatus(Yahoo::Status status);
 	unsigned int id();
 	void setId(unsigned int id);
+	int packetLength();
+	void setPacketLength(int len);
 
 	ParamList paramList();
 	QCString firstParam( int index );
Index: kopete/protocols/yahoo/libkyahoo/ymsgtransfer.cpp
===================================================================
--- kopete/protocols/yahoo/libkyahoo/ymsgtransfer.cpp.orig	2006-10-01 21:26:34.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/ymsgtransfer.cpp	2010-01-14 21:33:55.000000000 +0300
@@ -120,6 +120,16 @@ ParamList YMSGTransfer::paramList()
 	return d->data;
 }
 
+int YMSGTransfer::packetLength()
+{
+	return d->packetLength;
+}
+
+void YMSGTransfer::setPacketLength(int len)
+{
+	d->packetLength = len;
+}
+
 int YMSGTransfer::paramCount( int index )
 {
 	int cnt = 0;
@@ -213,9 +223,9 @@ QByteArray YMSGTransfer::serialize()
 	
 	stream << (Q_INT8)'Y' << (Q_INT8)'M' << (Q_INT8)'S' << (Q_INT8)'G';
 	if( d->service == Yahoo::ServicePictureUpload )
-		stream << (Q_INT16)0x0e00;
+		stream << (Q_INT16)0x0f00;
 	else
-		stream << (Q_INT16)0x000e;
+		stream << (Q_INT16)0x000f;
 	stream << (Q_INT16)0x0000;
 	if( d->service == Yahoo::ServicePictureUpload ||
 		d->service == Yahoo::ServiceFileTransfer )
Index: kopete/protocols/yahoo/libkyahoo/statusnotifiertask.cpp
===================================================================
--- kopete/protocols/yahoo/libkyahoo/statusnotifiertask.cpp.orig	2007-05-14 11:40:07.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/statusnotifiertask.cpp	2010-01-14 21:33:55.000000000 +0300
@@ -72,7 +72,8 @@ bool StatusNotifierTask::forMe( Transfer
 		t->service() == Yahoo::ServiceIddeAct ||
 		t->service() == Yahoo::ServiceStatus ||
 		t->service() == Yahoo::ServiceStealthOffline ||
-		t->service() == Yahoo::ServiceAuthorization
+		t->service() == Yahoo::ServiceAuthorization ||
+		t->service() == Yahoo::ServiceBuddyStatus
 	)
 		return true;
 	else
Index: kopete/protocols/yahoo/libkyahoo/listtask.cpp
===================================================================
--- kopete/protocols/yahoo/libkyahoo/listtask.cpp.orig	2007-05-14 11:40:07.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/listtask.cpp	2010-01-14 21:33:55.000000000 +0300
@@ -58,7 +58,8 @@ bool ListTask::forMe( Transfer* transfer
 		return false;
 
 
-	if ( t->service() == Yahoo::ServiceList )
+	if ( t->service() == Yahoo::ServiceList  ||
+	t->service() == Yahoo::ServiceBuddyList )
 		return true;
 	else
 		return false;
@@ -67,7 +68,7 @@ bool ListTask::forMe( Transfer* transfer
 void ListTask::parseBuddyList( YMSGTransfer *t )
 {
 	kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl;
-
+/*
 	QString raw;
 	m_list.append( t->firstParam( 87 ) );
 
@@ -89,6 +90,22 @@ void ListTask::parseBuddyList( YMSGTrans
 		}
 	}
 	m_list.truncate( 0 );
+*/
+	ParamList plist = t->paramList();
+	Param p;
+	QString group;
+	for(ParamList::Iterator it = plist.begin(); it != plist.end(); ++it)
+	{
+		p = *it;
+		switch(p.first)
+		{
+			case 65:
+				group = p.second;
+				break;
+			case 7:
+				emit gotBuddy(p.second, QString::null, group);
+		}
+	}
 }
 
 void ListTask::parseStealthList( YMSGTransfer *t )
Index: kopete/protocols/yahoo/libkyahoo/yahootypes.h
===================================================================
--- kopete/protocols/yahoo/libkyahoo/yahootypes.h.orig	2006-10-01 21:26:34.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/yahootypes.h	2010-01-14 21:33:55.000000000 +0300
@@ -100,7 +100,9 @@ namespace Yahoo
 		ServiceFileTransfer7 = 0xdc,	/* YMSG13 */
 		ServiceFileTransfer7Info,	/* YMSG13 */
 		ServiceFileTransfer7Accept,	/* YMSG13 */
-		ServiceBuddyChangeGroup = 0xe7	/* YMSG13 */
+		ServiceBuddyChangeGroup = 0xe7,	/* YMSG13 */
+		ServiceBuddyStatus = 0xf0,	/* YMSG13 */
+		ServiceBuddyList = 0xf1		/* YMSG13 */
 	};
 	
 	enum Status 
Index: kopete/protocols/yahoo/libkyahoo/ymsgprotocol.cpp
===================================================================
--- kopete/protocols/yahoo/libkyahoo/ymsgprotocol.cpp.orig	2007-10-08 13:49:09.000000000 +0400
+++ kopete/protocols/yahoo/libkyahoo/ymsgprotocol.cpp	2010-01-14 21:33:55.000000000 +0300
@@ -237,6 +237,14 @@ Transfer* YMSGProtocol::parse( const QBy
 			kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " Parsed packet service -  This means ServicePeerToPeer " << servicenum << endl;
 			service = Yahoo::ServicePeerToPeer;
 		break;
+		case (Yahoo::ServiceBuddyStatus) :
+			kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " Parsed packet service -  This means ServiceBuddyStatus " << servicenum << endl;
+			service = Yahoo::ServiceBuddyStatus;
+		break;
+		case (Yahoo::ServiceBuddyList) :
+			kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " Parsed packet service -  This means ServiceBuddyList " << servicenum << endl;
+			service = Yahoo::ServiceBuddyList;
+		break;
 		/*
 		ServiceIdle, // 5 (placemarker)
 		ServiceMailStat,
openSUSE Build Service is sponsored by