Beispiel #1
0
void ICQClient::snac_login(unsigned short type, unsigned short)
{
    unsigned long newUin;
    switch (type){
    case ICQ_SNACxLOGIN_ERROR:
        m_reconnect = NO_RECONNECT;
        m_socket->error_state(I18N_NOOP("Login error"), AuthError);
        break;
    case ICQ_SNACxLOGIN_REGISTER:
        if (data.owner.Uin.value){
            m_socket->error_state(I18N_NOOP("Registered in no register state"));
            break;
        }
        m_socket->readBuffer.incReadPos(0x2E);
        m_socket->readBuffer.unpack(newUin);
        log(L_DEBUG, "Register %u %08lX", newUin, newUin);
        setUin(newUin);
        setState(Connecting);
        m_socket->connect(getServer(), getPort(), this);
        break;
    case ICQ_SNACxLOGIN_AUTHxKEYxRESPONSE:
        if (data.owner.Screen.ptr){
            string md5_key;
            m_socket->readBuffer.unpackStr(md5_key);
            snac(ICQ_SNACxFAM_LOGIN, ICQ_SNACxLOGIN_MD5xLOGIN, false, false);
            m_socket->writeBuffer.tlv(0x0001, data.owner.Screen.ptr);
            MD5_CTX c;
            MD5_Init(&c);
            unsigned char md[MD5_DIGEST_LENGTH];
            MD5_Update(&c, md5_key.c_str(), md5_key.length());
            string pswd = getContacts()->fromUnicode(NULL, getPassword());
            MD5_Update(&c, pswd.c_str(), pswd.length());
            pswd = "AOL Instant Messenger (SM)";
            MD5_Update(&c, pswd.c_str(), pswd.length());
            MD5_Final(md, &c);

            m_socket->writeBuffer.tlv(0x0025, (char*)&md, sizeof(md));
            m_socket->writeBuffer.tlv(0x0003, "AOL Instant Messenger, version 5.1.3036/WIN32");
            m_socket->writeBuffer.tlv(0x0016, (unsigned short)0x0109);
            m_socket->writeBuffer.tlv(0x0017, (unsigned short)0x0005);
            m_socket->writeBuffer.tlv(0x0018, (unsigned short)0x0001);
            m_socket->writeBuffer.tlv(0x0019, (unsigned short)0x0000);
            m_socket->writeBuffer.tlv(0x001A, (unsigned short)0x0BDC);
            m_socket->writeBuffer.tlv(0x0014, 0x000000D2L);
            m_socket->writeBuffer.tlv(0x000F, "en");
            m_socket->writeBuffer.tlv(0x000E, "us");
            m_socket->writeBuffer.tlv(0x004A, "\x01");
            sendPacket();
        }
        break;
    case ICQ_SNACxLOGIN_LOGINxREPLY:
        chn_close();
        break;
    default:
        log(L_WARN, "Unknown login family type %04X", type);
    }
}
void ICQClient::snac_login(unsigned short type, unsigned short)
{
    unsigned long newUin;
    switch (type){
    case ICQ_SNACxLOGIN_ERROR:
        if (data.owner.Uin.value){
            m_reconnect = NO_RECONNECT;
            m_socket->error_state(I18N_NOOP("Login error"), AuthError);
            break;
        }
        // in the process of registering;
        // it seems that we need to request bot protection picture;
        // reconnecting to send the request.
        log(L_DEBUG, "Verification required, reconnecting");
        m_bVerifying = true;
        m_socket->close();
        m_socket->connect(getServer(), getPort(), this);
        break;
    case ICQ_SNACxLOGIN_REGISTER:
        if (data.owner.Uin.value){
            m_socket->error_state(I18N_NOOP("Registered in no register state"));
            break;
        }
        m_socket->readBuffer.incReadPos(0x2E);
        m_socket->readBuffer.unpack(newUin);
        log(L_DEBUG, "Register %lu %08lX", newUin, newUin);
        setUin(newUin);
        setState(Connecting);
        m_socket->connect(getServer(), getPort(), this);
        break;
    case ICQ_SNACxLOGIN_AUTHxKEYxRESPONSE:
        log(L_DEBUG, "Sending MD5 key");
        if (data.owner.Screen.ptr || data.owner.Uin.value){
            string md5_key;
            m_socket->readBuffer.unpackStr(md5_key);
            snac(ICQ_SNACxFAM_LOGIN, ICQ_SNACxLOGIN_MD5xLOGIN, false, false);
	    if (data.owner.Uin.value){
                char uin[20];
                sprintf(uin, "%lu", data.owner.Uin.value);
                m_socket->writeBuffer.tlv(0x0001, uin);
	    }else{
                m_socket->writeBuffer.tlv(0x0001, data.owner.Screen.ptr);
	    }
            string md = md5_key;
            md += getContacts()->fromUnicode(NULL, getPassword());
            md += "AOL Instant Messenger (SM)";
            md = md5(md.c_str());
            m_socket->writeBuffer.tlv(0x0025, md.c_str(), md.length());
	    if (data.owner.Uin.value){
		m_socket->writeBuffer.tlv(0x0003, "ICQ Inc. - Product of ICQ (TM).2003b.5.56.1.3916.85");
		m_socket->writeBuffer.tlv(0x0016, 0x010A);
		m_socket->writeBuffer.tlv(0x0017, 0x0002);
		m_socket->writeBuffer.tlv(0x0018, 0x0038);
		m_socket->writeBuffer.tlv(0x0019, 0x0001);
		m_socket->writeBuffer.tlv(0x001A, 0x0F4C);
		m_socket->writeBuffer.tlv(0x0014, 0x00000055L);
		m_socket->writeBuffer.tlv(0x000f, "en");
		m_socket->writeBuffer.tlv(0x000e, "us");
	    }else{
		m_socket->writeBuffer.tlv(0x0003, "AOL Instant Messenger, version 5.1.3036/WIN32");
		m_socket->writeBuffer.tlv(0x0016, (unsigned short)0x0109);
		m_socket->writeBuffer.tlv(0x0017, (unsigned short)0x0005);
		m_socket->writeBuffer.tlv(0x0018, (unsigned short)0x0001);
		m_socket->writeBuffer.tlv(0x0019, (unsigned short)0x0000);
		m_socket->writeBuffer.tlv(0x001A, (unsigned short)0x0BDC);
		m_socket->writeBuffer.tlv(0x0014, 0x000000D2L);
		m_socket->writeBuffer.tlv(0x000F, "en");
		m_socket->writeBuffer.tlv(0x000E, "us");
		m_socket->writeBuffer.tlv(0x004A, "\x01");
	    }
            sendPacket(true);
        }
        break;
    case ICQ_SNACxLOGIN_LOGINxREPLY:
        chn_close();
        break;
    case ICQ_SNACxLOGIN_REGISTERxSEND_IMG: {
        m_bVerifying = false;
        TlvList tlv(m_socket->readBuffer);
        // currently there are 2 TLVs in SNAC(17,0D):
        // type = 1: the value contains the mime type of the image (image/jpeg); ignored
        // type = 2: the value contains the image itself in the binary form
        Tlv* tlvImage = tlv(2);
        if (!tlvImage)
            break;
        log(L_DEBUG, "Image length: %d bytes", tlvImage->Size());
        uchar* buf = new uchar[tlvImage->Size()];
        memcpy(buf, *tlvImage, tlvImage->Size());
        QPixmap pict;
        if (!pict.loadFromData(buf, tlvImage->Size()))
        {
            delete[] buf;
            break;
        }
        delete[] buf;
        log(L_DEBUG, "Received verification image");
        VerifyDlg verdlg(qApp->activeWindow(), pict);
        if (verdlg.exec() == QDialog::Accepted) // what to do if the user has cancelled the dialog?
        {
            QString verifyStr = verdlg.getVerifyString();
            log(L_DEBUG, "User input: %s", verifyStr.latin1());
            snac(ICQ_SNACxFAM_LOGIN, ICQ_SNACxLOGIN_REGISTERxREQ);
            Buffer msg;
            msg
            << 0x00000000L << 0x28000300L << 0x00000000L
            << 0x00000000L << 0x94680000L << 0x94680000L
            << 0x00000000L << 0x00000000L << 0x00000000L
            << 0x00000000L;
            string pswd = getContacts()->fromUnicode(NULL, getPassword());
            unsigned short len = (unsigned short)(pswd.length() + 1);
            msg.pack(len);
            msg.pack(pswd.c_str(), len);
            msg << 0x94680000L << 0x00000602L;
            m_socket->writeBuffer.tlv(0x0001, msg);
            m_socket->writeBuffer.tlv(0x0009, verifyStr.latin1(), verifyStr.length());
            sendPacket(true);            
        }
        break;
        }
    default:
        log(L_WARN, "Unknown login family type %04X", type);
    }
}
Beispiel #3
0
void ICQClient::packet_ready()
{
    time(&m_lastTime);
    if (m_bHeader){
        char c;
        readBuffer >> c;
        if (c != 0x2A){
            log(L_ERROR, "Server send bad packet start code: %02X", c);
            error(ErrorProtocol);
            return;
        }
        readBuffer >> m_nChannel;
        unsigned short sequence, size;
        readBuffer >> sequence >> size;
        if (size){
            readBuffer.add(size);
            m_bHeader = false;
            return;
        }
    }
    dumpPacket(readBuffer, 0,"Read");
    switch (m_nChannel){
    case ICQ_CHNxNEW:
        chn_login();
        break;
    case ICQ_CHNxCLOSE:
        chn_close();
        break;
    case ICQ_CHNxDATA:{
            unsigned short fam, type;
            unsigned short flags, seq, cmd;
            readBuffer >> fam >> type >> flags >> seq >> cmd;
            switch (fam){
            case ICQ_SNACxFAM_SERVICE:
                snac_service(type, seq);
                break;
            case ICQ_SNACxFAM_LOCATION:
                snac_location(type, seq);
                break;
            case ICQ_SNACxFAM_BUDDY:
                snac_buddy(type, seq);
                break;
            case ICQ_SNACxFAM_MESSAGE:
                snac_message(type, seq);
                break;
            case ICQ_SNACxFAM_BOS:
                snac_bos(type, seq);
                break;
            case ICQ_SNACxFAM_PING:
                snac_ping(type, seq);
                break;
            case ICQ_SNACxFAM_LISTS:
                snac_lists(type, seq);
                break;
            case ICQ_SNACxFAM_VARIOUS:
                snac_various(type, seq);
                break;
            case ICQ_SNACxFAM_LOGIN:
                snac_login(type, seq);
                break;
            default:
                log(L_WARN, "Unknown family %02X", fam);
            }
            break;
        }
    default:
        log(L_ERROR, "Unknown channel %u", m_nChannel & 0xFF);
    }
    processInfoRequestQueue();
    processPhoneRequestQueue(0);
    processResponseRequestQueue(0);
    readBuffer.init(6);
    m_bHeader = true;
}