Example #1
0
void DoOpenUrl(LPSTR tokenResp, LPSTR url)
{
	ptrA encodedUrl(mir_urlEncode(url)), encodedToken(mir_urlEncode(tokenResp));
	size_t size = mir_strlen(TOKEN_AUTH_URL) + 1 + mir_strlen(encodedToken) + mir_strlen(encodedUrl);
	LPSTR composedUrl = (LPSTR)alloca(size);
	mir_snprintf(composedUrl, size, TOKEN_AUTH_URL, encodedToken, encodedUrl);
	Utils_OpenUrl(composedUrl);
}
Example #2
0
LPSTR MakeRequest(HANDLE hUser, LPSTR reqUrl, LPSTR reqParamsFormat, LPSTR p1, LPSTR p2)
{
	ptrA encodedP1(mir_urlEncode(p1)), encodedP2(mir_urlEncode(p2));
	size_t size = mir_strlen(reqParamsFormat) + 1 + mir_strlen(encodedP1) + mir_strlen(encodedP2);
	LPSTR reqParams = (LPSTR)alloca(size);
	mir_snprintf(reqParams, size, reqParamsFormat, encodedP1, encodedP2);
	return HttpPost(hUser, reqUrl, reqParams);
}
Example #3
0
int ThreadData::sendMessage(int msgType, const char* email, int netId, const char* parMsg, int parFlags)
{
	char buf[2048];
	int off;

	off = mir_snprintf(buf, sizeof(buf), "MIME-Version: 1.0\r\n");

	if ((parFlags & MSG_DISABLE_HDR) == 0) {
		char  tFontName[100], tFontStyle[3];
		DWORD tFontColor;

		strcpy(tFontName, "Arial");

		if (proto->getByte("SendFontInfo", 1)) {
			char* p;

			DBVARIANT dbv;
			if (!db_get_s(NULL, "SRMsg", "Font0", &dbv)) {
				for (p = dbv.pszVal; *p; p++)
					if (BYTE(*p) >= 128 || *p < 32)
						break;

				if (*p == 0) {
					strncpy_s(tFontName, sizeof(tFontName), ptrA(mir_urlEncode(dbv.pszVal)), _TRUNCATE);
					db_free(&dbv);
				}
			}

			int  tStyle = db_get_b(NULL, "SRMsg", "Font0Sty", 0);
			p = tFontStyle;
			if (tStyle & 1) *p++ = 'B';
			if (tStyle & 2) *p++ = 'I';
			*p = 0;

			tFontColor = db_get_dw(NULL, "SRMsg", "Font0Col", 0);
		}
		else {
			tFontColor = 0;
			tFontStyle[0] = 0;
		}

		if (parFlags & MSG_OFFLINE)
			off += mir_snprintf(buf + off, sizeof(buf) - off, "Dest-Agent: client\r\n");

		off += mir_snprintf(buf + off, sizeof(buf) - off, "Content-Type: text/plain; charset=UTF-8\r\n");
		off += mir_snprintf(buf + off, sizeof(buf) - off, "X-MMS-IM-Format: FN=%s; EF=%s; CO=%x; CS=0; PF=31%s\r\n\r\n",
			tFontName, tFontStyle, tFontColor, (parFlags & MSG_RTL) ? ";RL=1" : "");
	}

	int seq;
	if (netId == NETID_YAHOO || netId == NETID_MOB || (parFlags & MSG_OFFLINE))
		seq = sendPacket("UUM", "%s %d %c %d\r\n%s%s", email, netId, msgType,
		strlen(parMsg)+off, buf, parMsg);
	else
		seq = sendPacket("MSG", "%c %d\r\n%s%s", msgType,
		strlen(parMsg)+off, buf, parMsg);

	return seq;
}
Example #4
0
void SearchWord(TCHAR *word, int engine)
{
	char szURL[4096];
	if (word && word[0]) {
		T2Utf wordUTF(word);
		ptrA wordURL(mir_urlEncode(wordUTF));
		switch (engine) {
		case SEARCHENGINE_WIKIPEDIA:
			mir_snprintf(szURL, "http://en.wikipedia.org/wiki/%s", wordURL);
			break;
		case SEARCHENGINE_YAHOO:
			mir_snprintf(szURL, "http://search.yahoo.com/search?p=%s&ei=UTF-8", wordURL);
			break;
		case SEARCHENGINE_FOODNETWORK:
			mir_snprintf(szURL, "http://search.foodnetwork.com/search/delegate.do?fnSearchString=%s", wordURL);
			break;
		case SEARCHENGINE_BING:
			mir_snprintf(szURL, "http://www.bing.com/search?q=%s&form=OSDSRC", wordURL);
			break;
		case SEARCHENGINE_GOOGLE_MAPS:
			mir_snprintf(szURL, "http://maps.google.com/maps?q=%s&ie=utf-8&oe=utf-8", wordURL);
			break;
		case SEARCHENGINE_GOOGLE_TRANSLATE:
			mir_snprintf(szURL, "http://translate.google.com/?q=%s&ie=utf-8&oe=utf-8", wordURL);
			break;
		case SEARCHENGINE_YANDEX:
			mir_snprintf(szURL, "http://yandex.ru/yandsearch?text=%s", wordURL);
			break;
		case SEARCHENGINE_GOOGLE:
		default:
			mir_snprintf(szURL, "http://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", wordURL);
			break;
		}

		Utils_OpenUrl(szURL);
	}
}
Example #5
0
INT_PTR CMsnProto::MsnSendHotmail(WPARAM hContact, LPARAM)
{
	char szEmail[MSN_MAX_EMAIL_LEN];
	if (MSN_IsMeByContact(hContact, szEmail))
		MsnGotoInbox(0, 0);
	else if (msnLoggedIn)
		MsnInvokeMyURL(true, CMStringA().Format("http://mail.live.com?rru=compose?to=%s", ptrA(mir_urlEncode(szEmail))));

	return 0;
}
Example #6
0
AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const TCHAR_PARAM &param)
{
	T2Utf szValue(param.tszValue);
	CMStringA &s = pReq->m_szParam;
	if (!s.IsEmpty())
		s.AppendChar('&');
	s.AppendFormat("%s=%s", param.szName, ptrA(pReq->bExpUrlEncode ? ExpUrlEncode(szValue) : mir_urlEncode(szValue)));
	return pReq;
}
Example #7
0
// Seaching station name from a single weather service (Threaded)
// name = the name of the weather station to be searched
// searchId = -1
// sData = the name search data for that particular weather service
// svcname = the name of the weather service that is currently searching (ie. Yahoo Weather)
int NameSearchProc(TCHAR *name, const int searchId, WINAMESEARCH *sData, TCHAR *svc, TCHAR *svcname)
{
	TCHAR Name[MAX_DATA_LEN], str[MAX_DATA_LEN], sID[MAX_DATA_LEN], *szData = NULL, *search;

	// replace spaces with %20
	char loc[256];
	ptrA szSearchName( mir_utf8encodeT(name));
	mir_snprintf(loc, SIZEOF(loc), sData->SearchURL, ptrA( mir_urlEncode(szSearchName)));
	if (InternetDownloadFile(loc, NULL, NULL, &szData) == 0) {
		TCHAR* szInfo = szData;
		search = _tcsstr(szInfo, sData->NotFoundStr);	// determine if data is available
		if (search == NULL) { // if data is found
			// test if it is single result
			if (sData->Single.Available && sData->Multiple.Available)
				search = _tcsstr(szInfo, sData->SingleStr);
			// for single result
			if (sData->Single.Available && (search != NULL || !sData->Multiple.Available)) { // single result
				// if station ID appears first in the downloaded data
				if ( !_tcsicmp(sData->Single.First, _T("ID"))) {
					GetDataValue(&sData->Single.ID, str, &szInfo);
					mir_sntprintf(sID, SIZEOF(sID), _T("%s/%s"), svc, str);
					GetDataValue(&sData->Single.Name, Name, &szInfo);
				}
				// if station name appears first in the downloaded data
				else if ( !_tcsicmp(sData->Single.First, _T("NAME"))) {
					GetDataValue(&sData->Single.Name, Name, &szInfo);
					GetDataValue(&sData->Single.ID, str, &szInfo);
					mir_sntprintf(sID, SIZEOF(sID), _T("%s/%s"), svc, str);
				}
				// if no station ID is obtained, quit the search
				if (str[0] == 0) {
					mir_free(szData);
					return 1;
				}
				
				// if can't get the name, use the search string as name
				if (Name[0] == 0)
					_tcscpy(Name, name);

				// set the data and broadcast it
				PROTOSEARCHRESULT psr = { sizeof(psr) };
				psr.flags = PSR_TCHAR;
				psr.nick = Name;
				psr.firstName = _T(" ");
				psr.lastName = svcname;
				psr.email = sID;
				psr.id = sID;
				ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
				mir_free(szData);
				return 0;
			}
			// for multiple result
			else if (sData->Multiple.Available) { // multiple results
				// search for the next occurrence of the string
				for (;;) {
					// if station ID appears first in the downloaded data
					if ( !_tcsicmp(sData->Multiple.First, _T("ID"))) {
						GetDataValue(&sData->Multiple.ID, str, &szInfo);
						mir_sntprintf(sID, SIZEOF(sID), _T("%s/%s"), svc, str);
						GetDataValue(&sData->Multiple.Name, Name, &szInfo);
					}
					// if station name appears first in the downloaded data
					else if ( !_tcsicmp(sData->Multiple.First, _T("NAME"))) {
						GetDataValue(&sData->Multiple.Name, Name, &szInfo);
						GetDataValue(&sData->Multiple.ID, str, &szInfo);
						mir_sntprintf(sID, SIZEOF(sID), _T("%s/%s"), svc, str);
					}
					// if no station ID is obtained, search completed and quit the search
					if (str[0] == 0)	break;
					// if can't get the name, use the search string as name
					if (Name[0] == 0)	
						_tcscpy(Name, name);

					PROTOSEARCHRESULT psr = { sizeof(psr) };
					psr.flags = PSR_TCHAR;
					psr.nick = Name;
					psr.firstName = _T("");
					psr.lastName = svcname;
					psr.email = sID;
					psr.id = sID;
					ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
		}	}	}

		mir_free(szData);
		return 0;
	}

	mir_free(szData);
	return 1;  
}
Example #8
0
void __cdecl CJabberProto::FileServerThread(filetransfer *ft)
{
	debugLogA("Thread started: type=file_send");

	ThreadData info(this, NULL);
	ft->type = FT_OOB;

	NETLIBBIND nlb = { 0 };
	nlb.cbSize = sizeof(NETLIBBIND);
	nlb.pfnNewConnectionV2 = JabberFileServerConnection;
	nlb.pExtra = this;
	nlb.wPort = 0;	// Use user-specified incoming port ranges, if available
	info.s = (HANDLE)CallService(MS_NETLIB_BINDPORT, (WPARAM)m_hNetlibUser, (LPARAM)&nlb);
	if (info.s == NULL) {
		debugLogA("Cannot allocate port to bind for file server thread, thread ended.");
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
		delete ft;
		return;
	}

	ft->s = info.s;
	debugLogA("ft->s = %d", info.s);

	HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	ft->hFileEvent = hEvent;

	TCHAR szPort[20];
	mir_sntprintf(szPort, _countof(szPort), _T("%d"), nlb.wPort);
	JABBER_LIST_ITEM *item = ListAdd(LIST_FILE, szPort);
	item->ft = ft;

	TCHAR *ptszResource = ListGetBestClientResourceNamePtr(ft->jid);
	if (ptszResource != NULL) {
		ft->state = FT_CONNECTING;
		for (int i = 0; i < ft->std.totalFiles && ft->state != FT_ERROR && ft->state != FT_DENIED; i++) {
			ft->std.currentFileNumber = i;
			ft->state = FT_CONNECTING;
			if (ft->httpPath) mir_free(ft->httpPath);
			ft->httpPath = NULL;

			TCHAR *p;
			if ((p = _tcschr(ft->std.ptszFiles[i], '\\')) != NULL)
				p++;
			else
				p = ft->std.ptszFiles[i];

			ptrA pFileName(mir_urlEncode(T2Utf(p)));
			if (pFileName != NULL) {
				ft->szId = JabberId2string(SerialNext());

				ptrA myAddr;
				if (m_options.BsDirect && m_options.BsDirectManual)
					myAddr = getStringA("BsDirectAddr");
				if (myAddr == NULL)
					myAddr = (char*)CallService(MS_NETLIB_ADDRESSTOSTRING, 1, nlb.dwExternalIP);

				char szAddr[256];
				mir_snprintf(szAddr, _countof(szAddr), "http://%s:%d/%s", myAddr, nlb.wPort, pFileName);

				size_t len = mir_tstrlen(ptszResource) + mir_tstrlen(ft->jid) + 2;
				TCHAR *fulljid = (TCHAR *)alloca(sizeof(TCHAR) * len);
				mir_sntprintf(fulljid, len, _T("%s/%s"), ft->jid, ptszResource);

				XmlNodeIq iq(_T("set"), ft->szId, fulljid);
				HXML query = iq << XQUERY(JABBER_FEAT_OOB);
				query << XCHILD(_T("url"), _A2T(szAddr));
				query << XCHILD(_T("desc"), ft->szDescription);
				m_ThreadInfo->send(iq);

				debugLogA("Waiting for the file to be sent...");
				WaitForSingleObject(hEvent, INFINITE);
			}
			debugLogA("File sent, advancing to the next file...");
			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
		}
		CloseHandle(hEvent);
		ft->hFileEvent = NULL;
		debugLogA("Finish all files");
	}

	ft->s = NULL;
	debugLogA("ft->s is NULL");

	ListRemove(LIST_FILE, szPort);

	switch (ft->state) {
	case FT_DONE:
		debugLogA("Finish successfully");
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
		break;
	case FT_DENIED:
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0);
		break;
	default: // FT_ERROR:
		debugLogA("Finish with errors");
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
		break;
	}

	debugLogA("Thread ended: type=file_send");
	delete ft;
}
Example #9
0
std::string utils::url::encode(const std::string &s)
{
	return (char*)ptrA(mir_urlEncode(s.c_str()));
}
Example #10
0
std::string http::url_encode(const std::string &s)
{
	return (char*)ptrA( mir_urlEncode( s.c_str()));
}
Example #11
0
void CAimProto::aim_connection_clientlogin(void)
{
	pass_ptrA password(getStringA(AIM_KEY_PW));
	replaceStr(m_username, ptrA(getStringA(AIM_KEY_SN)));

	CMStringA buf;
	buf.Format("devId=%s&f=xml&pwd=%s&s=%s", AIM_DEFAULT_CLIENT_KEY, ptrA(mir_urlEncode(password)), ptrA(mir_urlEncode(m_username)));

	NETLIBHTTPHEADER headers[] = {
		{ "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" }
	};

	NETLIBHTTPREQUEST req = { 0 };
	req.cbSize = sizeof(req);
	req.flags = NLHRF_SSL;
	req.requestType = REQUEST_POST;
	req.szUrl = AIM_LOGIN_URL;
	req.headers = headers;
	req.headersCount = _countof(headers);
	req.pData = buf.GetBuffer();
	req.dataLength = buf.GetLength();

	NLHR_PTR resp(CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req));
	if (!resp || !resp->dataLength) {
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	time_t hosttime;
	CMStringA token, secret;
	if (!parse_clientlogin_response(resp, headers, token, secret, hosttime)) {
		//TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		mir_free(headers[0].szValue);
		return;
	}

	bool encryption = !getByte(AIM_KEY_DSSL, 0);
	CMStringA url;
	fill_session_url(url, token, secret, hosttime, password, encryption);

	// reuse NETLIBHTTPREQUEST
	req.requestType = REQUEST_GET;
	req.pData = NULL;
	req.flags |= NLHRF_MANUALHOST;
	req.dataLength = 0;
	req.headersCount = 1;
	req.szUrl = url.GetBuffer();
	{
		NETLIBHTTPHEADER headers2[] = {
			{ "Host", "api.oscar.aol.com" },
		};
		req.headers = headers2;

		resp = CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req);
	}

	if (!resp || !resp->dataLength) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	CMStringA bos_host, cookie, tls_cert_name; //TODO: find efficient buf size
	unsigned short bos_port = 0;
	if (!parse_start_socar_session_response(resp->pData, bos_host, bos_port, cookie, tls_cert_name, encryption)) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	m_hServerConn = aim_connect(bos_host, bos_port, (tls_cert_name[0] && encryption) ? true : false, bos_host);
	if (!m_hServerConn) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	replaceStr(COOKIE, cookie);
	COOKIE_LENGTH = (int)mir_strlen(cookie);

	ForkThread(&CAimProto::aim_protocol_negotiation, 0);
}
Example #12
0
void generate_signature(BYTE *signature, const char *method, const char *url, const char *parameters, const char *session_key)
{
	CMStringA sig_base(FORMAT, "%s&%s&%s", method, ptrA(mir_urlEncode(url)), ptrA(mir_urlEncode(parameters)));
	mir_hmac_sha256(signature, (BYTE*)session_key, mir_strlen(session_key), (BYTE*)sig_base.GetString(), sig_base.GetLength());
}
Example #13
0
void CMsnProto::MsnInvokeMyURL(bool ismail, const char* url)
{
	char* hippy = NULL;
	if (!url)
		url = ismail ? "http://mail.live.com?rru=inbox" : "http://profile.live.com";

	const char *postdata = ismail ? postdataM : postdataS;

	char passport[256];
	if (db_get_static(NULL, m_szModuleName, "MsnPassportHost", passport, 256))
		strcpy(passport, "https://login.live.com/");

	char *p = strchr(passport, '/');
	if (p && p[1] == '/') p = strchr(p + 2, '/');
	if (p)
		*p = 0;

	CMStringA post = HotmailLogin(CMStringA().Format(postdata, (unsigned)time(NULL), ptrA(mir_urlEncode(url))));
	if (!post.IsEmpty()) {
		CMStringA hippy(passport);
		hippy.AppendFormat("/ppsecure/sha1auth.srf?lc=%d&token=%s", itoa(langpref, passport, 10), ptrA(mir_urlEncode(post)));

		debugLogA("Starting URL: '%s'", hippy);
		CallService(MS_UTILS_OPENURL, 1, (LPARAM)hippy.GetString());
	}
}
Example #14
0
int CMsnProto::MSN_SetMyAvatar(const TCHAR* sztFname, void* pData, size_t cbLen)
{
	mir_sha1_ctx sha1ctx;
	BYTE sha1c[MIR_SHA1_HASH_SIZE], sha1d[MIR_SHA1_HASH_SIZE];

	char *szFname = mir_utf8encodeT(sztFname);

	mir_sha1_init(&sha1ctx);
	mir_sha1_append(&sha1ctx, (BYTE*)pData, (int)cbLen);
	mir_sha1_finish(&sha1ctx, sha1d);

	ptrA szSha1d( mir_base64_encode((PBYTE)sha1d, sizeof(sha1d)));

	mir_sha1_init(&sha1ctx);
	ezxml_t xmlp = ezxml_new("msnobj");

	mir_sha1_append(&sha1ctx, (PBYTE)"Creator", 7);
	mir_sha1_append(&sha1ctx, (PBYTE)MyOptions.szEmail, (int)strlen(MyOptions.szEmail));
	ezxml_set_attr(xmlp, "Creator", MyOptions.szEmail);

	char szFileSize[20];
	_ultoa((unsigned)cbLen, szFileSize, 10);
	mir_sha1_append(&sha1ctx, (PBYTE)"Size", 4);
	mir_sha1_append(&sha1ctx, (PBYTE)szFileSize, (int)strlen(szFileSize));
	ezxml_set_attr(xmlp, "Size", szFileSize);

	mir_sha1_append(&sha1ctx, (PBYTE)"Type", 4);
	mir_sha1_append(&sha1ctx, (PBYTE)"3", 1);  // MSN_TYPEID_DISPLAYPICT
	ezxml_set_attr(xmlp, "Type", "3");

	mir_sha1_append(&sha1ctx, (PBYTE)"Location", 8);
	mir_sha1_append(&sha1ctx, (PBYTE)szFname, (int)strlen(szFname));
	ezxml_set_attr(xmlp, "Location", szFname);

	mir_sha1_append(&sha1ctx, (PBYTE)"Friendly", 8);
	mir_sha1_append(&sha1ctx, (PBYTE)"AAA=", 4);
	ezxml_set_attr(xmlp, "Friendly", "AAA=");

	mir_sha1_append(&sha1ctx, (PBYTE)"SHA1D", 5);
	mir_sha1_append(&sha1ctx, (PBYTE)(char*)szSha1d, (int)strlen(szSha1d));
	ezxml_set_attr(xmlp, "SHA1D", szSha1d);

	mir_sha1_finish(&sha1ctx, sha1c);

	ptrA szSha1c( mir_base64_encode((PBYTE)sha1c, sizeof(sha1c)));

	//	ezxml_set_attr(xmlp, "SHA1C", szSha1c);

	char* szBuffer = ezxml_toxml(xmlp, false);
	ezxml_free(xmlp);
	mir_free(szFname);
	ptrA szEncodedBuffer(mir_urlEncode(szBuffer));
	free(szBuffer);

	const TCHAR *szExt;
	int fmt = ProtoGetBufferFormat(pData, &szExt);
	if (fmt == PA_FORMAT_UNKNOWN)
		return fmt;

	TCHAR szFileName[MAX_PATH];
	MSN_GetAvatarFileName(NULL, szFileName, SIZEOF(szFileName), NULL);
	_tremove(szFileName);

	MSN_GetAvatarFileName(NULL, szFileName, SIZEOF(szFileName), szExt);

	int fileId = _topen(szFileName, _O_CREAT | _O_TRUNC | _O_WRONLY | O_BINARY, _S_IREAD | _S_IWRITE);
	if (fileId >= 0) {
		_write(fileId, pData, (unsigned)cbLen);
		_close(fileId);

		char szAvatarHashdOld[41] = "";
		db_get_static(NULL, m_szModuleName, "AvatarHash", szAvatarHashdOld, sizeof(szAvatarHashdOld));
		char *szAvatarHash = arrayToHex(sha1d, sizeof(sha1d));
		if (strcmp(szAvatarHashdOld, szAvatarHash)) {
			setString("PictObject", szEncodedBuffer);
			setString("AvatarHash", szAvatarHash);
		}
		mir_free(szAvatarHash);
	}
	else MSN_ShowError("Cannot set avatar. File '%s' could not be created/overwritten", szFileName);

	return fmt;
}
Example #15
0
int CSteamProto::SetStatus(int new_status)
{
	mir_cslock lock(set_status_lock);

	// Routing statuses not supported by Steam
	switch (new_status)
	{
	case ID_STATUS_OFFLINE:
	case ID_STATUS_AWAY:
	case ID_STATUS_NA:
		break;

	case ID_STATUS_DND:
	case ID_STATUS_OCCUPIED:
	case ID_STATUS_ONTHEPHONE:
	case ID_STATUS_OUTTOLUNCH:
		new_status = ID_STATUS_NA;
		break;

	default:
		new_status = ID_STATUS_ONLINE;
		break;
	}

	if (new_status == m_iDesiredStatus)
		return 0;

	debugLog(_T("CSteamProto::SetStatus: changing status from %i to %i"), m_iStatus, new_status);

	int old_status = m_iStatus;
	m_iDesiredStatus = new_status;

	if (new_status == ID_STATUS_OFFLINE)
	{
		m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

		ptrA token(getStringA("TokenSecret"));
		ptrA umqid(getStringA("UMQID"));
		SendRequest(new LogoffRequest(token, umqid));

		requestQueue->Stop();

		if (!Miranda_Terminated())
			SetAllContactsStatus(ID_STATUS_OFFLINE);
	}
	else if (old_status == ID_STATUS_OFFLINE)
	{
		m_iStatus = ID_STATUS_CONNECTING;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

		requestQueue->Start();

		ptrA token(getStringA("TokenSecret"));
		if (mir_strlen(token) > 0)
		{
			PushRequest(
				new LogonRequest(token),
				&CSteamProto::OnLoggedOn);
		}
		else
		{
			ptrA username(mir_urlEncode(ptrA(mir_utf8encodeT(getTStringA("Username")))));
			if (username == NULL || username[0] == '\0')
			{
				m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
				ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus);
				return 0;
			}

			PushRequest(
				new GetRsaKeyRequest(username),
				&CSteamProto::OnGotRsaKey);
		}
	}
	else
	{
		m_iStatus = new_status;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
	}

	return 0;
}