示例#1
0
void __cdecl CIcqProto::KeepAliveThread(void *arg)
{
	serverthread_info *info = (serverthread_info*)arg;
	icq_packet packet;
	DWORD dwInterval = getDword("KeepAliveInterval", KEEPALIVE_INTERVAL);

	debugLogA("Keep alive thread starting.");

	info->hKeepAliveEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

	for (;;)
	{
		DWORD dwWait = ICQWaitForSingleObject(info->hKeepAliveEvent, dwInterval);
		if (serverThreadHandle == NULL) // connection lost, end
			break;
		if (dwWait == WAIT_TIMEOUT)
		{
			// Send a keep alive packet to server
			packet.wLen = 0;
			write_flap(&packet, ICQ_PING_CHAN);
			sendServPacket(&packet);
		}
		else if (dwWait == WAIT_IO_COMPLETION)
			// Possible shutdown in progress
			if (Miranda_Terminated()) break;
			else
				break;
	}

	debugLogA("Keep alive thread ended.");

	CloseHandle(info->hKeepAliveEvent);
	info->hKeepAliveEvent = NULL;
}
示例#2
0
void CIcqProto::sendClientAuth(const char *szKey, size_t wKeyLen, BOOL bSecure)
{
	char szUin[UINMAXLEN];
	icq_packet packet;

	size_t wUinLen = mir_strlen(strUID(m_dwLocalUIN, szUin));

	packet.wLen = WORD((m_bLegacyFix ? 65 : 70) + sizeof(CLIENT_ID_STRING) + wUinLen + wKeyLen + (m_bSecureConnection ? 4 : 0));

	if (bSecure) {
		serverPacketInit(&packet, packet.wLen + 10);
		packFNACHeader(&packet, ICQ_AUTHORIZATION_FAMILY, ICQ_SIGNON_LOGIN_REQUEST, 0, 0);
	}
	else {
		write_flap(&packet, ICQ_LOGIN_CHAN);
		packDWord(&packet, 0x00000001);
	}
	packTLV(&packet, 0x0001, wUinLen, (LPBYTE)szUin);

	if (bSecure) { // Pack MD5 auth digest
		packTLV(&packet, 0x0025, wKeyLen, (BYTE*)szKey);
		packDWord(&packet, 0x004C0000); // empty TLV(0x4C): unknown
	}
	else { // Pack old style password hash
		BYTE hash[20];

		icq_encryptPassword(szKey, hash);
		packTLV(&packet, 0x0002, wKeyLen, hash);
	}

	// Pack client identification details.
	packTLV(&packet, 0x0003, (WORD)sizeof(CLIENT_ID_STRING)-1, (LPBYTE)CLIENT_ID_STRING);
	packTLVWord(&packet, 0x0017, CLIENT_VERSION_MAJOR);
	packTLVWord(&packet, 0x0018, CLIENT_VERSION_MINOR);
	packTLVWord(&packet, 0x0019, CLIENT_VERSION_LESSER);
	packTLVWord(&packet, 0x001a, CLIENT_VERSION_BUILD);
	packTLVWord(&packet, 0x0016, CLIENT_ID_CODE);
	packTLVDWord(&packet, 0x0014, CLIENT_DISTRIBUTION);
	packTLV(&packet, 0x000f, 0x0002, (LPBYTE)CLIENT_LANGUAGE);
	packTLV(&packet, 0x000e, 0x0002, (LPBYTE)CLIENT_COUNTRY);
	if (!m_bLegacyFix)
		packTLV(&packet, 0x0094, 0x0001, &m_bConnectionLost); // CLIENT_RECONNECT flag
	if (m_bSecureConnection)
		packDWord(&packet, 0x008C0000); // empty TLV(0x8C): use SSL

	sendServPacket(&packet);
}
示例#3
0
void __fastcall serverCookieInit(icq_packet *pPacket, BYTE *pCookie, WORD wCookieSize)
{
	pPacket->wLen = (WORD)(wCookieSize + 8 + sizeof(CLIENT_ID_STRING) + 66);

	write_flap(pPacket, ICQ_LOGIN_CHAN);
	packDWord(pPacket, 0x00000001);
	packTLV(pPacket, 0x06, wCookieSize, pCookie);

	// Pack client identification details.
	packTLV(pPacket, 0x0003, (WORD)sizeof(CLIENT_ID_STRING)-1, (LPBYTE)CLIENT_ID_STRING);
	packTLVWord(pPacket, 0x0017, CLIENT_VERSION_MAJOR);
	packTLVWord(pPacket, 0x0018, CLIENT_VERSION_MINOR);
	packTLVWord(pPacket, 0x0019, CLIENT_VERSION_LESSER);
	packTLVWord(pPacket, 0x001a, CLIENT_VERSION_BUILD);
	packTLVWord(pPacket, 0x0016, CLIENT_ID_CODE);
	packTLVDWord(pPacket, 0x0014, CLIENT_DISTRIBUTION);
	packTLV(pPacket, 0x000f, 0x0002, (LPBYTE)CLIENT_LANGUAGE);
	packTLV(pPacket, 0x000e, 0x0002, (LPBYTE)CLIENT_COUNTRY);
	packDWord(pPacket, 0x00940001); // reconnect flag
	packByte(pPacket, 0);
	packTLVDWord(pPacket, 0x8003, 0x00100000); // Unknown
}
示例#4
0
void avatars_server_connection::connectionThread()
{
	// This is the "infinite" loop that receives the packets from the ICQ avatar server
	NETLIBPACKETRECVER packetRecv = { 0 };
	DWORD dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL;

	hPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)hConnection, 65536);
	packetRecv.cbSize = sizeof(packetRecv);
	packetRecv.dwTimeout = 1000; // timeout - for stopThread to work
	while (!stopThread) {
		int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hPacketRecver, (LPARAM)&packetRecv);
		if (recvResult == 0) {
			ppro->debugLogA("Clean closure of avatar socket");
			break;
		}

		if (recvResult == SOCKET_ERROR) {
			if (GetLastError() == ERROR_TIMEOUT) {  // timeout, check if we should be still running
				if (Miranda_Terminated())
					break;

				if (time(0) >= dwLastKeepAlive) { // limit frequency (HACK: on some systems select() does not work well)
					if (!ppro->m_bGatewayMode && ppro->getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED)) { // send keep-alive packet
						icq_packet packet;
						packet.wLen = 0;
						write_flap(&packet, ICQ_PING_CHAN);
						sendServerPacket(&packet);
					}
					dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL;
				}

				// check if we got something to request
				checkRequestQueue();
				continue;
			}
			if (!stopThread)
				ppro->debugLogA("Avatar socket closed abortively, error: %d", GetLastError());
			else
				ppro->debugLogA("Avatar socket gracefully closed.");
			break;
		}

		// Deal with the packet
		packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable);

		if (isActive && (packetRecv.bytesAvailable == packetRecv.bytesUsed)) // no packets pending
			checkRequestQueue(); // process request queue
	}
	{
		// release connection
		mir_cslock l(localSeqMutex);
		NetLib_SafeCloseHandle(&hPacketRecver); // Close the packet receiver
		NetLib_CloseConnection(&hConnection, FALSE); // Close the connection
	}
	{
		// release rates
		mir_cslock l(m_ratesMutex);
		delete m_rates; m_rates = NULL;
	}

	SAFE_FREE((void**)&pCookie);
}
示例#5
0
void __fastcall serverPacketInit(icq_packet *pPacket, WORD wSize)
{
	pPacket->wLen = wSize;
	write_flap(pPacket, ICQ_DATA_CHAN);
}
示例#6
0
void avatars_server_connection::connectionThread()
{
	// This is the "infinite" loop that receives the packets from the ICQ avatar server
	NETLIBPACKETRECVER packetRecv = {0};
	DWORD wLastKeepAlive = 0; // we send keep-alive at most one per 30secs
	DWORD dwKeepAliveInterval = ppro->getDword("KeepAliveInterval", KEEPALIVE_INTERVAL);

	hPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)hConnection, 65536);
	packetRecv.cbSize = sizeof(packetRecv);
	packetRecv.dwTimeout = dwKeepAliveInterval < KEEPALIVE_INTERVAL ? dwKeepAliveInterval: KEEPALIVE_INTERVAL; // timeout - for stopThread to work
	while (!stopThread)
	{
		int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hPacketRecver, (LPARAM)&packetRecv);

		if (recvResult == 0)
		{
			ppro->debugLogA("Clean closure of server socket");
			break;
		}

		if (recvResult == SOCKET_ERROR)
		{
			if (GetLastError() == ERROR_TIMEOUT)
			{  // timeout, check if we should be still running
				if (Miranda_Terminated())
				{ // we must stop here, cause due to a hack in netlib, we always get timeout, even if the connection is already dead
					stopThread = 1;
					continue;
				}
#ifdef _DEBUG
				else ppro->debugLogA("Thread is Idle.");
#endif
				if (GetTickCount() > wLastKeepAlive)
				{ // limit frequency (HACK: on some systems select() does not work well)
					if (!ppro->m_bGatewayMode && ppro->getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED))
					{ // send keep-alive packet
						icq_packet packet;

						packet.wLen = 0;
						write_flap(&packet, ICQ_PING_CHAN);
						sendServerPacket(&packet);
					}
					wLastKeepAlive = GetTickCount() + dwKeepAliveInterval;
				}
				else
				{ // this is bad, the system does not handle select() properly
#ifdef _DEBUG
					ppro->debugLogA("Thread is Forcing Idle.");
#endif
					SleepEx(500, TRUE); // wait some time, can we do anything else ??
					if (Miranda_Terminated())
					{
						stopThread = 1;
						continue;
					}
				}
				// check if we got something to request
				checkRequestQueue();
				continue;
			}
			if (!stopThread)
				ppro->debugLogA("Abortive closure of server socket, error: %d", GetLastError());
			else
				ppro->debugLogA("Connection closed.");
			break;
		}

		// Deal with the packet
		packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable);

		if (isActive && (packetRecv.bytesAvailable == packetRecv.bytesUsed)) // no packets pending
		{ // process request queue
			checkRequestQueue();
		}
	}
	{ // release connection
		icq_lock l(localSeqMutex);
		NetLib_SafeCloseHandle(&hPacketRecver); // Close the packet receiver
		NetLib_CloseConnection(&hConnection, FALSE); // Close the connection
	}

	{ // release rates
		icq_lock l(m_ratesMutex);
		SAFE_DELETE((MZeroedObject**)&m_rates);
	}

	SAFE_FREE((void**)&pCookie);
}
示例#7
0
void CIcqProto::handleLoginChannel(BYTE *buf, WORD datalen, serverthread_info *info)
{
	icq_packet packet;

#ifdef _DEBUG
  NetLog_Server("Received SRV_HELLO from %s", info->isLoginServer ? "login server" : "communication server");
#endif

	// isLoginServer is "1" if we just received SRV_HELLO
	if (info->isLoginServer)
	{
		if (m_bSecureLogin)
		{
			char szUin[UINMAXLEN];
			WORD wUinLen;

#ifdef _DEBUG
			NetLog_Server("Sending %s to %s", "CLI_HELLO", "login server");
#endif
			packet.wLen = 12;
			write_flap(&packet, ICQ_LOGIN_CHAN);
			packDWord(&packet, 0x00000001);
			packTLVDWord(&packet, 0x8003, 0x00100000); // unknown
			sendServPacket(&packet);  // greet login server

			wUinLen = strlennull(strUID(m_dwLocalUIN, szUin));
#ifdef _DEBUG
			NetLog_Server("Sending %s to %s", "ICQ_SIGNON_AUTH_REQUEST", "login server");
#endif

			serverPacketInit(&packet, (WORD)(14 + wUinLen));
			packFNACHeader(&packet, ICQ_AUTHORIZATION_FAMILY, ICQ_SIGNON_AUTH_REQUEST, 0, 0);
			packTLV(&packet, 0x0001, wUinLen, (LPBYTE)szUin);
			sendServPacket(&packet);  // request login digest
		}
		else
		{
			sendClientAuth((char*)info->szAuthKey, info->wAuthKeyLen, FALSE);
#ifdef _DEBUG
			NetLog_Server("Sent CLI_IDENT to %s", "login server");
#endif
		}

		info->isLoginServer = 0;
		if (info->cookieDataLen)
		{
			SAFE_FREE((void**)&info->cookieData);
			info->cookieDataLen = 0;
		}
	}
	else 
	{
		if (info->cookieDataLen)
		{
			wLocalSequence = generate_flap_sequence();

			serverCookieInit(&packet, info->cookieData, (WORD)info->cookieDataLen);
			sendServPacket(&packet);

#ifdef _DEBUG
			NetLog_Server("Sent CLI_IDENT to %s", "communication server");
#endif

			SAFE_FREE((void**)&info->cookieData);
			info->cookieDataLen = 0;
		}
		else
		{
			// We need a cookie to identify us to the communication server
      NetLog_Server("Error: Connected to %s without a cookie!", "communication server");
		}
	}
}