Beispiel #1
0
ThreadData* CMsnProto::MSN_GetP2PThreadByContact(const char *wlid)
{
	mir_cslock lck(m_csThreads);

	for (int i = 0; i < m_arThreads.getCount(); i++) {
		ThreadData &T = m_arThreads[i];
		if (T.mType != SERVER_P2P_DIRECT || !T.mJoinedIdentContactsWLID.getCount())
			continue;

		if (_stricmp(T.mJoinedIdentContactsWLID[0], wlid) == 0)
			return &T;
	}

	char *szEmail = NULL;
	parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);

	ThreadData *result = NULL;
	for (int i = 0; i < m_arThreads.getCount(); i++) {
		ThreadData &T = m_arThreads[i];
		if (T.mJoinedContactsWLID.getCount() && !T.mInitialContactWLID &&
			_stricmp(T.mJoinedContactsWLID[0], szEmail) == 0) {
			if (T.mType == SERVER_P2P_DIRECT)
				return &T;

			if (T.mType == SERVER_SWITCHBOARD)
				result = &T;
		}
	}

	return result;
}
Beispiel #2
0
// do the compare("A","B","X","Y")
void checkStringForcompare(CMStringA &str)
{
	if (!strstr(str, "compare(\"")) return;
	char *A, *B, *X, *Y, *copyOfStr = NEWSTR_ALLOCA(str.c_str());
	CMStringA tmp;
	unsigned int i, j = 0, s = str.GetLength();
	for (i = 0; i < s; i++) {
		if (!strncmp(str.c_str()+i, "compare(\"", mir_strlen("compare(\""))) {
			i += (int)mir_strlen("compare(\"");
			A = strtok(&copyOfStr[i], "\",\"");
			B = strtok(NULL, "\",\"");
			X = strtok(NULL, "\",\"");
			Y = strtok(NULL, ",\")");
			j = Y - &copyOfStr[i] + (int)mir_strlen(Y) + 1;
			if (A && B && X && Y) {
				if (!mir_strcmp(A, B))
					tmp.Append(X);
				else
					tmp.Append(Y);
			}
			else tmp.Append(str.c_str()+i, j);
			i += j;
		}
		else tmp.AppendChar(copyOfStr[i]);
	}
	str = tmp;
}
static BOOL MatchMask( char* name, char* mask)
{
	if ( !mask || !name )
		return mask == name;

	if ( *mask != '|' ) 
		return WildComparei( name, mask );
	
	char* temp = NEWSTR_ALLOCA(mask);
	for ( int e=1; mask[e] != '\0'; e++ ) {
		int s = e;
		while ( mask[e] != '\0' && mask[e] != '|')
			e++;

		memcpy( temp, mask+s, e-s );
		temp[e-s] = '\0';
		if ( WildComparei( name, temp ))
			return TRUE;

		if ( mask[e] == 0 )
			return FALSE;
	}

	return FALSE;
}
Beispiel #4
0
ThreadData* CMsnProto::MSN_GetThreadByContact(const char* wlid, TInfoType type)
{
	mir_cslock lck(m_csThreads);

	if (type == SERVER_P2P_DIRECT) {
		for (int i = 0; i < m_arThreads.getCount(); i++) {
			ThreadData &T = m_arThreads[i];
			if (T.mType != SERVER_P2P_DIRECT || !T.mJoinedIdentContactsWLID.getCount() || T.s == NULL)
				continue;

			if (_stricmp(T.mJoinedIdentContactsWLID[0], wlid) == 0)
				return &T;
		}
	}

	char *szEmail = NULL;
	parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);

	for (int i = 0; i < m_arThreads.getCount(); i++) {
		ThreadData &T = m_arThreads[i];
		if (T.mType != type || !T.mJoinedContactsWLID.getCount() || T.mInitialContactWLID || T.s == NULL)
			continue;

		if (_stricmp(T.mJoinedContactsWLID[0], szEmail) == 0 && T.mChatID[0] == 0)
			return &T;
	}

	return NULL;
}
Beispiel #5
0
filetransfer*  CMsnProto::p2p_getSessionByCallID(const char* CallID, const char* wlid)
{
	if (CallID == NULL)
		return NULL;

	EnterCriticalSection(&sessionLock);

	filetransfer* ft = NULL;
	char* szEmail = NULL;
	for (int i=0; i < sessionList.getCount(); i++) 
	{
		filetransfer* FT = &sessionList[i];
		if (FT->p2p_callID && !_stricmp(FT->p2p_callID, CallID)) 
		{
 			if (_stricmp(FT->p2p_dest, wlid))
			{
				if (!szEmail)
					parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);
				if (_stricmp(FT->p2p_dest, szEmail))
					continue;
			}
			ft = FT;
			break;
		}	
	}

	LeaveCriticalSection(&sessionLock);
	if (ft == NULL)
		MSN_DebugLog("Ignoring unknown session call id %s", CallID);

	return ft;
}
Beispiel #6
0
STDMETHODIMP_(BOOL) CDb3Mmap::GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
{
	dbv->type = 0;
	if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
		return 1;

	if (dbv->type == DBVT_UTF8) {
		WCHAR *tmp = NULL;
		char *p = NEWSTR_ALLOCA(dbv->pszVal);
		if (mir_utf8decode(p, &tmp) != NULL) {
			BOOL bUsed = FALSE;
			int  result = WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, NULL, 0, NULL, &bUsed);

			mir_free(dbv->pszVal);

			if (bUsed || result == 0) {
				dbv->type = DBVT_WCHAR;
				dbv->pwszVal = tmp;
			}
			else {
				dbv->type = DBVT_ASCIIZ;
				dbv->pszVal = (char *)mir_alloc(result);
				WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, dbv->pszVal, result, NULL, NULL);
				mir_free(tmp);
			}
		}
		else {
			dbv->type = DBVT_ASCIIZ;
			mir_free(tmp);
		}
	}

	return 0;
}
Beispiel #7
0
// do load("A") A is DBVar name
void checkStringForLoad(MCONTACT hContact, CMStringA &str)
{
	if (!strstr(str, "load(\"")) return;
	char *A, *copyOfStr = NEWSTR_ALLOCA(str.c_str());
	unsigned int i, j = 0, s = str.GetLength();
	CMStringA tmp;
	for (i = 0; i < s; i++) {
		if (!strncmp(str.c_str()+i, "load(\"", mir_strlen("load(\""))) {
			i += (int)mir_strlen("load(\"");
			A = strtok(&copyOfStr[i], "\")");
			j = A - &copyOfStr[i] + (int)mir_strlen(A) + 1;
			if (A) {
				DBVARIANT dbv;
				if (!db_get_s(hContact, MODNAME, A, &dbv)) {
					tmp.Append(dbv.pszVal);
					db_free(&dbv);
				}
			}
			else tmp.Append(str.c_str()+i, j);
			i += j;
		}
		else tmp.AppendChar(copyOfStr[i]);
	}
	str = tmp;
}
Beispiel #8
0
static INT_PTR GetContactSetting(WPARAM wParam, LPARAM lParam)
{
	DBCONTACTGETSETTING* dgs = ( DBCONTACTGETSETTING* )lParam;
	dgs->pValue->type = 0;
	if ( GetContactSettingWorker(( HANDLE )wParam, dgs, 0 ))
		return 1;

	if ( dgs->pValue->type == DBVT_UTF8 ) {
		WCHAR* tmp = NULL;
		char*  p = NEWSTR_ALLOCA(dgs->pValue->pszVal);
		if ( mir_utf8decode( p, &tmp ) != NULL ) {
			BOOL bUsed = FALSE;
			int  result = WideCharToMultiByte( mirCp, WC_NO_BEST_FIT_CHARS, tmp, -1, NULL, 0, NULL, &bUsed );

			mir_free( dgs->pValue->pszVal );

			if ( bUsed || result == 0 ) {
				dgs->pValue->type = DBVT_WCHAR;
				dgs->pValue->pwszVal = tmp;
			}
			else {
				dgs->pValue->type = DBVT_ASCIIZ;
				dgs->pValue->pszVal = mir_alloc( result );
				WideCharToMultiByte( mirCp, WC_NO_BEST_FIT_CHARS, tmp, -1, dgs->pValue->pszVal, result, NULL, NULL );
				mir_free( tmp );
			}
		}
		else {
			dgs->pValue->type = DBVT_ASCIIZ;
			mir_free( tmp );
	}	}

	return 0;
}
Beispiel #9
0
time_t IsoToUnixTime(const char *stamp)
{
	char date[9];
	int i, y;

	if (stamp == NULL)
		return 0;

	char *p = NEWSTR_ALLOCA(stamp);

	// skip '-' chars
	int si = 0, sj = 0;
	while (true) {
		if (p[si] == '-')
			si++;
		else if (!(p[sj++] = p[si++]))
			break;
	}

	// Get the date part
	for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++)
		date[i] = *p;

	// Parse year
	if (i == 6) {
		// 2-digit year (1970-2069)
		y = (date[0] - '0') * 10 + (date[1] - '0');
		if (y < 70) y += 100;
	}
	else if (i == 8) {
		// 4-digit year
		y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0';
		y -= 1900;
	}
	else return 0;

	struct tm timestamp;
	timestamp.tm_year = y;

	// Parse month
	timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1;

	// Parse date
	timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0';

	// Skip any date/time delimiter
	for (; *p != '\0' && !isdigit(*p); p++);

	// Parse time
	if (sscanf(p, "%d:%d:%d", &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec) != 3)
		return (time_t)0;

	timestamp.tm_isdst = 0;	// DST is already present in _timezone below
	time_t t = mktime(&timestamp);

	_tzset();
	t -= _timezone;
	return (t >= 0) ? t : 0;
}
Beispiel #10
0
static void BackupRegTree(HKEY hKey, const char *pszSubKey, const char *pszDbPrefix)
{
	struct BackupRegTreeParam param;
	DWORD dwDbPrefixSize;
	param.level = 0;
	param.pdwDbPrefixSize = &dwDbPrefixSize;
	param.ppszDbPrefix = (char**)&pszDbPrefix;
	pszDbPrefix = NEWSTR_ALLOCA(pszDbPrefix);
	dwDbPrefixSize = (int)mir_strlen(pszDbPrefix)+1;
	BackupRegTree_Worker(hKey, pszSubKey, &param);
}
Beispiel #11
0
ThreadData::~ThreadData()
{
	if (s != NULL) {
		proto->debugLogA("Closing connection handle %08X", s);
		Netlib_CloseHandle(s);
	}

	if (mIncomingBoundPort != NULL) {
		Netlib_CloseHandle(mIncomingBoundPort);
	}

	if (mMsnFtp != NULL) {
		delete mMsnFtp;
		mMsnFtp = NULL;
	}

	if (hWaitEvent != INVALID_HANDLE_VALUE)
		CloseHandle(hWaitEvent);

	if (mTimerId != 0)
		KillTimer(NULL, mTimerId);

#ifdef OBSOLETE
	if (mType == SERVER_SWITCHBOARD) {
		for (int i = 0; i < mJoinedContactsWLID.getCount(); ++i) {
			const char* wlid = mJoinedContactsWLID[i];
			MCONTACT hContact = proto->MSN_HContactFromEmail(wlid);
			int temp_status = proto->getWord(hContact, "Status", ID_STATUS_OFFLINE);
			if (temp_status == ID_STATUS_INVISIBLE && proto->MSN_GetThreadByContact(wlid) == NULL)
				proto->setWord(hContact, "Status", ID_STATUS_OFFLINE);
		}
	}
#endif

	mJoinedContactsWLID.destroy();
	mJoinedIdentContactsWLID.destroy();

	mir_free(mInitialContactWLID); mInitialContactWLID = NULL;

#ifdef OBSOLETE
	const char* wlid = NEWSTR_ALLOCA(mInitialContactWLID);

	if (proto && mType == SERVER_P2P_DIRECT)
		proto->p2p_clearDormantSessions();

	if (wlid != NULL && mType == SERVER_SWITCHBOARD &&
		proto->MSN_GetThreadByContact(wlid) == NULL &&
		proto->MSN_GetUnconnectedThread(wlid) == NULL) {
		proto->MsgQueue_Clear(wlid, true);
	}
#endif

	mir_free(mData);
}
Beispiel #12
0
MsnPlace* CMsnProto::Lists_GetPlace(const char* wlid)
{
	mir_cslock lck(m_csLists);

	char *szEmail, *szInst;
	parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, &szInst);

	if (szInst == NULL)
		szInst = (char*)sttVoidUid;

	MsnContact* p = m_arContacts.find((MsnContact*)&szEmail);
	if (p == NULL)
		return NULL;

	return p->places.find((MsnPlace*)&szInst);
}
Beispiel #13
0
MsnPlace* CMsnProto::Lists_GetPlace(const char* wlid)
{
	EnterCriticalSection(&csLists);

	char *szEmail, *szInst;
	parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, &szInst);

	if (szInst == NULL) szInst = (char*)sttVoidUid;

	MsnPlace* pl = NULL;
	MsnContact* p = contList.find((MsnContact*)&szEmail);
	if (p) pl = p->places.find((MsnPlace*)&szInst);

	LeaveCriticalSection(&csLists);
	return pl;
}
Beispiel #14
0
static INT_PTR GetContactSettingStr(WPARAM wParam, LPARAM lParam)
{
	DBCONTACTGETSETTING* dgs = (DBCONTACTGETSETTING*)lParam;
	int iSaveType = dgs->pValue->type;

	if ( GetContactSettingWorker(( HANDLE )wParam, dgs, 0 ))
		return 1;

	if ( iSaveType == 0 || iSaveType == dgs->pValue->type )
		return 0;

	if ( dgs->pValue->type != DBVT_ASCIIZ && dgs->pValue->type != DBVT_UTF8 )
		return 1;

	if ( iSaveType == DBVT_WCHAR ) {
		if ( dgs->pValue->type != DBVT_UTF8 ) {
			int len = MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, NULL, 0 );
			wchar_t* wszResult = ( wchar_t* )mir_alloc(( len+1 )*sizeof( wchar_t ));
			if ( wszResult == NULL )
				return 1;

			MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, wszResult, len );
			wszResult[ len ] = 0;
			mir_free( dgs->pValue->pszVal );
			dgs->pValue->pwszVal = wszResult;
		}
		else {
			char* savePtr = NEWSTR_ALLOCA(dgs->pValue->pszVal);
			mir_free( dgs->pValue->pszVal );
			if ( !mir_utf8decode( savePtr, &dgs->pValue->pwszVal ))
				return 1;
		}
	}
	else if ( iSaveType == DBVT_UTF8 ) {
		char* tmpBuf = mir_utf8encode( dgs->pValue->pszVal );
		if ( tmpBuf == NULL )
			return 1;

		mir_free( dgs->pValue->pszVal );
		dgs->pValue->pszVal = tmpBuf;
	}
	else if ( iSaveType == DBVT_ASCIIZ )
		mir_utf8decode( dgs->pValue->pszVal, NULL );

	dgs->pValue->type = iSaveType;
	return 0;
}
Beispiel #15
0
void CMsnProto::p2p_startSessions(const char* wlid)
{
	mir_cslock lck(m_csSessions);

	char* szEmail;
	parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);

	for (int i = 0; i < m_arSessions.getCount(); i++) {
		filetransfer* FT = &m_arSessions[i];
		if (!FT->bAccepted  && !_stricmp(FT->p2p_dest, szEmail)) {
			if (FT->p2p_appID == MSN_APPID_FILE && (FT->std.flags & PFTS_SENDING))
				p2p_invite(FT->p2p_type, FT, wlid);
			else if (FT->p2p_appID != MSN_APPID_FILE && !(FT->std.flags & PFTS_SENDING))
				p2p_invite(FT->p2p_type, FT, wlid);
		}
	}
}
Beispiel #16
0
ThreadData* CMsnProto::MSN_GetUnconnectedThread(const char* wlid, TInfoType type)
{
	mir_cslock lck(m_csThreads);

	char* szEmail = (char*)wlid;

	if (type == SERVER_SWITCHBOARD && strchr(wlid, ';'))
		parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);

	for (int i = 0; i < m_arThreads.getCount(); i++) {
		ThreadData &T = m_arThreads[i];
		if (T.mType == type && T.mInitialContactWLID && _stricmp(T.mInitialContactWLID, szEmail) == 0)
			return &T;
	}

	return NULL;
}
Beispiel #17
0
STDMETHODIMP_(BOOL) CDb3Mmap::GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
{
	int iSaveType = dbv->type;

	if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
		return 1;

	if (iSaveType == 0 || iSaveType == dbv->type)
		return 0;

	if (dbv->type != DBVT_ASCIIZ && dbv->type != DBVT_UTF8)
		return 1;

	if (iSaveType == DBVT_WCHAR) {
		if (dbv->type != DBVT_UTF8) {
			int len = MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, NULL, 0);
			wchar_t* wszResult = (wchar_t*)mir_alloc((len + 1)*sizeof(wchar_t));
			if (wszResult == NULL)
				return 1;

			MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, wszResult, len);
			wszResult[len] = 0;
			mir_free(dbv->pszVal);
			dbv->pwszVal = wszResult;
		}
		else {
			char* savePtr = NEWSTR_ALLOCA(dbv->pszVal);
			mir_free(dbv->pszVal);
			if (!mir_utf8decode(savePtr, &dbv->pwszVal))
				return 1;
		}
	}
	else if (iSaveType == DBVT_UTF8) {
		char* tmpBuf = mir_utf8encode(dbv->pszVal);
		if (tmpBuf == NULL)
			return 1;

		mir_free(dbv->pszVal);
		dbv->pszVal = tmpBuf;
	}
	else if (iSaveType == DBVT_ASCIIZ)
		mir_utf8decode(dbv->pszVal, NULL);

	dbv->type = iSaveType;
	return 0;
}
Beispiel #18
0
// do saveN("A","B","C","D") A is module, B is setting, c is value, D is type 0/b 1/w 2/d 3/s
void checkStringForSaveN(CMStringA &str)
{
	if (!strstr(str, "saveN(\"")) return;
	char *A, *B, *C, *D, *copyOfStr = NEWSTR_ALLOCA(str.c_str());
	unsigned int i, j = 0, s = str.GetLength();
	CMStringA tmp;
	for (i = 0; i < s; i++) {
		if (!strncmp(str.c_str()+i, "saveN(\"", mir_strlen("saveN(\""))) {
			i += (int)mir_strlen("saveN(\"");
			A = strtok(&copyOfStr[i], "\",\"");
			B = strtok(NULL, ",\"");
			C = strtok(NULL, ",\"");
			D = strtok(NULL, ",\")");
			j = D - &copyOfStr[i] + (int)mir_strlen(D) + 1;
			if (A && B && C && D) {
				switch (D[0]) {
				case '0':
				case 'b':
					db_set_b(NULL, A, B, (BYTE)atoi(C));
					break;
				case '1':
				case 'w':
					db_set_w(NULL, A, B, (WORD)atoi(C));
					break;
				case '2':
				case 'd':
					db_set_dw(NULL, A, B, (DWORD)atoi(C));
					break;
				case '3':
				case 's':
					db_set_s(NULL, A, B, C);
					break;
				}
			}
			else tmp.Append(str.c_str()+i, j);
			i += j;
		}
		else tmp.AppendChar(copyOfStr[i]);
	}
	str = tmp;
}
Beispiel #19
0
char* MSN_GetAvatarHash(char* szContext, char** pszUrl)
{
	if (pszUrl)
		*pszUrl = NULL;

	if (szContext == NULL)
		return NULL;

	char *res  = NULL;

	ezxml_t xmli = ezxml_parse_str(NEWSTR_ALLOCA(szContext), strlen(szContext));
	const char *szAvatarHash = ezxml_attr(xmli, "SHA1D");
	if (szAvatarHash != NULL) {
		unsigned hashLen;
		mir_ptr<BYTE> hash((BYTE*)mir_base64_decode(szAvatarHash, &hashLen));
		if (hash)
			res = arrayToHex(hash, hashLen);

		if (pszUrl) {
			const char *pszUrlAttr;
			for (int i=0; ; i++) {
				char szSetting[20];
				if (i == 0)
					strcpy(szSetting, "Url");
				else
					mir_snprintf(szSetting, sizeof(szSetting), "Url%d", i);
				pszUrlAttr = ezxml_attr(xmli, szSetting);
				if (pszUrlAttr == NULL)
					break;

				if (pszUrlAttr[0] != 0) {
					*pszUrl = mir_strdup(pszUrlAttr);
					break;
				}
			}
		}
	}
	ezxml_free(xmli);

	return res;
}
Beispiel #20
0
void  CMsnProto::p2p_startSessions(const char* wlid)
{
	EnterCriticalSection(&sessionLock);

	char* szEmail;
	parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);

	for (int i=0; i < sessionList.getCount(); i++) 
	{
		filetransfer* FT = &sessionList[i];
		if (!FT->bAccepted  && !_stricmp(FT->p2p_dest, szEmail))
		{
			if (FT->p2p_appID == MSN_APPID_FILE && (FT->std.flags & PFTS_SENDING))
				p2p_invite(FT->p2p_type, FT, wlid);
			else if (FT->p2p_appID != MSN_APPID_FILE && !(FT->std.flags & PFTS_SENDING))
				p2p_invite(FT->p2p_type, FT, wlid);
		}
	}

	LeaveCriticalSection(&sessionLock);
}
Beispiel #21
0
int CVkProto::PollServer()
{
	debugLogA("CVkProto::PollServer");

	NETLIBHTTPREQUEST req = { sizeof(req) };
	req.requestType = REQUEST_GET;
	req.szUrl = NEWSTR_ALLOCA(CMStringA().Format("http://%s?act=a_check&key=%s&ts=%s&wait=25&access_token=%s", m_pollingServer, m_pollingKey, m_pollingTs, m_szAccessToken));
	req.flags = VK_NODUMPHEADERS | NLHRF_PERSISTENT;
	req.timeout = 30000;
	req.nlc = m_pollingConn;

	NETLIBHTTPREQUEST *reply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req);
	if (reply == NULL) {
		m_pollingConn = NULL;
		return 0;
	}

	int retVal = 0;
	if (reply->resultCode == 200) {
		JSONROOT pRoot(reply->pData);
		JSONNODE *pFailed = json_get(pRoot, "failed");
		if (pFailed != NULL && json_as_int(pFailed) == 2) {
			RetrievePollingInfo();
			retVal = -1;
			debugLogA("Polling key expired, restarting polling thread");
		}
		else if (CheckJsonResult(NULL, reply, pRoot)) {
			m_pollingTs = mir_t2a(ptrT(json_as_string(json_get(pRoot, "ts"))));
			JSONNODE *pUpdates = json_get(pRoot, "updates");
			if (pUpdates != NULL)
				PollUpdates(pUpdates);
			retVal = 1;
		}
	}

	m_pollingConn = reply->nlc;

	CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply);
	return retVal;
}
Beispiel #22
0
// do save("A","B") A is DBVar name, B is value
void checkStringForSave(MCONTACT hContact, CMStringA &str)
{
	if (!strstr(str, "save(\"")) return;
	char *A, *B, *copyOfStr = NEWSTR_ALLOCA(str.c_str());
	unsigned int i, j = 0, s = str.GetLength();
	CMStringA tmp;
	for (i = 0; i < s; i++) {
		if (!strncmp(str.c_str()+i, "save(\"", mir_strlen("save(\""))) {
			i += (int)mir_strlen("save(\"");
			A = strtok(&copyOfStr[i], "\",\"");
			B = strtok(NULL, ",\")");
			j = B - &copyOfStr[i] + (int)mir_strlen(B) + 1;
			if (A && B)
				db_set_s(hContact, MODNAME, A, B);

			else tmp.Append(str.c_str()+i, j);
			i += j;
		}
		else tmp.AppendChar(copyOfStr[i]);
	}
	str = tmp;
}
Beispiel #23
0
// do loadN("A","B") A is module, B is setting
void checkStringForLoadN(CMStringA &str)
{
	if (!strstr(str, "loadN(\"")) return;
	char *copyOfStr = NEWSTR_ALLOCA(str.c_str()), temp[32];
	unsigned int i, j = 0, s = str.GetLength();
	CMStringA tmp;
	for (i = 0; i < s; i++) {
		if (!strncmp(str.c_str()+i, "loadN(\"", mir_strlen("loadN(\""))) {
			i += (int)mir_strlen("loadN(\"");
			char *A = strtok(&copyOfStr[i], "\",\"");
			char *B = strtok(NULL, ",\")");
			if (A && B) {
				j = B - &copyOfStr[i] + (int)mir_strlen(B) + 1;
				DBVARIANT dbv;
				if (!db_get(NULL, A, B, &dbv)) {
					switch (dbv.type) {
					case DBVT_BYTE:
						tmp.Append(_itoa(dbv.bVal, temp, 10));
						break;
					case DBVT_WORD:
						tmp.Append(_itoa(dbv.wVal, temp, 10));
						break;
					case DBVT_DWORD:
						tmp.Append(_itoa(dbv.dVal, temp, 10));
						break;
					case DBVT_ASCIIZ:
						tmp.Append(dbv.pszVal);
						break;
					}
					db_free(&dbv);
				}
			}
			else tmp.Append(str.c_str()+i, i);
			i += j;
		}
		else tmp.AppendChar(copyOfStr[i]);
	}
	str = tmp;
}
Beispiel #24
0
filetransfer* CMsnProto::p2p_getSessionByCallID(const char* CallID, const char* wlid)
{
	if (CallID == NULL)
		return NULL;

	mir_cslock lck(m_csSessions);

	char* szEmail = NULL;
	for (int i = 0; i < m_arSessions.getCount(); i++) {
		filetransfer* FT = &m_arSessions[i];
		if (FT->p2p_callID && !_stricmp(FT->p2p_callID, CallID)) {
			if (_stricmp(FT->p2p_dest, wlid)) {
				if (!szEmail)
					parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);
				if (_stricmp(FT->p2p_dest, szEmail))
					continue;
			}
			return FT;
		}
	}

	return NULL;
}
Beispiel #25
0
int CMsnProto::MSN_ChatInit(GCThreadData *info, const char *pszID, const char *pszTopic)
{
	char *szNet, *szEmail;

	_tcsncpy(info->mChatID, _A2T(pszID), _countof(info->mChatID));
	parseWLID(NEWSTR_ALLOCA(pszID), &szNet, &szEmail, NULL);
	info->netId = atoi(szNet);
	strncpy(info->szEmail, szEmail, sizeof(info->szEmail));

	TCHAR szName[512];
	InterlockedIncrement(&m_chatID);
	if (*pszTopic) _tcsncpy(szName, _A2T(pszTopic), _countof(szName));
	else mir_sntprintf(szName, _T("%s %s%d"),
		m_tszUserName, TranslateT("Chat #"), m_chatID);

	GCSESSION gcw = { sizeof(gcw) };
	gcw.iType = GCW_CHATROOM;
	gcw.pszModule = m_szModuleName;
	gcw.ptszName = szName;
	gcw.ptszID = info->mChatID;
	CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);

	GCDEST gcd = { m_szModuleName, info->mChatID, GC_EVENT_ADDGROUP };
	GCEVENT gce = { sizeof(gce), &gcd };
	for (int j = 0; j < _countof(m_ptszRoles); j++) {
		gce.ptszStatus = m_ptszRoles[j];
		CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
	}

	gcd.iType = GC_EVENT_CONTROL;
	CallServiceSync(MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce);
	CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce);
	CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gce);

	mir_free((TCHAR*)gce.ptszUID);
	return 0;
}
Beispiel #26
0
INT_PTR CMsnProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
{
	PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
	TCHAR filename[MAX_PATH];
	MsnContact *cont = NULL;

	if (pai->hContact) {
		cont = Lists_Get(pai->hContact);
		if (cont == NULL) return GAIR_NOAVATAR;

		/*
		if ((cont->cap1 & 0xf0000000) == 0)
			return GAIR_NOAVATAR;
		*/
	}

	if (pai->hContact == NULL || _stricmp(cont->email, MyOptions.szEmail) == 0) {
		MSN_GetAvatarFileName(NULL, filename, _countof(filename), NULL);
		pai->format = ProtoGetAvatarFormat(filename);
		if (pai->format != PA_FORMAT_UNKNOWN)
			mir_tstrcpy(pai->filename, filename);
		return pai->format == PA_FORMAT_UNKNOWN ? GAIR_NOAVATAR : GAIR_SUCCESS;
	}

	char *szContext;
	DBVARIANT dbv;
	if (getString(pai->hContact, pai->hContact ? "PictContext" : "PictObject", &dbv) == 0) {
		szContext = (char*)NEWSTR_ALLOCA(dbv.pszVal);
		db_free(&dbv);
	}
	else return GAIR_NOAVATAR;

	MSN_GetAvatarFileName(pai->hContact, filename, _countof(filename), NULL);
	pai->format = ProtoGetAvatarFormat(filename);

	if (pai->format != PA_FORMAT_UNKNOWN) {
		bool needupdate = true;
		if (getString(pai->hContact, "PictSavedContext", &dbv) == 0) {
			needupdate = mir_strcmp(dbv.pszVal, szContext) != 0;
			db_free(&dbv);
		}

		if (needupdate) {
			setString(pai->hContact, "PictSavedContext", szContext);

			// Store also avatar hash
			char* szAvatarHash = MSN_GetAvatarHash(szContext);
			if (szAvatarHash != NULL) {
				setString(pai->hContact, "AvatarSavedHash", szAvatarHash);
				mir_free(szAvatarHash);
			}
		}
		mir_tstrcpy(pai->filename, filename);
		return GAIR_SUCCESS;
	}

	if ((wParam & GAIF_FORCE) != 0 && pai->hContact != NULL) {
		if (avsPresent < 0) avsPresent = ServiceExists(MS_AV_SETMYAVATAR) != 0;
		if (!avsPresent)
			return GAIR_NOAVATAR;

		WORD wStatus = getWord(pai->hContact, "Status", ID_STATUS_OFFLINE);
		if (wStatus == ID_STATUS_OFFLINE) {
			delSetting(pai->hContact, "AvatarHash");
			PROTO_AVATAR_INFORMATION *fakeAI = new PROTO_AVATAR_INFORMATION;
			*fakeAI = *pai;
			ForkThread(&CMsnProto::sttFakeAvatarAck, fakeAI);
		}
		else if (!getString(pai->hContact, "AvatarUrl", &dbv)) {
			pushAvatarRequest(pai->hContact, dbv.pszVal);
			db_free(&dbv);
		}
#ifdef OBSOLETE
		else if (p2p_getAvatarSession(pai->hContact) == NULL) {
			filetransfer* ft = new filetransfer(this);
			ft->std.hContact = pai->hContact;
			ft->p2p_object = mir_strdup(szContext);

			MSN_GetAvatarFileName(pai->hContact, filename, _countof(filename), _T("unk"));
			ft->std.tszCurrentFile = mir_tstrdup(filename);

			p2p_invite(MSN_APPID_AVATAR, ft, NULL);
		}
#endif

		return GAIR_WAITFOR;
	}
	return GAIR_NOAVATAR;
}
Beispiel #27
0
void CMsnProto::MSN_ChatStart(ezxml_t xmli)
{
	if (!mir_strcmp(xmli->txt, "thread"))
		return;

	// If Chat ID already exists, don'T create a new one
	const char *pszID = ezxml_txt(ezxml_child(xmli, "id"));
	GCThreadData* info = MSN_GetThreadByChatId(_A2T(pszID));
	if (info == NULL) {
		info = new GCThreadData;
		{
			mir_cslock lck(m_csThreads);
			m_arGCThreads.insert(info);
		}

		MSN_ChatInit(info, pszID, ezxml_txt(ezxml_get(xmli, "properties", 0, "topic", -1)));
		MSN_StartStopTyping(info, false);
	}
	else {
		GCDEST gcd = { m_szModuleName, info->mChatID, GC_EVENT_CONTROL };
		GCEVENT gce = { sizeof(gce), &gcd };
		CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce);
	}

	const char *pszCreator = ezxml_txt(ezxml_get(xmli, "properties", 0, "creator", -1));

	for (ezxml_t memb = ezxml_get(xmli, "members", 0, "member", -1); memb != NULL; memb = ezxml_next(memb)) {
		const char *mri = ezxml_txt(ezxml_child(memb, "mri"));
		const char *role = ezxml_txt(ezxml_child(memb, "role"));
		GCUserItem *gcu = NULL;

		for (int j = 0; j < info->mJoinedContacts.getCount(); j++) {
			if (!mir_strcmp(info->mJoinedContacts[j]->WLID, mri)) {
				gcu = info->mJoinedContacts[j];
				break;
			}
		}
		if (!gcu) {
			gcu = new GCUserItem;
			info->mJoinedContacts.insert(gcu);
			strncpy(gcu->WLID, mri, sizeof(gcu->WLID));
		}
		mir_tstrcpy(gcu->role, _A2T(role));

		if (pszCreator && !mir_strcmp(mri, pszCreator)) info->mCreator = gcu;
		char* szEmail, *szNet;
		parseWLID(NEWSTR_ALLOCA(mri), &szNet, &szEmail, NULL);
		if (!mir_strcmpi(szEmail, GetMyUsername(atoi(szNet))))
			info->mMe = gcu;
		gcu->btag = 1;
	}

	// Remove contacts not on list (not tagged)
	for (int j = 0; j < info->mJoinedContacts.getCount(); j++) {
		if (!info->mJoinedContacts[j]->btag) {
			info->mJoinedContacts.remove(j);
			j--;
		}
		else info->mJoinedContacts[j]->btag = 0;
	}
}
Beispiel #28
0
void CMsnProto::MSN_GCProcessThreadActivity(ezxml_t xmli, const TCHAR *mChatID)
{
	if (!mir_strcmp(xmli->name, "topicupdate")) {
		ezxml_t initiator = ezxml_child(xmli, "initiator");
		GCDEST gcd = { m_szModuleName, mChatID, GC_EVENT_TOPIC};
		GCEVENT gce = { sizeof(gce), &gcd };
		gce.dwFlags = GCEF_ADDTOLOG;
		gce.time = MsnTSToUnixtime(ezxml_txt(ezxml_child(xmli, "eventtime")));
		gce.ptszUID = initiator?mir_a2t(initiator->txt):NULL;
		MCONTACT hContInitiator = MSN_HContactFromEmail(initiator->txt);
		gce.ptszNick = GetContactNameT(hContInitiator);
		gce.ptszText = mir_a2t(ezxml_txt(ezxml_child(xmli, "value")));
		CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
		mir_free((TCHAR*)gce.ptszUID);
		mir_free((TCHAR*)gce.ptszText);
	}
	else if (ezxml_t target = ezxml_child(xmli, "target")) {
		MCONTACT hContInitiator = NULL;
		GCDEST gcd = { m_szModuleName, mChatID, 0};
		GCEVENT gce = { sizeof(gce), &gcd };
		gce.dwFlags = GCEF_ADDTOLOG;

		if (!mir_strcmp(xmli->name, "deletemember")) {
			gcd.iType = GC_EVENT_PART;
			if (ezxml_t initiator = ezxml_child(xmli, "initiator")) {
				if (mir_strcmp(initiator->txt, target->txt)) {
					hContInitiator = MSN_HContactFromEmail(initiator->txt);
					gce.ptszStatus = GetContactNameT(hContInitiator);
					gcd.iType = GC_EVENT_KICK;
				}
			}
		}
		else if (!mir_strcmp(xmli->name, "addmember")) {
			gcd.iType = GC_EVENT_JOIN;
		}
		else if (!mir_strcmp(xmli->name, "roleupdate")) {
			gcd.iType = GC_EVENT_ADDSTATUS;
			if (ezxml_t initiator = ezxml_child(xmli, "initiator")) {
				hContInitiator = MSN_HContactFromEmail(initiator->txt);
				gce.ptszText= GetContactNameT(hContInitiator);
			}
			gce.ptszStatus = _T("admin");
		}

		if (gcd.iType) {
			gce.time = MsnTSToUnixtime(ezxml_txt(ezxml_child(xmli, "eventtime")));
			const char *pszTarget = NULL;

			while (target) {
				switch (gcd.iType) {
				case GC_EVENT_JOIN:
					gce.ptszStatus = MSN_GCGetRole(MSN_GetThreadByChatId(mChatID), target->txt);
					// ..fall through.. //
				case GC_EVENT_KICK:
				case GC_EVENT_PART:
					pszTarget = target->txt;
					break;
				case GC_EVENT_ADDSTATUS:
				case GC_EVENT_REMOVESTATUS:
					gcd.iType = mir_strcmp(ezxml_txt(ezxml_child(target, "role")), "admin") == 0 ? GC_EVENT_ADDSTATUS : GC_EVENT_REMOVESTATUS;
					pszTarget = ezxml_txt(ezxml_child(target, "id"));
					break;
				}
				char *szEmail, *szNet;
				parseWLID(NEWSTR_ALLOCA(pszTarget), &szNet, &szEmail, NULL);
				gce.bIsMe = !mir_strcmpi(szEmail, GetMyUsername(atoi(szNet)));
				gce.ptszUID = mir_a2t(pszTarget);
				MCONTACT hContTarget = MSN_HContactFromEmail(pszTarget);
				gce.ptszNick = GetContactNameT(hContTarget);
				CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
				mir_free((TCHAR*)gce.ptszUID);
				if ((gcd.iType == GC_EVENT_PART || gcd.iType == GC_EVENT_KICK) && gce.bIsMe) {
					GCDEST gcd2 = { m_szModuleName, mChatID, GC_EVENT_CONTROL };
					GCEVENT gce2 = { sizeof(gce2), &gcd2 };
					CallServiceSync(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce2);
					break;
				}
				target = ezxml_next(target);
			}
		}
	}
}
Beispiel #29
0
int ContactStatusChanged(MCONTACT hContact, WORD oldStatus, WORD newStatus)
{
	if (opt.LogToDB && (!opt.LogToDB_WinOpen || CheckMsgWnd(hContact))) {
		wchar_t stzStatusText[MAX_SECONDLINE] = { 0 };
		GetStatusText(hContact, newStatus, oldStatus, stzStatusText);
		T2Utf blob(stzStatusText);

		DBEVENTINFO dbei = {};
		dbei.cbBlob = (DWORD)mir_strlen(blob) + 1;
		dbei.pBlob = (PBYTE)blob;
		dbei.eventType = EVENTTYPE_STATUSCHANGE;
		dbei.flags = DBEF_READ | DBEF_UTF;

		dbei.timestamp = (DWORD)time(0);
		dbei.szModule = MODULE;
		MEVENT hDBEvent = db_event_add(hContact, &dbei);

		if (opt.LogToDB_WinOpen && opt.LogToDB_Remove) {
			DBEVENT *dbevent = (DBEVENT *)mir_alloc(sizeof(DBEVENT));
			dbevent->hContact = hContact;
			dbevent->hDBEvent = hDBEvent;
			eventListStatus.insert(dbevent);
		}
	}

	bool bEnablePopup = true, bEnableSound = true;
	char *szProto = GetContactProto(hContact);
	int myStatus = Proto_GetStatus(szProto);

	if (!mir_strcmp(szProto, META_PROTO)) { //this contact is Meta
		MCONTACT hSubContact = db_mc_getMostOnline(hContact);
		char *szSubProto = GetContactProto(hSubContact);
		if (szSubProto == nullptr)
			return 0;

		if (newStatus == ID_STATUS_OFFLINE) {
			// read last online proto for metacontact if exists,
			// to avoid notifying when meta went offline but default contact's proto still online
			DBVARIANT dbv;
			if (!db_get_s(hContact, szProto, "LastOnline", &dbv)) {
				szSubProto = NEWSTR_ALLOCA(dbv.pszVal);
				db_free(&dbv);
			}
		}
		else
			db_set_s(hContact, szProto, "LastOnline", szSubProto);

		if (db_get_b(0, MODULE, szSubProto, 1) == 0)
			return 0;

		szProto = szSubProto;
	}
	else {
		if (myStatus == ID_STATUS_OFFLINE || db_get_b(0, MODULE, szProto, 1) == 0)
			return 0;
	}

	if (!opt.FromOffline || oldStatus != ID_STATUS_OFFLINE) { // Either it wasn't a change from Offline or we didn't enable that.
		char buff[8];
		mir_snprintf(buff, "%d", newStatus);
		if (db_get_b(0, MODULE, buff, 1) == 0)
			return 0; // "Notify when a contact changes to one of..." is unchecked
	}

	if (SkipHiddenContact(hContact))
		return 0;

	// check if that proto from which we received statuschange notification, isn't in autodisable list
	if (opt.AutoDisable) {
		char statusIDs[12], statusIDp[12];
		mir_snprintf(statusIDs, "s%d", myStatus);
		mir_snprintf(statusIDp, "p%d", myStatus);
		bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : TRUE;
		bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : TRUE;
	}

	if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) {
		int wStatus = Proto_GetStatus(szProto);
		wchar_t str[MAX_SECONDLINE] = { 0 };
		if (opt.ShowStatus)
			GetStatusText(hContact, newStatus, oldStatus, str);

		if (opt.ReadAwayMsg && wStatus != ID_STATUS_INVISIBLE && StatusHasAwayMessage(szProto, newStatus))
			db_set_ws(hContact, MODULE, "LastPopupText", str);

		PLUGINDATA *pdp = (PLUGINDATA *)mir_calloc(sizeof(PLUGINDATA));
		pdp->oldStatus = oldStatus;
		pdp->newStatus = newStatus;
		pdp->hAwayMsgHook = nullptr;
		pdp->hAwayMsgProcess = nullptr;
		ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, newStatus), newStatus, str, pdp);
	}

	if (opt.BlinkIcon && !opt.TempDisabled) {
		HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, newStatus) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE);
		wchar_t str[256];
		mir_snwprintf(str, TranslateT("%s is now %s"), Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText);
		BlinkIcon(hContact, hIcon, str);
	}

	if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) {
		if (oldStatus == ID_STATUS_OFFLINE)
			PlayChangeSound(hContact, StatusListEx[ID_STATUS_FROMOFFLINE].lpzSkinSoundName);
		else
			PlayChangeSound(hContact, StatusList[Index(newStatus)].lpzSkinSoundName);
	}

	if (opt.LogToFile) {
		wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN];

		GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime));
		GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate));
		mir_snwprintf(stzText, TranslateT("%s, %s. %s changed status to %s (was %s)\r\n"),
			stzDate, stzTime, Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText,
			StatusList[Index(oldStatus)].lpzStandardText);
		LogToFile(stzText);
	}

	return 0;
}
Beispiel #30
0
char* TScramAuth::getChallenge(const TCHAR *challenge)
{
	unsigned chlLen, saltLen = 0;
	ptrA snonce, salt;
	int ind = -1;

	ptrA chl((char*)mir_base64_decode(_T2A(challenge), &chlLen));

	for (char *p = strtok(NEWSTR_ALLOCA(chl), ","); p != NULL; p = strtok(NULL, ",")) {
		if (*p == 'r' && p[1] == '=') { // snonce
			if (strncmp(cnonce, p + 2, mir_strlen(cnonce)))
				return NULL;
			snonce = mir_strdup(p + 2);
		}
		else if (*p == 's' && p[1] == '=') // salt
			salt = (char*)mir_base64_decode(p + 2, &saltLen);
		else if (*p == 'i' && p[1] == '=')
			ind = atoi(p + 2);
	}

	if (snonce == NULL || salt == NULL || ind == -1)
		return NULL;

	ptrA passw(mir_utf8encodeT(info->conn.password));
	size_t passwLen = mir_strlen(passw);

	BYTE saltedPassw[MIR_SHA1_HASH_SIZE];
	Hi(saltedPassw, passw, passwLen, salt, saltLen, ind);

	BYTE clientKey[MIR_SHA1_HASH_SIZE];
	mir_hmac_sha1(clientKey, saltedPassw, sizeof(saltedPassw), (BYTE*)"Client Key", 10);

	BYTE storedKey[MIR_SHA1_HASH_SIZE];

	mir_sha1_ctx ctx;
	mir_sha1_init(&ctx);
	mir_sha1_append(&ctx, clientKey, MIR_SHA1_HASH_SIZE);
	mir_sha1_finish(&ctx, storedKey);

	char authmsg[4096];
	int authmsgLen = mir_snprintf(authmsg, _countof(authmsg), "%s,%s,c=biws,r=%s", msg1, chl, snonce);

	BYTE clientSig[MIR_SHA1_HASH_SIZE];
	mir_hmac_sha1(clientSig, storedKey, sizeof(storedKey), (BYTE*)authmsg, authmsgLen);

	BYTE clientProof[MIR_SHA1_HASH_SIZE];
	for (unsigned j = 0; j < sizeof(clientKey); j++)
		clientProof[j] = clientKey[j] ^ clientSig[j];

	/* Calculate the server signature */
	BYTE serverKey[MIR_SHA1_HASH_SIZE];
	mir_hmac_sha1(serverKey, saltedPassw, sizeof(saltedPassw), (BYTE*)"Server Key", 10);

	BYTE srvSig[MIR_SHA1_HASH_SIZE];
	mir_hmac_sha1(srvSig, serverKey, sizeof(serverKey), (BYTE*)authmsg, authmsgLen);
	serverSignature = mir_base64_encode((PBYTE)srvSig, sizeof(srvSig));

	char buf[4096];
	ptrA encproof(mir_base64_encode((PBYTE)clientProof, sizeof(clientProof)));
	int cbLen = mir_snprintf(buf, "c=biws,r=%s,p=%s", snonce, encproof);
	return mir_base64_encode((PBYTE)buf, cbLen);
}