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,