Пример #1
0
void CIcqProto::handleXtrazNotifyResponse(DWORD dwUin, MCONTACT hContact, WORD wCookie, char* szMsg, int nMsgLen)
{
	char *szMem, *szRes, *szEnd;
	int nResLen;

#ifdef _DEBUG
	debugLogA("Received Xtraz Notify Response");
#endif

	szRes = strstrnull(szMsg, "<RES>");
	szEnd = strstrnull(szMsg, "</RES>");

	if (szRes && szEnd) { // valid response
		char *szNode, *szWork;

		szRes += 5;
		nResLen = szEnd - szRes;

		szMem = szRes = DemangleXml(szRes, nResLen);

#ifdef _DEBUG
		debugLogA("Response: %s", szRes);
#endif

		ProtoBroadcastAck(hContact, ICQACKTYPE_XTRAZNOTIFY_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, (LPARAM)szRes);

	NextVal:
		szNode = strstrnull(szRes, "<val srv_id=");
		if (szNode) szEnd = strstrnull(szNode, ">"); else szEnd = NULL;

		if (szNode && szEnd) {
			*(szEnd - 1) = '\0';
			szNode += 13; //one more than the length of the string to skip ' or " too
			szWork = szEnd + 1;

			if (!stricmpnull(szNode, "cAwaySrv")) {
				int bChanged = FALSE;

				*szEnd = ' ';
				szNode = strstrnull(szWork, "<index>");
				szEnd = strstrnull(szWork, "</index>");
				if (szNode && szEnd) {
					szNode += 7;
					*szEnd = '\0';
					if (atoi(szNode) != getContactXStatus(hContact)) { // this is strange - but go on
						debugLogA("Warning: XStatusIds do not match!");
					}
					*szEnd = ' ';
				}
				szNode = strstrnull(szWork, "<title>");
				szEnd = strstrnull(szWork, "</title>");
				if (szNode && szEnd) { // we got XStatus title, save it
					char *szXName, *szOldXName;
					szNode += 7;
					*szEnd = '\0';
					szXName = DemangleXml(szNode, strlennull(szNode));
					// check if the name changed
					szOldXName = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, NULL);
					if (strcmpnull(szOldXName, szXName))
						bChanged = TRUE;
					SAFE_FREE(&szOldXName);
					db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, szXName);
					SAFE_FREE(&szXName);
					*szEnd = ' ';
				}
				szNode = strstrnull(szWork, "<desc>");
				szEnd = strstrnull(szWork, "</desc>");
				if (szNode && szEnd) { // we got XStatus mode msg, save it
					char *szXMsg, *szOldXMsg;
					szNode += 6;
					*szEnd = '\0';
					szXMsg = DemangleXml(szNode, strlennull(szNode));
					// check if the decription changed
					szOldXMsg = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, NULL);
					if (strcmpnull(szOldXMsg, szXMsg))
						bChanged = TRUE;
					SAFE_FREE(&szOldXMsg);
					db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_MSG, szXMsg);
					SAFE_FREE(&szXMsg);
				}
				ProtoBroadcastAck(hContact, ICQACKTYPE_XSTATUS_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
			}
			else {
				char *szSrvEnd = strstrnull(szEnd, "</srv>");

				if (szSrvEnd && strstrnull(szSrvEnd, "<val srv_id=")) { // check all values !
					szRes = szSrvEnd + 6; // after first value
					goto NextVal;
				}
				// no next val, we were unable to handle packet, write error
				debugLogA("Error: Unknown serverId \"%s\" in Xtraz response", szNode);
			}
		}
		else
			debugLogA("Error: Missing serverId in Xtraz response");

		SAFE_FREE(&szMem);
	}
	else
		debugLogA("Error: Invalid Xtraz Notify response");
}
Пример #2
0
void CIcqProto::handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szMsg, int nMsgLen, BOOL bThruDC)
{
	char *szNotify = strstrnull(szMsg, "<NOTIFY>");
	char *szQuery = strstrnull(szMsg, "<QUERY>");

	MCONTACT hContact = HContactFromUIN(dwUin, NULL);
	if (hContact) // user sent us xtraz, he supports it
		SetContactCapabilities(hContact, CAPF_XTRAZ);

	if (szNotify && szQuery) { // valid request
		char *szWork, *szEnd;
		int nNotifyLen, nQueryLen;

		szNotify += 8;
		szQuery += 7;
		szEnd = strstrnull(szMsg, "</NOTIFY>");
		if (!szEnd) szEnd = szMsg + nMsgLen;
		nNotifyLen = (szEnd - szNotify);
		szEnd = strstrnull(szMsg, "</QUERY>");
		if (!szEnd) szEnd = szNotify;
		szNotify = DemangleXml(szNotify, nNotifyLen);
		nQueryLen = (szEnd - szQuery);
		szQuery = DemangleXml(szQuery, nQueryLen);
		szWork = strstrnull(szQuery, "<PluginID>");
		szEnd = strstrnull(szQuery, "</PluginID>");
#ifdef _DEBUG
		debugLogA("Query: %s", szQuery);
		debugLogA("Notify: %s", szNotify);
#endif
		if (szWork && szEnd) { // this is our plugin
			szWork += 10;
			*szEnd = '\0';

			if (!stricmpnull(szWork, "srvMng") && strstrnull(szNotify, "AwayStat")) {
				char *szSender = strstrnull(szNotify, "<senderId>");
				char *szEndSend = strstrnull(szNotify, "</senderId>");

				if (szSender && szEndSend) {
					szSender += 10;
					*szEndSend = '\0';

					if ((DWORD)atoi(szSender) == dwUin) {
						BYTE dwXId = m_bXStatusEnabled ? getContactXStatus(NULL) : 0;

						if (dwXId && validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY)) { // apply privacy rules
							NotifyEventHooks(m_modeMsgsEvent, (WPARAM)MTYPE_SCRIPT_NOTIFY, (LPARAM)dwUin);

							char *tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_NAME, "");
							char *szXName = MangleXml(tmp, strlennull(tmp));
							SAFE_FREE(&tmp);

							tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, "");
							char *szXMsg = MangleXml(tmp, strlennull(tmp));
							SAFE_FREE(&tmp);

							int nResponseLen = 212 + strlennull(szXName) + strlennull(szXMsg) + UINMAXLEN + 2;
							char *szResponse = (char*)_alloca(nResponseLen + 1);
							// send response
							mir_snprintf(szResponse, nResponseLen,
								"<ret event=\"OnRemoteNotification\">"
								"<srv><id>cAwaySrv</id>"
								"<val srv_id=\"cAwaySrv\"><Root>"
								"<CASXtraSetAwayMessage></CASXtraSetAwayMessage>"
								"<uin>%d</uin>"
								"<index>%d</index>"
								"<title>%s</title>"
								"<desc>%s</desc></Root></val></srv></ret>",
								m_dwLocalUIN, dwXId, szXName, szXMsg);

							SAFE_FREE(&szXName);
							SAFE_FREE(&szXMsg);

							struct rates_xstatus_response : public rates_queue_item {
							protected:
								virtual rates_queue_item* copyItem(rates_queue_item *aDest = NULL)
								{
									rates_xstatus_response *pDest = (rates_xstatus_response*)aDest;
									if (!pDest)
										pDest = new rates_xstatus_response(ppro, wGroup);

									pDest->bThruDC = bThruDC;
									pDest->dwMsgID1 = dwMsgID1;
									pDest->dwMsgID2 = dwMsgID2;
									pDest->wCookie = wCookie;
									pDest->szResponse = null_strdup(szResponse);

									return rates_queue_item::copyItem(pDest);
								};
							public:
								rates_xstatus_response(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup), szResponse(NULL) {};
								virtual ~rates_xstatus_response() { if (bCreated) SAFE_FREE(&szResponse); };

								virtual void execute()
								{
									ppro->SendXtrazNotifyResponse(dwUin, dwMsgID1, dwMsgID2, wCookie, szResponse, strlennull(szResponse), bThruDC);
								};

								BOOL bThruDC;
								DWORD dwMsgID1;
								DWORD dwMsgID2;
								WORD wCookie;
								char *szResponse;
							};

							m_ratesMutex->Enter();
							WORD wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE);
							m_ratesMutex->Leave();

							rates_xstatus_response rr(this, wGroup);
							rr.hContact = hContact;
							rr.dwUin = dwUin;
							rr.bThruDC = bThruDC;
							rr.dwMsgID1 = dwMID;
							rr.dwMsgID2 = dwMID2;
							rr.wCookie = wCookie;
							rr.szResponse = szResponse;

							handleRateItem(&rr, RQT_RESPONSE, 0, !bThruDC);
						}
						else if (dwXId)
							debugLogA("Privacy: Ignoring XStatus request");
						else
							debugLogA("Error: We are not in XStatus, skipping");
					}
					else
						debugLogA("Error: Invalid sender information");
				}
				else
					debugLogA("Error: Missing sender information");
			}
			else
				debugLogA("Error: Unknown plugin \"%s\" in Xtraz message", szWork);
		}
		else
			debugLogA("Error: Missing PluginID in Xtraz message");

		SAFE_FREE(&szNotify);
		SAFE_FREE(&szQuery);
	}
	else
		debugLogA("Error: Invalid Xtraz Notify message");
}
Пример #3
0
static INT_PTR CALLBACK DlgProcIcqOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA );

	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);

		ppro = (CIcqProto*)lParam;
		SetWindowLongPtr( hwndDlg, GWLP_USERDATA, lParam );
		{
			DWORD dwUin = ppro->getContactUin(NULL);
			if (dwUin)
				SetDlgItemInt(hwndDlg, IDC_ICQNUM, dwUin, FALSE);
			else // keep it empty when no UIN entered
				SetDlgItemTextA(hwndDlg, IDC_ICQNUM, "");

			SendDlgItemMessage(hwndDlg, IDC_PASSWORD, EM_LIMITTEXT, PASSWORDMAXLEN - 1, 0);

			// bit of a security hole here, since it's easy to extract a password from an edit box
			char pszPwd[PASSWORDMAXLEN];
			if (ppro->GetUserStoredPassword(pszPwd, sizeof(pszPwd)))
				SetDlgItemTextA(hwndDlg, IDC_PASSWORD, pszPwd);

			LoadDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection", DEFAULT_SECURE_CONNECTION);
			LoadDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin", DEFAULT_SECURE_LOGIN);
			LoadDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix", DEFAULT_LEGACY_FIX);

			char szServer[MAX_PATH];
			if (!ppro->getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH))
				SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, szServer);
			else
				SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST);

			SetDlgItemInt(hwndDlg, IDC_ICQPORT, ppro->getWord("OscarPort", IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT), FALSE);
			LoadDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive", DEFAULT_KEEPALIVE_ENABLED);
			SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETRANGE, FALSE, MAKELONG(0, 4));
			SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETPOS, TRUE, 4-ppro->getByte("ShowLogLevel", LOG_WARNING));
			SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateTS(szLogLevelDescr[4-SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)]));
			ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_HIDE);
			LoadDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox", 0);
		}
		return TRUE;

	case WM_HSCROLL:
		SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateTS(szLogLevelDescr[4-SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL,TBM_GETPOS, 0, 0)]));
		OptDlgChanged(hwndDlg);
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_LOOKUPLINK:
			CallService(MS_UTILS_OPENURL, 1, (LPARAM)URL_FORGOT_PASSWORD);
			return TRUE;

		case IDC_NEWUINLINK:
			CallService(MS_UTILS_OPENURL, 1, (LPARAM)URL_REGISTER);
			return TRUE;

		case IDC_RESETSERVER:
			SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE);

		case IDC_SSL:
			SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST);
			SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE);
			OptDlgChanged(hwndDlg);
			return TRUE;
		}

		if (ppro->icqOnline() && LOWORD(wParam) != IDC_NOERRMULTI) {
			char szClass[80];
			GetClassNameA((HWND)lParam, szClass, sizeof(szClass));

			if (stricmpnull(szClass, "EDIT") || HIWORD(wParam) == EN_CHANGE)
				ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_SHOW);
		}

		if ((LOWORD(wParam)==IDC_ICQNUM || LOWORD(wParam)==IDC_PASSWORD || LOWORD(wParam)==IDC_ICQSERVER || LOWORD(wParam)==IDC_ICQPORT) &&
			(HIWORD(wParam)!=EN_CHANGE || (HWND)lParam!=GetFocus()))
		{
			return 0;
		}

		OptDlgChanged(hwndDlg);
		break;

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->code) {
		case PSN_APPLY:
			char str[128];

			ppro->setDword(UNIQUEIDSETTING, GetDlgItemInt(hwndDlg, IDC_ICQNUM, NULL, FALSE));
			GetDlgItemTextA(hwndDlg, IDC_PASSWORD, str, sizeof(ppro->m_szPassword));
			if (strlennull(str)) {
				strcpy(ppro->m_szPassword, str);
				ppro->m_bRememberPwd = TRUE;
			}
			else ppro->m_bRememberPwd = ppro->getByte("RememberPass", 0);
			ppro->setString("Password", str);

			GetDlgItemTextA(hwndDlg,IDC_ICQSERVER, str, sizeof(str));
			ppro->setString("OscarServer", str);

			ppro->setWord("OscarPort", (WORD)GetDlgItemInt(hwndDlg, IDC_ICQPORT, NULL, FALSE));

			StoreDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive");
			StoreDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection");
			StoreDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin");
			StoreDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix");
			StoreDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox");
			ppro->setByte("ShowLogLevel", (BYTE)(4-SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)));
			return TRUE;
		}
		break;
	}

	return FALSE;
}