bool PKCS15DODF::parseData(ByteArray data)
	{
		bool result = false;
		SimpleTLV tlv(data);

		while (tlv.decodeTLV())
		{
			switch (tlv.getTag())
			{
			case (unsigned int)0xA1 : /* CHOICE 1 : OidDO */
				{
					PKCS15OID oid(tlv.getValue());

					SCARD_DEBUG("OID DataObject");

					pair<ByteArray, PKCS15OID> newPair(oid.getOID(), oid);
					mapOID.insert(newPair);
				}
				break;

			default :
				SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.getLength(), tlv.getValue().toString());
				break;
			}
		}

		SCARD_DEBUG("dataList.size() = %d", mapOID.size());

		return result;
	}
Exemple #2
0
		void SecurityBlock::TLVList::set(SecurityBlock::TLV_TYPES type, std::string value)
		{
			SecurityBlock::TLV tlv(type, value);

			erase(tlv);
			insert(tlv);
		}
TlvChain& TlvChain::operator=(const Buffer& buffer)
{
    Buffer tmpBuffer = buffer;
    while ( tmpBuffer.bytesAvailable() > 0 ) {
        Word type = tmpBuffer.getWord();
        Word length = tmpBuffer.getWord();
        Tlv tlv( type, tmpBuffer.read(length) );
        m_tlvList.insert(type, tlv);
    }
    return *this;
}
	// CliMetaReqOfflineDelete SNAC
CliMetaReqOfflineDeleteSNAC::CliMetaReqOfflineDeleteSNAC(DWord uin)
	: SNAC_ICQ(ICQ_CLI_METAREQ, true) { 

	UnformattedTLV tlv(TLV_TYPE_UIN);

	tlv.data().setLittleEndian();
	tlv.data() << (Word) 0x0008;
	tlv.data() << uin;
	tlv.data() << DELETE_OFFLINE_MESSAGES;
	tlv.data() << (Word) 0x0002; // FIXME: request sequence
	m_data << tlv.pack();
}
void MetaInfoManager::sendMetaRequest(Word type, Buffer& metadata)
{
    Tlv tlv(0x01); // ENCAPSULATED_METADATA
    tlv.addLEWord( metadata.size() + 8 ); // data chunk size (tlv size - 2 )
    tlv.addLEDWord( d->uin.toUInt() ); // own UIN
    tlv.addLEWord(type);
    tlv.addLEWord( ++(d->metaSequence) ); // request sequence number
    tlv.addData(metadata);

    SnacBuffer snac(0x15, 0x02);
    snac.addTlv(tlv);
    d->socket->write(snac);
}
void TLVChain::parseLen(Buffer& b) {
	Word len;
	UnformattedTLV* tlv(TLV_TYPE_GENERIC);

	b >> len;

	while (len){
		tlv = new UnformattedTLV(TLV_TYPE_GENERIC);
		b.removeFromBegin();
		tlv->parse(b);
		this->addTLV(tlv);
		len -= (tlv->data().len() + 4);
	}
	b.removeFromBegin();
}
Exemple #7
0
string pad256(string& str) {
	string out = str;
	int pad = out.length() % 32;
	if( pad ) { // надо выровнять на 256 бит
	    if( pad>3 ) {
		out += tlv(0,padding.substr(0,32-3-pad));
	    }
	    else {
	    	if( pad==3 ) out += string("\0\0\0");
	    	else
	    	if( pad==2 ) out += string("\0\0");
	    	else         out += string("\0");
	    }
	}
	return out;
}
Exemple #8
0
void ICQClient::snac_service(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxSRV_PAUSE:
        log(L_DEBUG, "Server pause");
        m_bNoSend = true;
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_PAUSExACK);
        m_socket->writeBuffer << ICQ_SNACxFAM_SERVICE
        << ICQ_SNACxFAM_LOCATION
        << ICQ_SNACxFAM_BUDDY
        << ICQ_SNACxFAM_MESSAGE
        << ICQ_SNACxFAM_BOS
        << ICQ_SNACxFAM_PING
        << ICQ_SNACxFAM_LISTS
        << ICQ_SNACxFAM_VARIOUS
        << ICQ_SNACxFAM_LOGIN;
        sendPacket(true);
        break;
    case ICQ_SNACxSRV_RESUME:
        log(L_DEBUG, "Server resume");
        m_bNoSend = false;
        processSendQueue();
        break;
    case ICQ_SNACxSRV_MIGRATE:{
            log(L_DEBUG, "Server migrate");
            m_bNoSend = true;
            int i;
            unsigned short cnt;
            unsigned short fam[0x17];

            m_socket->readBuffer >> cnt;
            for (i = 0; i < cnt; i++) {
                m_socket->readBuffer >> fam[i];
            }
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlv_adr    = tlv(0x05);
            Tlv *tlv_cookie = tlv(0x06);
            for (; i >= 0; i--) {
                setServiceSocket(tlv_adr,tlv_cookie,fam[i]);
            }
            break;
        }
    case ICQ_SNACxSRV_RATExINFO:
    case ICQ_SNACxSRV_RATExCHANGE:{
            const char *msg_text = NULL;
            unsigned short msg_code;
            unsigned short class_id;
            unsigned long  window_size;
            unsigned long  clear_level;
            unsigned long  alert_level;
            unsigned long  limit_level;
            unsigned long  discon_level;
            unsigned long  current_level;
            unsigned long  max_level;
            unsigned long  last_level;
            char current_state;
            m_socket->readBuffer >> msg_code
            >> class_id
            >> window_size
            >> clear_level
            >> alert_level
            >> limit_level
            >> discon_level
            >> current_level
            >> max_level
            >> last_level
            >> current_state;
            if (type == ICQ_SNACxSRV_RATExCHANGE){
                switch (msg_code) {
                case 0x0001:
                    msg_text = "Rate limits parameters changed";
                    break;
                case 0x0002:
                    msg_text = "Rate limits warning";
                    break;
                case 0x0003:
                    msg_text = "Rate limit hit";
                    break;
                case 0x0004:
                    msg_text = "Rate limit clear";
                    break;
                default:
                    msg_text = "Unknown";
                }
                log(L_DEBUG, msg_text);
            }
            log(L_DEBUG, "ws: %04X, cl %04X, al %04X, ll %04X, dl: %04X, cur %04X, ml %04X",
                window_size,clear_level,alert_level,limit_level,discon_level,
                current_level,max_level);
            m_winSize  = window_size;
            m_maxLevel = max_level;
            m_minLevel = alert_level;
            m_curLevel = current_level;
			m_lastSend = QDateTime::currentDateTime();
            processSendQueue();
        }
        if (type != ICQ_SNACxSRV_RATExINFO)
            break;
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK);
        m_socket->writeBuffer << 0x00010002L << 0x00030004L << 0x0005;
        sendPacket(true);
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO);
        sendPacket(true);
        listsRequest();
        locationRequest();
        buddyRequest();
        icmbRequest();
        bosRequest();
        break;
    case ICQ_SNACxSRV_MOTD:
        break;
    case ICQ_SNACxSRV_ACKxIMxICQ:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO);
        sendPacket(true);
        break;
    case ICQ_SNACxSRV_NAMExINFO:{
            string screen = m_socket->readBuffer.unpackScreen();
            if (screen.length() == 0){
                char n;
                m_socket->readBuffer >> n;
                m_socket->readBuffer.incReadPos(n);
                screen = m_socket->readBuffer.unpackScreen();
            }
            if ((unsigned)atol(screen.c_str()) != data.owner.Uin.value){
                log(L_WARN, "No my name info (%s)", screen.c_str());
                break;
            }
            m_socket->readBuffer.incReadPos(4);
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                set_ip(&data.owner.IP, htonl((unsigned long)(*tlvIP)));
            log(L_DEBUG, "Name info");
            break;
        }
    case ICQ_SNACxSRV_SERVICExRESP:{
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlv_id = tlv(0x0D);
            if (!tlv_id){
                log(L_WARN, "No service id in response");
                break;
            }
            Tlv *tlv_adr    = tlv(0x05);
            Tlv *tlv_cookie = tlv(0x06);
            setServiceSocket(tlv_adr,tlv_cookie,(unsigned short)(*tlv_id));
            break;
        }
    case ICQ_SNACxSRV_READYxSERVER:
        log(L_DEBUG, "Server ready");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_IMxICQ);
        if (m_bAIM){
            m_socket->writeBuffer
            << 0x00010003L
            << 0x00130003L
            << 0x00020001L
            << 0x00030001L
            << 0x00040001L
            << 0x00060001L
            << 0x00080001L
            << 0x00090001L
            << 0x000A0001L
            << 0x000B0001L;
        }else{
            m_socket->writeBuffer
            << 0x00010004L
            << 0x00130004L
            << 0x00020001L
            << 0x00030001L
            << 0x00150001L
            << 0x00040001L
            << 0x00060001L
            << 0x00090001L
            << 0x000A0001L
            << 0x000B0001L;
        }
        sendPacket(true);
        break;
    case ICQ_SNACxSRV_ERROR:
        break;
    case ICQ_SNACxSRV_EVIL:{
            unsigned short level;
            m_socket->readBuffer.unpack(level);
            string from = m_socket->readBuffer.unpackScreen();
            data.owner.WarningLevel.value = level;
            QString f;
            f = from.c_str();
            if (f.isEmpty())
                f = i18n("anonymous");
            clientErrorData d;
            d.client  = this;
            d.code    = 0;
            d.err_str = I18N_NOOP("You've been warned by %1");
            d.args    = strdup(f.utf8());
            d.flags   = ERR_INFO;
            d.options = NULL;
            d.id	  = CmdShowWarning;
            Event e(EventClientError, &d);
            e.process();
            free(d.args);
            break;
        }
    default:
        log(L_WARN, "Unknown service family type %04X", type);
    }
Exemple #9
0
void ICQClient::chn_close()
{
    unsigned errorCode = 0;
    TlvList tlv(m_socket->readBuffer);
    Tlv *tlv_error = tlv(8);
    if (tlv_error){
        unsigned short err = *tlv_error;
        string errString;
        switch (err){
        case ICQ_LOGIN_ERRxIP_RATE_LIMIT:
        case ICQ_LOGIN_ERRxIP_RATE_LIMIT1:
            errString = I18N_NOOP("Too many clients from same IP");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxRATE_LIMIT:
            errString = I18N_NOOP("Rate limit");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxBAD_PASSWD:
        case ICQ_LOGIN_ERRxBAD_PASSWD1:
            errString = I18N_NOOP("Invalid UIN and password combination");
            m_reconnect = NO_RECONNECT;
            errorCode = AuthError;
            break;
        case ICQ_LOGIN_ERRxNOT_EXISTS:
        case ICQ_LOGIN_ERRxNOT_EXISTS1:
            errString = I18N_NOOP("Non-existant UIN");
            m_reconnect = NO_RECONNECT;
            errorCode = AuthError;
            break;
        case 0:
            break;
        default:
            errString = "Unknown error ";
            errString += number(err);
        }
        if (err){
            log(L_ERROR, "%s", errString.c_str());
            m_socket->error_state(errString.c_str(), errorCode);
            return;
        }
    }
    tlv_error = tlv(9);
    if (tlv_error){
        string errString;
        unsigned short err = *tlv_error;
        switch (err){
        case 0x1:{
                errString = I18N_NOOP("Youur UIN is being used from another location");
                m_reconnect = NO_RECONNECT;
                break;
            }
        case 0:
            break;
        default:
            errString = "Unknown run-time error ";
            errString += number(err);
        }
        if (err){
            log(L_ERROR, "%s", errString.c_str());
            m_socket->error_state(errString.c_str());
            return;
        }
    }

    Tlv *tlv_host = tlv(5);
    Tlv *tlv_cookie = tlv(6);
    if ((tlv_host == NULL) || (tlv_cookie == NULL)){
        m_socket->error_state(I18N_NOOP("Close packet from server"));
        return;
    }
    char *host = *tlv_host;
    char *port = strchr(host, ':');
    if (port == NULL){
        log(L_ERROR, "Bad host address %s", host);
        m_socket->error_state(I18N_NOOP("Bad host address"));
        return;
    }

    *port = 0;
    port++;
    m_socket->close();
    m_socket->connect(host, (unsigned short)atol(port), this);
    m_cookie.init(0);
    m_cookie.pack(*tlv_cookie, tlv_cookie->Size());
}
Exemple #10
0
void ICQClient::snac_service(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxSRV_RATExCHANGE:
        log(L_DEBUG, "Rate change");
        if (m_nSendTimeout < 200){
            m_nSendTimeout = m_nSendTimeout + 2;
            if (m_sendTimer->isActive()){
                m_sendTimer->stop();
                m_sendTimer->start(m_nSendTimeout * 500);
            }
        }
        break;
    case ICQ_SNACxSRV_RATExINFO:
        log(L_DEBUG, "Rate info");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK);
        m_socket->writeBuffer << 0x00010002L << 0x00030004L << 0x0005;
        sendPacket();
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO);
        sendPacket();
        listsRequest();
        locationRequest();
        buddyRequest();
        icmbRequest();
        bosRequest();
        break;
    case ICQ_SNACxSRV_MOTD:
        log(L_DEBUG, "Motd");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO);
        sendPacket();
        break;
    case ICQ_SNACxSRV_ACKxIMxICQ:
        log(L_DEBUG, "Ack im icq");
        break;
    case ICQ_SNACxSRV_NAMExINFO:{
            string screen = m_socket->readBuffer.unpackScreen();
            if (screen.length() == 0){
                char n;
                m_socket->readBuffer >> n;
                m_socket->readBuffer.incReadPos(n);
                screen = m_socket->readBuffer.unpackScreen();
            }
            if (atol(screen.c_str()) != data.owner.Uin){
                log(L_WARN, "No my name info (%s)", screen.c_str());
                break;
            }
            m_socket->readBuffer.incReadPos(4);
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                set_ip(&data.owner.IP, htonl((unsigned long)(*tlvIP)));
            log(L_DEBUG, "Name info");
            break;
        }
    case ICQ_SNACxSRV_READYxSERVER:
        log(L_DEBUG, "Server ready");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_IMxICQ);
        m_socket->writeBuffer
        << 0x00010003L
        << 0x00130002L
        << 0x00020001L
        << 0x00030001L
        << 0x00150001L
        << 0x00040001L
        << 0x00060001L
        << 0x00090001L
        << 0x000a0001L
        << 0x000b0001L;
        sendPacket();
        break;
    case ICQ_SNACxSRV_ERROR:
        break;
    default:
        log(L_WARN, "Unknown service family type %04X", type);
    }
void FrustumCullingTask::FrustrumCull(CCamera* cam, BaseState* state)
{
	Renderer* renderer = Renderer::getInstance();

	// Points of the AABB in world space
	std::vector<Vector3> verts(8);
	Vector3 origin, scaledHalfVec, rotatedX, rotatedY, rotatedZ;
	Quaternion rot;

  std::vector<CRenderer*>* deferredQueue;
  std::vector<CRenderer*>* forwardQueue;
  std::vector<CRenderer*>* diffuseQueue;
  std::vector<CRenderer*>* fontQueue;
	std::vector<CLight*>* lightQueue;

	//the only thread sensitive area should be here
	{
		ThreadUtils::ThreadLockVisitor tlv(4);
		deferredQueue = &renderer->mMapDeferredQueues[cam];
		forwardQueue = &renderer->mMapForwardQueues[cam];
		diffuseQueue = &renderer->mMapDiffuseQueues[cam];
   fontQueue = &renderer->mMapFontQueues[cam];
		lightQueue = &renderer->mMapLightQueues[cam];
	}

	const std::list<CRenderer*>* listRenderers = state->GetListOfComponentsOfType<CRenderer>();

	if (listRenderers)
	{
		// Get vertices in world space
		for (auto& iter : *listRenderers)
		{
			if (!iter->isEnabled() || !iter->mMesh.Valid())
				continue;

			origin = iter->GetMesh()->GetOrigin();
			rot = iter->gameObject->transform->GetRotationQuaternion();
			scaledHalfVec = iter->GetMesh()->GetAABB().maxPoint - origin;
			scaledHalfVec *= iter->gameObject->transform->scale;
			origin *= iter->gameObject->transform->scale;

			rotatedX = rot.RotatedVector(Vector3::cXAxis * scaledHalfVec.x);
			rotatedY = rot.RotatedVector(Vector3::cYAxis * scaledHalfVec.y);
			rotatedZ = rot.RotatedVector(Vector3::cZAxis * scaledHalfVec.z);
			rot.RotateVector(&origin);
			origin += iter->gameObject->transform->GetGlobalPosition();

			// + + +
			verts[0] = origin + rotatedX + rotatedY + rotatedZ;
			// + + -
			verts[1] = origin + rotatedX + rotatedY - rotatedZ;
			// + - +
			verts[2] = origin + rotatedX - rotatedY + rotatedZ;
			// - + +
			verts[3] = origin - rotatedX + rotatedY + rotatedZ;
			// - - +
			verts[4] = origin - rotatedX - rotatedY + rotatedZ;
			// - + -
			verts[5] = origin - rotatedX + rotatedY - rotatedZ;
			// + - -
			verts[6] = origin + rotatedX - rotatedY - rotatedZ;
			// - - -
			verts[7] = origin - rotatedX - rotatedY - rotatedZ;

			// AABB cull check
			if (cam->CullAABB(verts))
			{
        if (iter->mymeta() == CMeshRenderer::getmeta() || iter->mymeta() == CSkinMeshRenderer::getmeta())
          deferredQueue->push_back(iter);

				else if (iter->mymeta() == CForwardRenderer::getmeta())
          forwardQueue->push_back(iter);

        else if (iter->mymeta() == CDiffuseRenderer::getmeta())
          diffuseQueue->push_back(iter);

        else if (iter->mymeta() == CFontRenderer::getmeta())
          fontQueue->push_back(iter);
			}
		}
	}

	const std::list<CLight*>* listLight = state->GetListOfComponentsOfType<CLight>();
	if (listLight)
	{
		// Iterate through all Lights
		for (auto& light : *listLight)
		{
			if (!light->isEnabled())
				continue;


			if (light->mLightType == CLight::DIRECTIONAL)
			{
				lightQueue->push_back(light);
				continue;
			}

			Vector3 lightPos = light->gameObject->transform->GetGlobalPosition();

			if (cam->CullSphere(lightPos, light->GetRange()))
				lightQueue->push_back(light);
		}
  }  
}
Exemple #12
0
void ICQClient::snac_service(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxSRV_PAUSE:
        log(L_DEBUG, "Server pause");
        /* we now shouldn't send any packets to the server ...
        but I don't know how to solve this. Valdimir do you
        have an idea? */
        /*        m_bDontSendPakets = true; */
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_PAUSExACK);
        m_socket->writeBuffer << ICQ_SNACxFAM_SERVICE
        << ICQ_SNACxFAM_LOCATION
        << ICQ_SNACxFAM_BUDDY
        << ICQ_SNACxFAM_MESSAGE
        << ICQ_SNACxFAM_BOS
        << ICQ_SNACxFAM_PING
        << ICQ_SNACxFAM_LISTS
        << ICQ_SNACxFAM_VARIOUS
        << ICQ_SNACxFAM_LOGIN;
        sendPacket();
        break;
    case ICQ_SNACxSRV_RESUME:
        /*        m_bDontSendPakets = true;
        		emit canSendPakets(); */
        break;
    case ICQ_SNACxSRV_MIGRATE:{
            int i;
            unsigned short cnt;
            unsigned short fam[0x17];

            m_socket->readBuffer >> cnt;
            for (i = 0; i < cnt; i++) {
                m_socket->readBuffer >> fam[i];
            }
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlv_adr    = tlv(0x05);
            Tlv *tlv_cookie = tlv(0x06);
            for (; i >= 0; i--) {
                setServiceSocket(tlv_adr,tlv_cookie,fam[i]);
            }
            /*            m_bDontSendPakets = true;
                        emit canSendPakets(); */
            break;
        }
    case ICQ_SNACxSRV_RATExCHANGE:
        log(L_DEBUG, "Rate change");
        if (m_nSendTimeout < 200){
            m_nSendTimeout = m_nSendTimeout + 2;
            if (m_sendTimer->isActive()){
                m_sendTimer->stop();
                m_sendTimer->start(m_nSendTimeout * 500);
            }
        }
        break;
    case ICQ_SNACxSRV_RATExINFO:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK);
        m_socket->writeBuffer << 0x00010002L << 0x00030004L << 0x0005;
        sendPacket();
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO);
        sendPacket();
        listsRequest();
        locationRequest();
        buddyRequest();
        icmbRequest();
        bosRequest();
        break;
    case ICQ_SNACxSRV_MOTD:
        break;
    case ICQ_SNACxSRV_ACKxIMxICQ:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO);
        sendPacket();
        break;
    case ICQ_SNACxSRV_NAMExINFO:{
            string screen = m_socket->readBuffer.unpackScreen();
            if (screen.length() == 0){
                char n;
                m_socket->readBuffer >> n;
                m_socket->readBuffer.incReadPos(n);
                screen = m_socket->readBuffer.unpackScreen();
            }
            if ((unsigned)atol(screen.c_str()) != data.owner.Uin.value){
                log(L_WARN, "No my name info (%s)", screen.c_str());
                break;
            }
            m_socket->readBuffer.incReadPos(4);
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                set_ip(&data.owner.IP, htonl((unsigned long)(*tlvIP)));
            log(L_DEBUG, "Name info");
            break;
        }
    case ICQ_SNACxSRV_SERVICExRESP:{
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlv_id = tlv(0x0D);
            if (!tlv_id){
                log(L_WARN, "No service id in response");
                break;
            }
            Tlv *tlv_adr    = tlv(0x05);
            Tlv *tlv_cookie = tlv(0x06);
            setServiceSocket(tlv_adr,tlv_cookie,(unsigned short)(*tlv_id));
            break;
        }
    case ICQ_SNACxSRV_READYxSERVER:
        log(L_DEBUG, "Server ready");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_IMxICQ);
        if (m_bAIM){
            m_socket->writeBuffer
            << 0x00010003L
            << 0x00130003L
            << 0x00020001L
            << 0x00030001L
            << 0x00040001L
            << 0x00060001L
            << 0x00080001L
            << 0x00090001L
            << 0x000A0001L
            << 0x000B0001L;
        }else{
            m_socket->writeBuffer
            << 0x00010004L
            << 0x00130004L
            << 0x00020001L
            << 0x00030001L
            << 0x00150001L
            << 0x00040001L
            << 0x00060001L
            << 0x00090001L
            << 0x000A0001L
            << 0x000B0001L;
        }
        sendPacket();
        break;
    case ICQ_SNACxSRV_ERROR:
        break;
    case ICQ_SNACxSRV_EVIL:{
            unsigned short level;
            m_socket->readBuffer.unpack(level);
            string from = m_socket->readBuffer.unpackScreen();
            data.owner.WarningLevel.value = level;
            QString f;
            f = from.c_str();
            if (f.isEmpty())
                f = i18n("anonymous");
            clientErrorData d;
            d.client  = this;
            d.code    = 0;
            d.err_str = I18N_NOOP("You've been warned by %1");
            d.args    = strdup(f.utf8());
            Event e(EventClientError, &d);
            e.process();
            free(d.args);
            break;
        }
    default:
        log(L_WARN, "Unknown service family type %04X", type);
    }
Exemple #13
0
void ICQClient::snac_service(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxSRV_RATExCHANGE:
        log(L_DEBUG, "Rate change");
        if (m_nSendTimeout < 200){
            m_nSendTimeout = m_nSendTimeout + 2;
            if (m_sendTimer->isActive()){
                m_sendTimer->stop();
                m_sendTimer->start(m_nSendTimeout * 500);
            }
        }
        break;
    case ICQ_SNACxSRV_RATExINFO:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK);
        m_socket->writeBuffer << 0x00010002L << 0x00030004L << 0x0005;
        sendPacket();
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO);
        sendPacket();
        listsRequest();
        locationRequest();
        buddyRequest();
        icmbRequest();
        bosRequest();
        break;
    case ICQ_SNACxSRV_MOTD:
        break;
    case ICQ_SNACxSRV_ACKxIMxICQ:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO);
        sendPacket();
        break;
    case ICQ_SNACxSRV_NAMExINFO:{
            string screen = m_socket->readBuffer.unpackScreen();
            if (screen.length() == 0){
                char n;
                m_socket->readBuffer >> n;
                m_socket->readBuffer.incReadPos(n);
                screen = m_socket->readBuffer.unpackScreen();
            }
            if ((unsigned)atol(screen.c_str()) != data.owner.Uin){
                log(L_WARN, "No my name info (%s)", screen.c_str());
                break;
            }
            m_socket->readBuffer.incReadPos(4);
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                set_ip(&data.owner.IP, htonl((unsigned long)(*tlvIP)));
            log(L_DEBUG, "Name info");
            break;
        }
    case ICQ_SNACxSRV_SERVICExRESP:{
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlv_id = tlv(0x0D);
            if (tlv_id == NULL){
                log(L_WARN, "No service id in response");
                break;
            }
            ServiceSocket *s = NULL;
            for (list<ServiceSocket*>::iterator it = m_services.begin(); it != m_services.end(); ++it){
                if ((*it)->id() == (unsigned short)(*tlv_id)){
                    s = *it;
                    break;
                }
            }
            if (s == NULL){
                log(L_WARN, "Service not found");
                break;
            }
            Tlv *tlv_addr   = tlv(0x05);
            if (tlv_addr == NULL){
                s->error_state("No address for service", 0);
                break;
            }
            Tlv *tlv_cookie = tlv(0x06);
            if (tlv_cookie == NULL){
                s->error_state("No cookie for service", 0);
                break;
            }
            unsigned short port = getPort();
            string addr;
            addr = (const char*)(*tlv_addr);
            char *p = (char*)strchr(addr.c_str(), ':');
            if (p){
                *p = 0;
                port = (unsigned short)atol(p + 1);
            }
            s->connect(addr.c_str(), port, *tlv_cookie, tlv_cookie->Size());
            break;
        }
    case ICQ_SNACxSRV_READYxSERVER:
        log(L_DEBUG, "Server ready");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_IMxICQ);
        if (m_bAIM){
            m_socket->writeBuffer
            << 0x00010003L
            << 0x00130003L
            << 0x00020001L
            << 0x00030001L
            << 0x00040001L
            << 0x00060001L
            << 0x00080001L
            << 0x00090001L
            << 0x000A0001L
            << 0x000B0001L;
        }else{
            m_socket->writeBuffer
            << 0x00010004L
            << 0x00130004L
            << 0x00020001L
            << 0x00030001L
            << 0x00150001L
            << 0x00040001L
            << 0x00060001L
            << 0x00090001L
            << 0x000A0001L
            << 0x000B0001L;
        }
        sendPacket();
        break;
    case ICQ_SNACxSRV_ERROR:
        break;
    case ICQ_SNACxSRV_EVIL:{
            unsigned short level;
            m_socket->readBuffer.unpack(level);
            string from = m_socket->readBuffer.unpackScreen();
            data.owner.WarningLevel = level;
            QString f;
            f = from.c_str();
            if (f.isEmpty())
                f = i18n("anonymous");
            clientErrorData d;
            d.client  = this;
            d.code    = 0;
            d.err_str = I18N_NOOP("You've been warned by %1");
            d.args    = strdup(f.utf8());
            Event e(EventClientError, &d);
            e.process();
            free(d.args);
            break;
        }
    default:
        log(L_WARN, "Unknown service family type %04X", type);
    }
Exemple #14
0
void ICQClient::chn_close()
{
    unsigned errorCode = 0;
    TlvList tlv(m_socket->readBuffer);
    Tlv *tlv_error = tlv(8);
    if (tlv_error){
        unsigned short err = *tlv_error;
        string errString;
        switch (err){
        case ICQ_LOGIN_ERRxOLDCLIENT1:
        case ICQ_LOGIN_ERRxOLDCLIENT2:
            errString = I18N_NOOP("This client is outdated");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxIP_RATE_LIMIT1:
        case ICQ_LOGIN_ERRxIP_RATE_LIMIT2:
            errString = I18N_NOOP("Too many clients from same IP");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxRATE_LIMIT1:
        case ICQ_LOGIN_ERRxRATE_LIMIT2:
            errString = I18N_NOOP("Rate limit");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxBAD_PASSWD1:
        case ICQ_LOGIN_ERRxBAD_PASSWD2:
        case ICQ_LOGIN_ERRxBAD_PASSWD3:
            errString = I18N_NOOP("Invalid UIN and password combination");
            m_reconnect = NO_RECONNECT;
            errorCode = AuthError;
            break;
        case ICQ_LOGIN_ERRxNOT_EXISTS1:
        case ICQ_LOGIN_ERRxNOT_EXISTS2:
            errString = I18N_NOOP("Non-existant UIN");
            m_reconnect = NO_RECONNECT;
            errorCode = AuthError;
            break;
        case ICQ_LOGIN_ERRxBAD_LOGIN:
            errString = I18N_NOOP("Bad login procedure");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxUNAVAILABLE1:
        case ICQ_LOGIN_ERRxUNAVAILABLE2:
        case ICQ_LOGIN_ERRxUNAVAILABLE3:
        case ICQ_LOGIN_ERRxUNAVAILABLE4:
        case ICQ_LOGIN_ERRxUNAVAILABLE5:
        case ICQ_LOGIN_ERRxUNAVAILABLE6:
        case ICQ_LOGIN_ERRxUNAVAILABLE7:
        case ICQ_LOGIN_ERRxUNAVAILABLE8:
            errString = I18N_NOOP("Service temporarly unavailable");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxINVALID_ID:
            errString = I18N_NOOP("Invalid SecureID");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxTOO_YOUNG:
            errString = I18N_NOOP("Too young!");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxSUSPENDED1:
            errString = I18N_NOOP("UIN was suspended");
            m_reconnect = NO_RECONNECT;
            break;
        case ICQ_LOGIN_ERRxCANT_REGISTER:
            errString = I18N_NOOP("Can't login to ICQ network - Please try again later");
            m_reconnect = NO_RECONNECT;
            break;
        case 0:
            break;
        default:
            errString = "Unknown error ";
            errString += number(err);
        }
        if (err){
            log(L_ERROR, "%s", errString.c_str());
            m_socket->error_state(errString.c_str(), errorCode);
            return;
        }
    }
    tlv_error = tlv(9);
    if (tlv_error){
        string errString;
        unsigned short err = *tlv_error;
        switch (err){
        case 0x1:{
                errString = I18N_NOOP("Youur UIN is being used from another location");
                m_reconnect = NO_RECONNECT;
                break;
            }
        case 0:
            break;
        default:
            errString = "Unknown run-time error ";
            errString += number(err);
        }
        if (err){
            log(L_ERROR, "%s", errString.c_str());
            m_socket->error_state(errString.c_str());
            return;
        }
    }

    Tlv *tlv_host = tlv(5);
    Tlv *tlv_cookie = tlv(6);
    if ((tlv_host == NULL) || (tlv_cookie == NULL)){
        m_socket->error_state(I18N_NOOP("Close packet from server"));
        return;
    }
    char *host = *tlv_host;
    char *port = strchr(host, ':');
    if (port == NULL){
        log(L_ERROR, "Bad host address %s", host);
        m_socket->error_state(I18N_NOOP("Bad host address"));
        return;
    }

    *port = 0;
    port++;
    m_socket->close();
    m_socket->connect(host, (unsigned short)atol(port), this);
    m_cookie.init(0);
    m_cookie.pack(*tlv_cookie, tlv_cookie->Size());
}
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);
    }
}
Exemple #16
0
void ICQClient::snac_icmb(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxMSG_RIGHTSxGRANTED:
        log(L_DEBUG, "Message rights granted");
        break;
    case ICQ_SNACxMSG_MTN:{
            m_socket->readBuffer.incReadPos(10);
            unsigned long uin = m_socket->readBuffer.unpackUin();
            unsigned short type;
            m_socket->readBuffer >> type;
            bool bType = (type > 1);
            Contact *contact;
            ICQUserData *data = findContact(uin, NULL, false, contact);
            if (data == NULL)
                break;
            if ((bool)(data->bTyping) == bType)
                break;
            data->bTyping = bType;
            Event e(EventContactStatus, contact);
            e.process();
            break;
        }
    case ICQ_SNACxMSG_ERROR:{
            unsigned short error;
            m_socket->readBuffer >> error;
            const char *err_str = I18N_NOOP("Unknown error");
            if (error == 0x0009){
                Contact *contact;
                ICQUserData *data = findContact(m_send.uin, NULL, false, contact);
                if (data){
                    for (list<SendMsg>::iterator it = sendQueue.begin(); it != sendQueue.end();){
                        if ((*it).uin != m_send.uin){
                            ++it;
                            continue;
                        }
                        if ((*it).msg){
                            (*it).flags = 0;
                            ++it;
                            continue;
                        }
                        sendQueue.erase(it);
                        it = sendQueue.begin();
                    }
                    data->bBadClient = true;
                    if (m_send.msg)
                        sendThruServer(m_send.msg, data);
                    m_send.msg = NULL;
                    m_send.uin = 0;
                    m_sendTimer->stop();
                    send(true);
                    break;
                }
            }
            switch (error){
            case 0x0004:
                err_str = I18N_NOOP("User is offline");
                break;
            case 0x000E:
                err_str = I18N_NOOP("Packet was malformed");
                break;
            case 0x0015:
                err_str = I18N_NOOP("List overflow");
                break;
            }
            log(L_DEBUG, "ICMB error %u (%s)", error, err_str);
            if (m_send.msg){
				if (m_send.msg->type() == MessageCheckInvisible){
					bool bInvisible = (error == 0x000E);
					Contact *contact;
					ICQUserData *data = findContact(m_send.uin, NULL, false, contact);
					if (data && ((bool)(data->bInvisible) != bInvisible)){
						data->bInvisible = bInvisible;
						Event e(EventContactStatus, contact);
						e.process();
					}
				}
				m_send.msg->setError(err_str);
				Event e(EventMessageSent, m_send.msg);
				e.process();
                delete m_send.msg;
            }
            m_send.msg = NULL;
            m_send.uin = 0;
            m_sendTimer->stop();
            send(true);
            break;
        }
    case ICQ_SNACxMSG_ACK:
        {
            log(L_DEBUG, "Ack message");
            MessageId id;
            m_socket->readBuffer >> id.id_l >> id.id_h;
            m_socket->readBuffer.incReadPos(2);
            unsigned long uin = m_socket->readBuffer.unpackUin();
            if ((m_send.uin != uin) || !(m_send.id == id))
                log(L_WARN, "Bad ack sequence");
            if (m_send.msg){
                ackMessage();
            }else{
                replyQueue.push_back(m_send);
            }
            m_send.msg = NULL;
            m_send.uin = 0;
            m_sendTimer->stop();
            send(true);
            break;
        }
    case ICQ_SNACxMSG_AUTOREPLY:{
            MessageId id;
            m_socket->readBuffer >> id.id_l >> id.id_h;
            m_socket->readBuffer.incReadPos(2);
            unsigned long uin = m_socket->readBuffer.unpackUin();
            m_socket->readBuffer.incReadPos(2);
            unsigned short len;
            m_socket->readBuffer.unpack(len);
            m_socket->readBuffer.incReadPos(2);
            plugin p;
            m_socket->readBuffer.unpack((char*)p, sizeof(p));
            m_socket->readBuffer.incReadPos(len - sizeof(plugin) + 2);
            m_socket->readBuffer.unpack(len);
            m_socket->readBuffer.incReadPos(len + 0x10);

            if (memcmp(p, plugins[PLUGIN_NULL], sizeof(plugin))){
                unsigned plugin_index;
                for (plugin_index = 0; plugin_index < PLUGIN_NULL; plugin_index++){
                    if (memcmp(p, plugins[plugin_index], sizeof(plugin)) == 0)
                        break;
                }
                if (plugin_index == PLUGIN_NULL){
                    string plugin_str;
                    unsigned i;
                    for (i = 0; i < sizeof(plugin); i++){
                        char b[4];
                        sprintf(b, "%02X ", p[i]);
                        plugin_str += b;
                    }
                    log(L_DEBUG, "Unknown plugin sign in reply %s", plugin_str.c_str());
                    break;
                }
                Contact *contact;
                ICQUserData *data = findContact(uin, NULL, false, contact);
                if ((data == NULL) && (plugin_index != PLUGIN_RANDOMxCHAT))
                    break;

                list<SendMsg>::iterator it;
                for (it = replyQueue.begin(); it != replyQueue.end(); ++it){
                    SendMsg &s = *it;
                    if ((s.id == id) && (s.uin == uin))
                        break;
                }
                if (it == replyQueue.end()){
                    log(L_DEBUG, "No found message for plugin answer (%u)", uin);
                    break;
                }
                unsigned plugin_type = (*it).flags;
                replyQueue.erase(it);
                parsePluginPacket(m_socket->readBuffer, plugin_type, data, uin, false);
                break;
            }

            string answer;
            m_socket->readBuffer >> answer;
            log(L_DEBUG, "Autoreply from %u %s", uin, answer.c_str());
            Contact *contact;
            ICQUserData *data = findContact(uin, NULL, false, contact);
            if (data && set_str(&data->AutoReply, answer.c_str())){
                Event e(EventContactChanged, contact);
                e.process();
            }
            break;
        }
    case ICQ_SNACxMSG_SERVERxMESSAGE:{
            unsigned long timestamp1, timestamp2;
            m_socket->readBuffer >> timestamp1 >> timestamp2;
            unsigned short mFormat;
            m_socket->readBuffer >> mFormat;
            unsigned long uin = m_socket->readBuffer.unpackUin();
            log(L_DEBUG, "Message from %u [%04X]", uin, mFormat);
            unsigned short level, nTLV;
            m_socket->readBuffer >> level >> nTLV;
            switch (mFormat){
            case 0x0001:{
                    TlvList tlv(m_socket->readBuffer);
                    if (!tlv(2)){
                        log(L_WARN, "No found generic message tlv");
                        break;
                    }
                    Buffer m(*tlv(2));
                    TlvList tlv_msg(m);
                    Tlv *m_tlv = tlv_msg(0x101);
                    if (m_tlv == NULL){
                        log(L_WARN, "No found generic message tlv 101");
                        break;
                    }
                    if (m_tlv->Size() <= 4)
                        break;
                    char *m_data = (*m_tlv);
                    unsigned short encoding = (m_data[0] << 8) + m_data[1];
                    m_data += 4;
                    if (encoding == 2){
                        QString text;
                        for (int i = 0; i < m_tlv->Size() - 5; i += 2){
                            unsigned char r1 = *(m_data++);
                            unsigned char r2 = *(m_data++);
                            unsigned short c = (r1 << 8) + r2;
                            text += QChar(c);
                        }
                        Message *msg = new Message(MessageGeneric);
                        msg->setText(text);
                        messageReceived(msg, uin);
                        break;
                    }
                    ICQMessage *msg = new ICQMessage;
                    msg->setServerText(m_data);
                    messageReceived(msg, uin);
                    break;
                }
            case 0x0002:{
                    TlvList tlv(m_socket->readBuffer);
                    if (!tlv(5)){
                        log(L_WARN, "No found ICMB message tlv");
                        break;
                    }
                    Buffer msg(*tlv(5));
                    unsigned short type;
                    msg >> type;
                    switch (type){
                    case 0:
                        parseAdvancedMessage(uin, msg, tlv(3) != NULL, timestamp1, timestamp2);
                        break;
                    case 1:
                        log(L_DEBUG, "Cancel");
                        break;
                    case 2:
                        log(L_DEBUG, "File ack");
                        break;
                    default:
                        log(L_WARN, "Unknown type: %u", type);
                    }
                    break;
                }
            case 0x0004:{
                    TlvList tlv(m_socket->readBuffer);
                    if (!tlv(5)){
                        log(L_WARN, "No found advanced message tlv");
                        break;
                    }
                    Buffer msg(*tlv(5));
                    unsigned long msg_uin;
                    msg >> msg_uin;
                    if (msg_uin == 0){
                        parseAdvancedMessage(uin, msg, tlv(6) != NULL, timestamp1, timestamp2);
                        return;
                    }
                    char type, flags;
                    msg >> type;
                    msg >> flags;
                    string msg_str;
                    msg >> msg_str;
                    Message *m = parseMessage(type, uin, msg_str, msg, 0, 0, timestamp1, timestamp2);
                    if (m)
                        messageReceived(m, uin);
                    break;
                }
            default:
                log(L_WARN, "Unknown message format %04X", mFormat);
            }
            break;
        }
    default:
        log(L_WARN, "Unknown message family type %04X", type);
    }
}
Exemple #17
0
void ICQClient::snac_various(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxVAR_DATA:{
            TlvList tlv(readBuffer);
            if (tlv(0x0001) == NULL){
                log(L_WARN, "Bad server response");
                break;
            }
            Buffer msg(*tlv(1));
            unsigned short len, nType, nId;
            unsigned long own_uin;
            msg >> len >> own_uin >> nType >> nId;
            switch (nType){
            case ICQ_SRVxEND_OFFLINE_MSG:
                log(L_DEBUG, "End offline messages");
                serverRequest(ICQ_SRVxREQ_ACK_OFFLINE_MSG);
                sendServerRequest();
                break;
            case ICQ_SRVxOFFLINE_MSG:{
                    log(L_DEBUG, "Offline message");
                    unsigned long uin;
                    char type, flag;
                    struct tm sendTM;
                    memset(&sendTM, 0, sizeof(sendTM));
                    string message;
                    unsigned short year;
                    char month, day, hours, min;
                    msg >> uin
                    >> year >> month >> day >> hours >> min
                    >> type >> flag;
                    msg >> message;
                    uin = htonl(uin);
                    year = htons(year);
                    sendTM.tm_year = year-1900;
                    sendTM.tm_mon  = month-1;
                    sendTM.tm_mday = day;
                    sendTM.tm_hour = hours;
                    sendTM.tm_min  = min;
                    sendTM.tm_sec  = 0;
                    time_t send_time = mktime(&sendTM);
                    log(L_DEBUG, "Offline message %u [%08lX] %02X %02X %s", uin, uin, type & 0xFF, flag  & 0xFF, message.c_str());
                    ICQMessage *m = parseMessage(type, uin, message, msg, 0, 0, 0, 0);
                    if (m){
                        m->Time = (unsigned long)send_time;
                        messageReceived(m);
                    }
                    break;
                }
            case ICQ_SRVxANSWER_MORE:{
                    unsigned short nSubtype;
                    char nResult;
                    msg >> nSubtype >> nResult;
                    log(L_DEBUG, "Server answer %02X %04X", nResult & 0xFF, nSubtype);
                    if ((nResult == 0x32) || (nResult == 0x14) || (nResult == 0x1E)){
                        ICQEvent *e = findVarEvent(htons(nId));
                        if (e == NULL){
                            log(L_WARN, "Various event ID %04X not found (%X)", nId, nResult);
                            break;
                        }
                        e->failAnswer(this);
                        varEvents.remove(e);
                        delete e;
                        break;
                    }
                    ICQEvent *e = findVarEvent(htons(nId));
                    if (e == NULL){
                        log(L_WARN, "Various event ID %04X not found (%X)", nId, nResult);
                        break;
                    }
                    bool nDelete = e->processAnswer(this, msg, nSubtype);
                    if (nDelete){
                        log(L_DEBUG, "Delete event");
                        varEvents.remove(e);
                        delete e;
                    }
                    break;
                }
            default:
                log(L_WARN, "Unknown SNAC(15,03) response type %04X", nType);
            }
            break;
        }
    default:
        log(L_WARN, "Unknown various family type %04X", type);
    }
}
Exemple #18
0
string tlv(int t, int v) {
	string s;
	u_int l=(v<=0xFF)?1:((v<=0xFFFF)?2:((v<=0xFFFFFF)?3:4));
	s.assign((char*)&v,l);
	return tlv(t,s);
}
Exemple #19
0
string tlv(int t, const char* v) {
	return tlv(t, string(v));
}
Exemple #20
0
void ICQClient::snac_service(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxSRV_RATExCHANGE:
        break;
    case ICQ_SNACxSRV_RATExINFO:
        log(L_DEBUG, "Rate info");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK);
        writeBuffer << 0x00010002L << 0x00030004L << 0x0005;
        sendPacket();
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO);
        sendPacket();
        listsRequest();
        locationRequest();
        buddyRequest();
        messageRequest();
        bosRequest();
        break;
    case ICQ_SNACxSRV_MOTD:
        log(L_DEBUG, "Motd");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO);
        sendPacket();
        break;
    case ICQ_SNACxSRV_ACKxIMxICQ:
        log(L_DEBUG, "Ack im icq");
        break;
    case ICQ_SNACxSRV_NAMExINFO:{
            unsigned long uin = readBuffer.unpackUin();
            if (uin == 0){
                char n;
                readBuffer >> n;
                readBuffer.incReadPos(n);
                uin = readBuffer.unpackUin();
            }
            if (uin != Uin()){
                log(L_WARN, "No my name info (%lu)", uin);
                break;
            }
            readBuffer.incReadPos(4);
            TlvList tlv(readBuffer);
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                RealIP = htonl((unsigned long)(*tlvIP));
            log(L_DEBUG, "Name info");
            bool bSend = true;
            if (needPhonebookUpdate){
                sendInfoUpdate();
                needPhonebookUpdate = false;
                bSend = false;
            }
            if (needPhoneStatusUpdate){
                sendPhoneStatus();
                needPhoneStatusUpdate = false;
                bSend = false;
            }
            break;
        }
    case ICQ_SNACxSRV_READYxSERVER:
        log(L_DEBUG, "Server ready");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_IMxICQ);
        writeBuffer << 0x00010003L;
        writeBuffer << 0x00130002L;
        writeBuffer << 0x00020001L;
        writeBuffer << 0x00030001L;
        writeBuffer << 0x00150001L;
        writeBuffer << 0x00040001L;
        writeBuffer << 0x00060001L;
        writeBuffer << 0x00090001L;
        writeBuffer << 0x000a0001L;
        writeBuffer << 0x000b0001L;
        sendPacket();
        break;
    default:
        log(L_WARN, "Unknown service family type %04X", type);
    }
Exemple #21
0
void ICQClient::snac_service(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxSRV_RATExCHANGE:
        log(L_DEBUG, "Rate change");
        if (m_nSendTimeout < 200){
            m_nSendTimeout = m_nSendTimeout + 2;
            if (m_sendTimer->isActive()){
                m_sendTimer->stop();
                m_sendTimer->start(m_nSendTimeout * 500);
            }
        }
        break;
    case ICQ_SNACxSRV_RATExINFO:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK);
        m_socket->writeBuffer << 0x00010002L << 0x00030004L << 0x0005;
        sendPacket();
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO);
        sendPacket();
        listsRequest();
        locationRequest();
        buddyRequest();
        icmbRequest();
        bosRequest();
        break;
    case ICQ_SNACxSRV_MOTD:
        break;
    case ICQ_SNACxSRV_ACKxIMxICQ:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO);
        sendPacket();
        break;
    case ICQ_SNACxSRV_NAMExINFO:{
            string screen = m_socket->readBuffer.unpackScreen();
            if (screen.length() == 0){
                char n;
                m_socket->readBuffer >> n;
                m_socket->readBuffer.incReadPos(n);
                screen = m_socket->readBuffer.unpackScreen();
            }
            if ((unsigned)atol(screen.c_str()) != data.owner.Uin){
                log(L_WARN, "No my name info (%s)", screen.c_str());
                break;
            }
            m_socket->readBuffer.incReadPos(4);
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                set_ip(&data.owner.IP, htonl((unsigned long)(*tlvIP)));
            log(L_DEBUG, "Name info");
            break;
        }
    case ICQ_SNACxSRV_READYxSERVER:
        log(L_DEBUG, "Server ready");
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_IMxICQ);
		if (m_bAIM){
			m_socket->writeBuffer
			<< 0x00010003L
			<< 0x00130003L
			<< 0x00020001L
			<< 0x00030001L
			<< 0x00040001L
			<< 0x00060001L
			<< 0x00080001L
			<< 0x00090001L
			<< 0x000A0001L
			<< 0x000B0001L;
		}else{
			m_socket->writeBuffer
			<< 0x00010004L
			<< 0x00130004L
			<< 0x00020001L
			<< 0x00030001L
			<< 0x00150001L
			<< 0x00040001L
			<< 0x00060001L
			<< 0x00090001L
			<< 0x000A0001L
			<< 0x000B0001L;
		}
        sendPacket();
        break;
    case ICQ_SNACxSRV_ERROR:
        break;
	case ICQ_SNACxSRV_EVIL:{
			unsigned short level;
			m_socket->readBuffer.unpack(level);
			string from = m_socket->readBuffer.unpackScreen();
			data.owner.WarningLevel = level;
			QString f;
			f = from.c_str();
			if (f.isEmpty())
				f = i18n("anonymous");
			clientErrorData d;
			d.client  = this;
			d.code    = 0;
			d.err_str = I18N_NOOP("You've been warned by %1");
			d.args    = strdup(f.utf8());
			Event e(EventClientError, &d);
			e.process();
			free(d.args);
			break;
		}
    default:
        log(L_WARN, "Unknown service family type %04X", type);
    }
Exemple #22
0
void ICQClient::snac_buddy(unsigned short type, unsigned short)
{
    string screen;
    Contact *contact;
    ICQUserData *data;
    switch (type){
    case ICQ_SNACxBDY_RIGHTSxGRANTED:
        log(L_DEBUG, "Buddy rights granted");
        break;
    case ICQ_SNACxBDY_USEROFFLINE:
        screen = m_socket->readBuffer.unpackScreen();
        data = findContact(screen.c_str(), NULL, false, contact);
        if (data && (data->Status.value != ICQ_STATUS_OFFLINE)){
            setOffline(data);
            StatusMessage m;
            m.setContact(contact->id());
            m.setClient(dataName(data).c_str());
            m.setStatus(STATUS_OFFLINE);
            m.setFlags(MESSAGE_RECEIVED);
            Event e(EventMessageReceived, &m);
            e.process();
        }
        break;
    case ICQ_SNACxBDY_USERONLINE:
        screen = m_socket->readBuffer.unpackScreen();
        data = findContact(screen.c_str(), NULL, false, contact);
        if (data){
            time_t now;
            time(&now);

            bool bChanged     = false;
            bool bAwayChanged = false;
            unsigned long prevStatus = data->Status.value;

            unsigned short level, len;
            m_socket->readBuffer >> level >> len;
            data->WarningLevel.value = level;

            TlvList tlv(m_socket->readBuffer);

            Tlv *tlvClass = tlv(0x0001);
            if (tlvClass){
                unsigned short userClass = *tlvClass;
                if (userClass != data->Class.value){
                    if ((userClass & CLASS_AWAY) != (data->Class.value & CLASS_AWAY)){
                        data->StatusTime.value = (unsigned long)now;
                        bAwayChanged = true;
                    }
                    data->Class.value = userClass;
                    bChanged = true;
                }
                if (data->Uin.value == 0){
                    if (userClass & CLASS_AWAY){
                        fetchAwayMessage(data);
                    }else{
                        set_str(&data->AutoReply.ptr, NULL);
                    }
                }
            }

            // Status TLV
            Tlv *tlvStatus = tlv(0x0006);
            if (tlvStatus){
                unsigned long status = *tlvStatus;
                if (status != data->Status.value){
                    data->Status.value = status;
                    if ((status & 0xFF) == 0)
                        set_str(&data->AutoReply.ptr, NULL);
                    data->StatusTime.value = (unsigned long)now;
                }
            }else if (data->Status.value == ICQ_STATUS_OFFLINE){
                data->Status.value = ICQ_STATUS_ONLINE;
                data->StatusTime.value = (unsigned long)now;
            }

            // Online time TLV
            Tlv *tlvOnlineTime = tlv(0x0003);
            if (tlvOnlineTime){
                unsigned long OnlineTime = *tlvOnlineTime;
                if (OnlineTime != data->OnlineTime.value){
                    data->OnlineTime.value = OnlineTime;
                    bChanged = true;
                }
            }
            Tlv *tlvNATime = tlv(0x0004);
            if (tlvNATime){
                unsigned short na_time = *tlvNATime;
                unsigned long StatusTime = (unsigned long)now - na_time * 60;
                if (StatusTime != data->StatusTime.value){
                    data->StatusTime.value = StatusTime;
                    bChanged = true;
                }
            }

            // IP TLV
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                bChanged |= set_ip(&data->IP, htonl((unsigned long)(*tlvIP)));

            Tlv *tlvCapability = tlv(0x000D);
            if (tlvCapability){
                data->Caps.value = 0;
                Buffer info(*tlvCapability);
                for (; info.readPos() < info.size(); ){
                    capability cap;
                    info.unpack((char*)cap, sizeof(capability));
                    for (unsigned i = 0;; i++){
                        if (*capabilities[i] == 0) break;
                        unsigned size = sizeof(capability);
                        if (i == CAP_SIMOLD) size--;
                        if ((i == CAP_MICQ) || (i == CAP_LICQ) || (i == CAP_SIM)) size -= 4;
                        if (!memcmp(cap, capabilities[i], size)){
                            if (i == CAP_SIMOLD){
                                unsigned char build = cap[sizeof(capability)-1];
                                if (build && ((build == 0x92) || (build < (1 << 6)))) continue;
                                data->Build.value = build;
                            }
                            if ((i == CAP_MICQ) || (i == CAP_LICQ) || (i == CAP_SIM)){
                                unsigned char *p = (unsigned char*)cap;
                                p += 12;
                                data->Build.value = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
                            }
                            data->Caps.value |= (1 << i);
                            break;
                        }
                    }
                }
            }

            unsigned long infoUpdateTime = 0;
            unsigned long pluginInfoTime = 0;
            unsigned long pluginStatusTime = 0;

            // Direct connection info
            Tlv *tlvDirect = tlv(0x000C);
            if (tlvDirect){
                Buffer info(*tlvDirect);
                unsigned long  realIP;
                unsigned short port;
                char mode, version, junk;
                info >> realIP;
                info.incReadPos(2);
                info >> port;
                if (realIP == 0x7F000001)
                    realIP = 0;
                bChanged |= set_ip(&data->RealIP, htonl(realIP));
                data->Port.value = port;
                unsigned long DCcookie;
                info >> mode >> junk >> version >> DCcookie;
                data->DCcookie.value = DCcookie;
                info.incReadPos(8);
                info
                >> infoUpdateTime
                >> pluginInfoTime
                >> pluginStatusTime;
                if (mode == MODE_DENIED) mode = MODE_INDIRECT;
                if ((mode != MODE_DIRECT) && (mode != MODE_INDIRECT))
                    mode = MODE_INDIRECT;
                data->Mode.value    = mode;
                data->Version.value = version;
            }

            Tlv *tlvPlugin = tlv(0x0011);
            if (tlvPlugin && data->Uin.value){
                Buffer info(*tlvPlugin);
                char type;
                unsigned long time;
                info >> type;
                info.unpack(time);
                plugin p;
                unsigned plugin_index;
                unsigned long plugin_status;
                switch (type){
                case 1:
                    addFullInfoRequest(data->Uin.value);
                    break;
                case 2:
                    info.incReadPos(6);
                    info.unpack((char*)p, sizeof(p));
                    data->PluginInfoTime.value = time;
                    for (plugin_index = 0; plugin_index < PLUGIN_NULL; plugin_index++)
                        if (!memcmp(p, plugins[plugin_index], sizeof(p)))
                            break;
                    switch (plugin_index){
                    case PLUGIN_PHONEBOOK:
                        log(L_DEBUG, "Updated phonebook");
                        addPluginInfoRequest(data->Uin.value, plugin_index);
                        break;
                    case PLUGIN_PICTURE:
                        log(L_DEBUG, "Updated picture");
                        addPluginInfoRequest(data->Uin.value, plugin_index);
                        break;
                    case PLUGIN_QUERYxINFO:
                        log(L_DEBUG, "Updated info plugin list");
                        addPluginInfoRequest(data->Uin.value, plugin_index);
                        break;
                    default:
                        if (plugin_index >= PLUGIN_NULL)
                            log(L_WARN, "Unknown plugin sign");
                    }
                    break;
                case 3:
                    info.incReadPos(6);
                    info.unpack((char*)p, sizeof(p));
                    info.incReadPos(1);
                    info.unpack(plugin_status);
                    data->PluginStatusTime.value = time;
                    for (plugin_index = 0; plugin_index < PLUGIN_NULL; plugin_index++)
                        if (!memcmp(p, plugins[plugin_index], sizeof(p)))
                            break;
                    switch (plugin_index){
                    case PLUGIN_FOLLOWME:
                        if (data->FollowMe.value == plugin_status)
                            break;
                        data->FollowMe.value = plugin_status;
                        bChanged = true;
                        break;
                    case PLUGIN_FILESERVER:
                        if ((data->SharedFiles.value != 0) == (plugin_status != 0))
                            break;
                        data->SharedFiles.value = (plugin_status != 0);
                        bChanged = true;
                        break;
                    case PLUGIN_ICQPHONE:
                        if (data->ICQPhone.value == plugin_status)
                            break;
                        data->ICQPhone.value = plugin_status;
                        bChanged = true;
                        break;
                    default:
                        if (plugin_index >= PLUGIN_NULL)
                            log(L_WARN, "Unknown plugin sign");
                    }
                    break;

                }
            }else{
                data->InfoUpdateTime.value   = infoUpdateTime;
                data->PluginInfoTime.value   = pluginInfoTime;
                data->PluginStatusTime.value = pluginStatusTime;
                if (getAutoUpdate()){
                    if (infoUpdateTime == 0)
                        infoUpdateTime = 1;
                    if (infoUpdateTime != data->InfoFetchTime.value)
                        addFullInfoRequest(data->Uin.value);
                    if ((data->PluginInfoTime.value != data->PluginInfoFetchTime.value)){
                        if (data->PluginInfoTime.value)
                            addPluginInfoRequest(data->Uin.value, PLUGIN_QUERYxINFO);
                    }
                    if ((data->PluginInfoTime.value != data->PluginInfoFetchTime.value) ||
                            (data->PluginStatusTime.value != data->PluginStatusFetchTime.value)){
                        if (data->SharedFiles.bValue){
                            data->SharedFiles.bValue = false;
                            bChanged = true;
                        }
                        if (data->FollowMe.value){
                            data->FollowMe.value = 0;
                            bChanged = true;
                        }
                        if (data->ICQPhone.bValue){
                            data->ICQPhone.bValue = false;
                            bChanged = true;
                        }
                        if (data->PluginStatusTime.value)
                            addPluginInfoRequest(data->Uin.value, PLUGIN_QUERYxSTATUS);
                    }
                }
            }
            if (data->bInvisible.bValue){
                data->bInvisible.bValue = false;
                bChanged = true;
            }
            if (bChanged){
                Event e(EventContactChanged, contact);
                e.process();
            }
            if ((data->Status.value != prevStatus) || bAwayChanged){
                unsigned status = STATUS_OFFLINE;
                if ((data->Status.value & 0xFFFF) != ICQ_STATUS_OFFLINE){
                    status = STATUS_ONLINE;
                    if (data->Status.value & ICQ_STATUS_DND){
                        status = STATUS_DND;
                    }else if (data->Status.value & ICQ_STATUS_OCCUPIED){
                        status = STATUS_OCCUPIED;
                    }else if (data->Status.value & ICQ_STATUS_NA){
                        status = STATUS_NA;
                    }else if (data->Status.value & ICQ_STATUS_AWAY){
                        status = STATUS_AWAY;
                    }else if (data->Status.value & ICQ_STATUS_FFC){
                        status = STATUS_FFC;
                    }
                }
                if ((status == STATUS_ONLINE) && (data->Class.value & CLASS_AWAY))
                    status = STATUS_AWAY;
                StatusMessage m;
                m.setContact(contact->id());
                m.setClient(dataName(data).c_str());
                m.setStatus(status);
                m.setFlags(MESSAGE_RECEIVED);
                Event e(EventMessageReceived, &m);
                e.process();
                if (!contact->getIgnore() &&
                        ((data->Class.value & CLASS_AWAY) == 0) &&
                        (((data->Status.value & 0xFF) == ICQ_STATUS_ONLINE) &&
                         (((prevStatus & 0xFF) != ICQ_STATUS_ONLINE)) || bAwayChanged) &&
                        (((prevStatus & 0xFFFF) != ICQ_STATUS_OFFLINE) ||
                         (data->OnlineTime.value > this->data.owner.OnlineTime.value))){
                    Event e(EventContactOnline, contact);
                    e.process();
                }
                if (getAutoReplyUpdate() && ((data->Status.value & 0xFF) != ICQ_STATUS_ONLINE)){
                    if ((getInvisible() && data->VisibleId.value) ||
                            (!getInvisible() && (data->InvisibleId.value == 0)))
                        addPluginInfoRequest(data->Uin.value, PLUGIN_AR);
                }
            }
        }
Exemple #23
0
void ICQClient::snac_buddy(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxBDY_RIGHTSxGRANTED:
        log(L_DEBUG, "Buddy rights granted");
        break;
    case ICQ_SNACxBDY_USEROFFLINE:{
            unsigned long uin = readBuffer.unpackUin();
            ICQUser *user = getUser(uin);
            if (user && (user->uStatus != ICQ_STATUS_OFFLINE)){
                log(L_DEBUG, "User %lu [%s] offline", uin, user->Alias.c_str());
                user->setOffline();
                ICQEvent e(EVENT_STATUS_CHANGED, uin);
                process_event(&e);
            }
            break;
        }
    case ICQ_SNACxBDY_USERONLINE:{
            unsigned long uin = readBuffer.unpackUin();
            if (uin == Uin()) break;
            ICQUser *user = getUser(uin);
            if (user){
                time_t now;
                time(&now);
                bool changed = false;

                unsigned long cookie1, cookie2, cookie3;
                cookie1 = cookie2 = cookie3 = 0;
                unsigned short level, len;
                readBuffer >> level >> len;
                TlvList tlv(readBuffer);

                // Status TLV
                Tlv *tlvStatus = tlv(0x0006);
                if (tlvStatus){
                    unsigned long status = *tlvStatus;
                    log(L_DEBUG, "User %lu [%s] online [%08lX]", uin, user->Alias.c_str(), status);
                    if (status != user->uStatus){
                        user->prevStatus = user->uStatus;
                        user->uStatus = status;
                        if (status & 0xFF){
                            addResponseRequest(uin);
                        }else{
                            user->AutoReply = "";
                        }
                        user->StatusTime = (unsigned long)now;
                        changed = true;
                    }
                }

                // Online time TLV
                Tlv *tlvOnlineTime = tlv(0x0003);
                if (tlvOnlineTime){
                    user->OnlineTime = (unsigned long)(*tlvOnlineTime);
                    changed = true;
                }
                Tlv *tlvNATime = tlv(0x0004);
                if (tlvNATime){
                    user->StatusTime = (unsigned long)now - (unsigned short)(*tlvNATime) * 60L;
                    changed = true;
                }
                // IP TLV
                Tlv *tlvIP = tlv(0x000A);
                if (tlvIP){
                    unsigned long ip = htonl((unsigned long)(*tlvIP));
                    if (user->IP() != ip) user->HostName = "";
                    user->IP = ip;
                    changed = true;
                }

                // Direct connection info
                Tlv *tlvDirect = tlv(0x000C);
                if (tlvDirect){
                    user->ClientType = 0;
                    Buffer info(*tlvDirect);
                    unsigned long  realIP;
                    unsigned short port;
                    char mode, version, junk;
                    info >> realIP;
                    info.incReadPos(2);
                    info >> port;
                    realIP = htonl(realIP);
                    if (user->RealIP != realIP) user->RealHostName ="";
                    user->RealIP = realIP;
                    user->Port = port;
                    info >> mode >> junk >> version >> user->DCcookie;
                    info.incReadPos(8);
                    info
                    >> cookie1
                    >> cookie2
                    >> cookie3;
                    if (cookie3 != user->PhoneBookTime()){
                        user->bPhoneChanged = true;
                        user->PhoneBookTime = cookie3;
                    }
                    user->PhoneStatusTime = cookie2;
                    user->TimeStamp       = cookie1;
                    if (mode == MODE_DENIED) mode = MODE_INDIRECT;
                    if ((mode != MODE_DIRECT) && (mode != MODE_INDIRECT))
                        mode = MODE_INDIRECT;
                    user->Mode = (unsigned short)mode;
                    user->Version = (unsigned short)version;
                    changed = true;
                    if (user->DCcookie == 0)
                        user->ClientType = 4;
                    if ((user->DCcookie == cookie1) && (cookie1 == cookie2))
                        user->ClientType = 5;
                    if (cookie1 == 0x279c6996)
                        user->ClientType = 3;
                }

                Tlv *tlvCapability = tlv(0x000D);
                if (tlvCapability){
                    user->GetRTF = false;
                    Buffer info(*tlvCapability);
                    for (; info.readPos() < info.size(); ){
                        capability cap;
                        info.unpack((char*)cap, sizeof(capability));
                        if (!memcmp(cap, capabilities[1], sizeof(capability))){
                            user->GetRTF = true;
                            if (!user->CanPlugin){
                                if (user->bPhoneChanged) addPhoneRequest(uin);
                                user->CanPlugin = true;
                            }
                        }
                        if (!memcmp(cap, capabilities[3], sizeof(capability)))
                            user->CanResponse = true;
                        if (!memcmp(cap, capabilities[5], sizeof(capability)))
                            user->ClientType = 2;
                        if (!memcmp(cap, capabilities[4], sizeof(capability)))
                            user->ClientType = 1;
                        if (!memcmp(cap, capabilities[4], sizeof(capability)-1) &&
                                (cap[sizeof(capability)-1] > (1 << 6)) &&
                                (cap[sizeof(capability)-1] != 0x92))
                            user->ClientType = (char)(cap[sizeof(capability)-1]);
                    }
                }

                Tlv *tlvPlugin = tlv(0x0011);
                if (tlvPlugin){
                    Buffer info(*tlvPlugin);
                    char reqType;
                    info >> reqType;
                    info.incReadPos(10);
                    capability cap;
                    info.unpack((char*)cap, sizeof(capability));
                    if (user->CanPlugin && !memcmp(cap, PHONEBOOK_SIGN, sizeof(capability))){
                        if (reqType == 3){
                            info.incReadPos(3);
                            info >> user->PhoneState;
                            if (user->bPhoneChanged) addPhoneRequest(uin);
                        }else if (reqType == 2)
                            if (user->bPhoneChanged) addPhoneRequest(uin);
                    }
                    addInfoRequest(uin);
                    changed = true;
                }

                if (changed){
                    ICQEvent e(EVENT_STATUS_CHANGED, uin);
                    process_event(&e);
                    user->prevStatus = user->uStatus;
                }
            }
            break;
        }
void ICQClient::snac_service(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxSRV_PAUSE:
        log(L_DEBUG, "Server pause");
        m_bNoSend = true;
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_PAUSExACK);
        m_socket->writeBuffer << ICQ_SNACxFAM_SERVICE
        << ICQ_SNACxFAM_LOCATION
        << ICQ_SNACxFAM_BUDDY
        << ICQ_SNACxFAM_MESSAGE
        << ICQ_SNACxFAM_BOS
        << ICQ_SNACxFAM_PING
        << ICQ_SNACxFAM_LISTS
        << ICQ_SNACxFAM_VARIOUS
        << ICQ_SNACxFAM_LOGIN;
        sendPacket(true);
        break;
    case ICQ_SNACxSRV_RESUME:
        log(L_DEBUG, "Server resume");
        m_bNoSend = false;
        processSendQueue();
        break;
    case ICQ_SNACxSRV_MIGRATE:{
            log(L_DEBUG, "Server migrate");
            m_bNoSend = true;
            int i;
            unsigned short cnt;
            unsigned short fam[0x17];

            m_socket->readBuffer >> cnt;
            for (i = 0; i < cnt; i++) {
                m_socket->readBuffer >> fam[i];
            }
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlv_adr    = tlv(0x05);
            Tlv *tlv_cookie = tlv(0x06);
            for (; i >= 0; i--) {
                setServiceSocket(tlv_adr,tlv_cookie,fam[i]);
            }
            break;
        }
    case ICQ_SNACxSRV_RATExCHANGE:{
            const char *msg_text = NULL;
            unsigned short msg_code;
            unsigned short class_id;
            unsigned long  window_size;
            unsigned long  clear_level;
            unsigned long  alert_level;
            unsigned long  limit_level;
            unsigned long  discon_level;
            unsigned long  current_level;
            unsigned long  max_level;
            unsigned long  last_send;
            char current_state;
            m_socket->readBuffer >> msg_code
            >> class_id
            >> window_size
            >> clear_level
            >> alert_level
            >> limit_level
            >> discon_level
            >> current_level
            >> max_level
            >> last_send
            >> current_state;
            if (type == ICQ_SNACxSRV_RATExCHANGE){
                switch (msg_code) {
                case 0x0001:
                    msg_text = "Rate limits parameters changed";
                    break;
                case 0x0002:
                    msg_text = "Rate limits warning";
                    break;
                case 0x0003:
                    msg_text = "Rate limit hit";
                    break;
                case 0x0004:
                    msg_text = "Rate limit clear";
                    break;
                default:
                    msg_text = "Unknown";
                }
                log(L_DEBUG, "%s", msg_text);
            }
            log(L_DEBUG, "grp: %02X, ws: %04lX, cl %04lX, al %04lX, ll %04lX, dl: %04lX, cur %04lX, ml %04lX",
                class_id,window_size,clear_level,alert_level,limit_level,discon_level,
                current_level,max_level);
            if (--class_id < m_rates.size()){
                RateInfo &r = m_rates[class_id];
                r.m_winSize  = window_size;
                r.m_maxLevel = max_level;
                r.m_minLevel = alert_level;
                r.m_curLevel = current_level;
                r.m_lastSend = QDateTime::currentDateTime();
                processSendQueue();
            }
            break;
        }
    case ICQ_SNACxSRV_RATExINFO:
        if (m_rates.size() == 0){
            unsigned short n_rates;
            m_socket->readBuffer >> n_rates;
            unsigned n;
            for (n = 0; n < n_rates; n++){
                unsigned short class_id;
                unsigned long  window_size;
                unsigned long  clear_level;
                unsigned long  alert_level;
                unsigned long  limit_level;
                unsigned long  discon_level;
                unsigned long  current_level;
                unsigned long  max_level;
                unsigned long  last_send;
                char current_state;
                m_socket->readBuffer
                >> class_id
                >> window_size
                >> clear_level
                >> alert_level
                >> limit_level
                >> discon_level
                >> current_level
                >> max_level
                >> last_send
                >> current_state;
                log(L_DEBUG, "grp: %02X, ws: %04lX, cl %04lX, al %04lX, ll %04lX, dl: %04lX, cur %04lX, ml %04lX",
                    class_id,window_size,clear_level,alert_level,limit_level,discon_level,
                    current_level,max_level);
                RateInfo r;
                r.m_winSize		= window_size;
                r.m_minLevel	= alert_level;
                r.m_maxLevel	= max_level;
                r.m_curLevel	= current_level;
                r.m_lastSend	= QDateTime::currentDateTime();
                m_rates.push_back(r);
            }
            for (n = 0; n < n_rates; n++){
                unsigned short class_id;
                unsigned short pairs;
                m_socket->readBuffer
                >> class_id
                >> pairs;
                class_id--;
                for (unsigned i = 0; i < pairs; i++){
                    unsigned long snac;
                    m_socket->readBuffer >> snac;
                    if (class_id >= m_rates.size())
                        continue;
                    RATE_MAP::iterator it = m_rate_grp.find(snac);
                    if (it != m_rate_grp.end())
                        continue;
                    m_rate_grp.insert(RATE_MAP::value_type(snac, class_id));
                }
            }
            snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK);
            m_socket->writeBuffer << 0x00010002L << 0x00030004L << 0x0005;
            sendPacket(true);
            snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO);
            sendPacket(true);
            listsRequest();
            locationRequest();
            buddyRequest();
            icmbRequest();
            bosRequest();
        }
        break;
    case ICQ_SNACxSRV_MOTD:
        break;
    case ICQ_SNACxSRV_ACKxIMxICQ:
        snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO);
        sendPacket(true);
        break;
    case ICQ_SNACxSRV_NAMExINFO:{
            string screen = m_socket->readBuffer.unpackScreen();
            if (screen.length() == 0){
                char n;
                m_socket->readBuffer >> n;
                m_socket->readBuffer.incReadPos(n);
                screen = m_socket->readBuffer.unpackScreen();
            }
            if ((unsigned)atol(screen.c_str()) != data.owner.Uin.value){
                log(L_WARN, "No my name info (%s)", screen.c_str());
                break;
            }
            m_socket->readBuffer.incReadPos(4);
            TlvList tlv(m_socket->readBuffer);
            Tlv *tlvIP = tlv(0x000A);
            if (tlvIP)
                set_ip(&data.owner.IP, htonl((unsigned long)(*tlvIP)));
            break;
        }
Exemple #25
0
void ICQClientPrivate::snac_buddy(unsigned short type, unsigned short)
{
    switch (type){
    case ICQ_SNACxBDY_RIGHTSxGRANTED:
        log(L_DEBUG, "Buddy rights granted");
        break;
    case ICQ_SNACxBDY_USEROFFLINE:{
            unsigned long uin = sock->readBuffer.unpackUin();
            ICQUser *user = client->getUser(uin);
            if (user && (user->uStatus != ICQ_STATUS_OFFLINE)){
                log(L_DEBUG, "User %lu [%s] offline", uin, user->Alias.c_str());
                user->setOffline();
                ICQEvent e(EVENT_STATUS_CHANGED, uin);
                client->process_event(&e);
            }
            break;
        }
    case ICQ_SNACxBDY_USERONLINE:{
            unsigned long uin = sock->readBuffer.unpackUin();
            if (uin == client->owner->Uin) break;
            ICQUser *user = client->getUser(uin);
            if (user){
                time_t now;
                time(&now);
                bool changed = false;

                if (user->uStatus == ICQ_STATUS_OFFLINE)
                    user->Caps = 0;

                unsigned long cookie1, cookie2, cookie3;
                cookie1 = cookie2 = cookie3 = 0;
                unsigned short level, len;
                sock->readBuffer >> level >> len;
                TlvList tlv(sock->readBuffer);

                // Status TLV
                Tlv *tlvStatus = tlv(0x0006);
                if (tlvStatus){
                    unsigned long status = *tlvStatus;
                    log(L_DEBUG, "User %lu [%s] online [%08lX]", uin, user->Alias.c_str(), status);
                    if (status != user->uStatus){
                        user->prevStatus = user->uStatus;
                        user->uStatus = status;
                        if (status & 0xFF){
                            client->addResponseRequest(uin);
                        }else{
                            user->AutoReply = "";
                        }
                        user->StatusTime = (unsigned long)now;
                        changed = true;
                    }
                }else if (user->uStatus == ICQ_STATUS_OFFLINE){
                    user->uStatus = ICQ_STATUS_ONLINE;
                }

                // Online time TLV
                Tlv *tlvOnlineTime = tlv(0x0003);
                if (tlvOnlineTime){
                    user->OnlineTime = (unsigned long)(*tlvOnlineTime);
                    changed = true;
                }
                Tlv *tlvNATime = tlv(0x0004);
                if (tlvNATime){
                    user->StatusTime = (unsigned long)now - (unsigned short)(*tlvNATime) * 60L;
                    changed = true;
                }
                // IP TLV
                Tlv *tlvIP = tlv(0x000A);
                if (tlvIP){
                    unsigned long ip = htonl((unsigned long)(*tlvIP));
                    if (user->IP != ip) user->HostName = "";
                    user->IP = ip;
                    log(L_DEBUG, "IP %s %lu", user->Alias.c_str(), user->IP);
                    changed = true;
                }

                // Direct connection info
                Tlv *tlvDirect = tlv(0x000C);
                if (tlvDirect){
                    Buffer info(*tlvDirect);
                    unsigned long  realIP;
                    unsigned short port;
                    char mode, version, junk;
                    info >> realIP;
                    info.incReadPos(2);
                    info >> port;
                    realIP = htonl(realIP);
                    if (user->RealIP != realIP) user->RealHostName ="";
                    user->RealIP = realIP;
                    user->Port = port;
                    info >> mode >> junk >> version >> user->DCcookie;
                    info.incReadPos(8);
                    info
                    >> cookie1
                    >> cookie2
                    >> cookie3;
                    if (cookie3 != user->PhoneBookTime){
                        user->bPhoneChanged = true;
                        user->PhoneBookTime = cookie3;
                    }
                    user->PhoneStatusTime = cookie2;
                    user->InfoUpdateTime  = cookie1;
                    if (mode == MODE_DENIED) mode = MODE_INDIRECT;
                    if ((mode != MODE_DIRECT) && (mode != MODE_INDIRECT))
                        mode = MODE_INDIRECT;
                    user->Mode = (unsigned short)mode;
                    user->Version = (unsigned short)version;
                    changed = true;
                }

                Tlv *tlvCapability = tlv(0x000D);
                if (tlvCapability){
                    Buffer info(*tlvCapability);
                    for (; info.readPos() < info.size(); ){
                        capability cap;
                        info.unpack((char*)cap, sizeof(capability));
                        for (unsigned i = 0;; i++){
                            if (*capabilities[i] == 0) break;
                            unsigned size = sizeof(capability);
                            if (i == CAP_SIM) size--;
                            if (i == CAP_MICQ) size -= 4;
                            if (!memcmp(cap, capabilities[i], size)){
                                if (i == CAP_SIM){
                                    unsigned char build = cap[sizeof(capability)-1];
                                    log(L_DEBUG, "Build: %X %u", build, build);
                                    if (build && ((build == 0x92) || (build < (1 << 6)))) continue;
                                    user->Build = build;
                                }
                                if (i == CAP_MICQ){
                                    unsigned char *p = (unsigned char*)cap;
                                    p += 12;
                                    user->Build = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
                                }
                                user->Caps |= (1 << i);
                            }
                        }
                    }
                    if (user->hasCap(CAP_RTF) && !user->CanPlugin){
                        user->CanPlugin = true;
                        if (user->bPhoneChanged) client->addPhoneRequest(uin);
                    }
                }

                Tlv *tlvPlugin = tlv(0x0011);
                if (tlvPlugin){
                    Buffer info(*tlvPlugin);
                    char reqType;
                    info >> reqType;
                    info.incReadPos(10);
                    capability cap;
                    info.unpack((char*)cap, sizeof(capability));
                    if (user->CanPlugin && !memcmp(cap, PHONEBOOK_SIGN, sizeof(capability))){
                        if (reqType == 3){
                            info.incReadPos(3);
                            info >> user->PhoneState;
                            if (user->bPhoneChanged) client->addPhoneRequest(uin);
                        }else if (reqType == 2)
                            if (user->bPhoneChanged) client->addPhoneRequest(uin);
                    }
                    client->addInfoRequest(uin);
                    changed = true;
                }

                if (changed){
                    ICQEvent e(EVENT_STATUS_CHANGED, uin);
                    client->process_event(&e);
                    user->prevStatus = user->uStatus;
                }
            }
            break;
        }