char* directconnection::calcHashedNonce(UUID* nonce) { mir_sha1_ctx sha1ctx; BYTE sha[MIR_SHA1_HASH_SIZE]; mir_sha1_init(&sha1ctx); mir_sha1_append(&sha1ctx, (BYTE*)nonce, sizeof(UUID)); mir_sha1_finish(&sha1ctx, sha); char* p; UuidToStringA((UUID*)&sha, (BYTE**)&p); size_t len = strlen(p) + 3; char* result = (char*)mir_alloc(len); mir_snprintf(result, len, "{%s}", p); _strupr(result); RpcStringFreeA((BYTE**)&p); return result; }
INT_PTR __cdecl CJabberProto::JabberSetAvatar(WPARAM, LPARAM lParam) { TCHAR *tszFileName = (TCHAR*)lParam; if (m_bJabberOnline) { SetServerVcard(TRUE, tszFileName); SendPresence(m_iDesiredStatus, false); } else if (tszFileName == NULL || tszFileName[0] == 0) { // Remove avatar TCHAR tFileName[ MAX_PATH ]; GetAvatarFileName(NULL, tFileName, MAX_PATH); DeleteFile(tFileName); delSetting("AvatarSaved"); delSetting("AvatarHash"); } else { int fileIn = _topen(tszFileName, O_RDWR | O_BINARY, S_IREAD | S_IWRITE); if (fileIn == -1) { mir_free(tszFileName); return 1; } long dwPngSize = _filelength(fileIn); char *pResult = new char[ dwPngSize ]; if (pResult == NULL) { _close(fileIn); mir_free(tszFileName); return 2; } _read(fileIn, pResult, dwPngSize); _close(fileIn); BYTE digest[MIR_SHA1_HASH_SIZE]; mir_sha1_ctx sha1ctx; mir_sha1_init(&sha1ctx); mir_sha1_append(&sha1ctx, (BYTE*)pResult, dwPngSize); mir_sha1_finish(&sha1ctx, digest); TCHAR tFileName[MAX_PATH]; GetAvatarFileName(NULL, tFileName, MAX_PATH); DeleteFile(tFileName); char buf[MIR_SHA1_HASH_SIZE*2+1]; bin2hex(digest, sizeof(digest), buf); m_options.AvatarType = ProtoGetBufferFormat(pResult); GetAvatarFileName(NULL, tFileName, MAX_PATH); FILE *out = _tfopen(tFileName, _T("wb")); if (out != NULL) { fwrite(pResult, dwPngSize, 1, out); fclose(out); } delete[] pResult; setString("AvatarSaved", buf); } return 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); }
BOOL SendPicture(TlenProtocol *proto, MCONTACT hContact) { DBVARIANT dbv; if (!db_get(hContact, proto->m_szModuleName, "jid", &dbv)) { char *jid = dbv.pszVal; char szFilter[512]; char *szFileName = (char*) mir_alloc(_MAX_PATH); OPENFILENAMEA ofn = {0}; CallService(MS_UTILS_GETBITMAPFILTERSTRINGS, ( WPARAM ) sizeof( szFilter ), ( LPARAM )szFilter ); ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = NULL; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = NULL; ofn.lpstrFile = szFileName; ofn.nMaxFile = _MAX_PATH; ofn.Flags = OFN_FILEMUSTEXIST; szFileName[0] = '\0'; if ( GetOpenFileNameA( &ofn )) { long size; FILE* fp = fopen( szFileName, "rb" ); if (fp) { fseek(fp, 0, SEEK_END); size = ftell(fp); if (size > 0 && size < 256*1024) { TLEN_LIST_ITEM *item; mir_sha1_ctx sha; DWORD digest[5]; int i; char idStr[10]; char fileBuffer[2048]; int id = TlenSerialNext(proto); mir_snprintf(idStr, sizeof(idStr), "%d", id); item = TlenListAdd(proto, LIST_PICTURE, idStr); item->ft = TlenFileCreateFT(proto, jid); item->ft->files = (char **) mir_alloc(sizeof(char *)); item->ft->filesSize = (long *) mir_alloc(sizeof(long)); item->ft->files[0] = szFileName; item->ft->filesSize[0] = size; item->ft->fileTotalSize = size; fseek(fp, 0, SEEK_SET); mir_sha1_init( &sha ); for (i = item->ft->filesSize[0]; i > 0; ) { int toread = min(2048, i); int readcount = (int)fread(fileBuffer, (size_t)1, (size_t)toread, fp); i -= readcount; if (readcount > 0) { mir_sha1_append( &sha, (BYTE* )fileBuffer, readcount); } if (toread != readcount) { break; } } mir_sha1_finish( &sha, (BYTE* )digest ); TlenSend(proto, "<message type='pic' to='%s' crc='%08x%08x%08x%08x%08x' idt='%s' size='%d' ext='%s'/>", jid, (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4]), idStr, item->ft->filesSize[0], "jpg"); } else { /* file too big */ } fclose(fp); } } db_free(&dbv); } return FALSE; }
void CJabberProto::SetServerVcard(BOOL bPhotoChanged, TCHAR* szPhotoFileName) { if (!m_bJabberOnline) return; int i; char idstr[33]; XmlNodeIq iq(AddIQ(&CJabberProto::OnIqResultSetVcard, JABBER_IQ_TYPE_SET)); HXML v = iq << XCHILDNS(_T("vCard"), JABBER_FEAT_VCARD_TEMP); AppendVcardFromDB(v, "FN", "FullName"); HXML n = v << XCHILD(_T("N")); AppendVcardFromDB(n, "GIVEN", "FirstName"); AppendVcardFromDB(n, "MIDDLE", "MiddleName"); AppendVcardFromDB(n, "FAMILY", "LastName"); AppendVcardFromDB(v, "NICKNAME", "Nick"); AppendVcardFromDB(v, "BDAY", "BirthDate"); AppendVcardFromDB(v, "GENDER", "GenderString"); for (i = 0;; i++) { mir_snprintf(idstr, "e-mail%d", i); ptrT email(getTStringA(idstr)); if (email == NULL) break; HXML e = v << XCHILD(_T("EMAIL"), email); AppendVcardFromDB(e, "USERID", idstr); mir_snprintf(idstr, "e-mailFlag%d", i); WORD nFlag = getWord(idstr, 0); if (nFlag & JABBER_VCEMAIL_HOME) e << XCHILD(_T("HOME")); if (nFlag & JABBER_VCEMAIL_WORK) e << XCHILD(_T("WORK")); if (nFlag & JABBER_VCEMAIL_INTERNET) e << XCHILD(_T("INTERNET")); if (nFlag & JABBER_VCEMAIL_X400) e << XCHILD(_T("X400")); } n = v << XCHILD(_T("ADR")); n << XCHILD(_T("HOME")); AppendVcardFromDB(n, "STREET", "Street"); AppendVcardFromDB(n, "EXTADR", "Street2"); AppendVcardFromDB(n, "EXTADD", "Street2"); // for compatibility with client using old vcard format AppendVcardFromDB(n, "LOCALITY", "City"); AppendVcardFromDB(n, "REGION", "State"); AppendVcardFromDB(n, "PCODE", "ZIP"); AppendVcardFromDB(n, "CTRY", "Country"); AppendVcardFromDB(n, "COUNTRY", "Country"); // for compatibility with client using old vcard format n = v << XCHILD(_T("ADR")); n << XCHILD(_T("WORK")); AppendVcardFromDB(n, "STREET", "CompanyStreet"); AppendVcardFromDB(n, "EXTADR", "CompanyStreet2"); AppendVcardFromDB(n, "EXTADD", "CompanyStreet2"); // for compatibility with client using old vcard format AppendVcardFromDB(n, "LOCALITY", "CompanyCity"); AppendVcardFromDB(n, "REGION", "CompanyState"); AppendVcardFromDB(n, "PCODE", "CompanyZIP"); AppendVcardFromDB(n, "CTRY", "CompanyCountry"); AppendVcardFromDB(n, "COUNTRY", "CompanyCountry"); // for compatibility with client using old vcard format n = v << XCHILD(_T("ORG")); AppendVcardFromDB(n, "ORGNAME", "Company"); AppendVcardFromDB(n, "ORGUNIT", "CompanyDepartment"); AppendVcardFromDB(v, "TITLE", "CompanyPosition"); AppendVcardFromDB(v, "ROLE", "Role"); AppendVcardFromDB(v, "URL", "Homepage"); AppendVcardFromDB(v, "DESC", "About"); for (i = 0;; i++) { mir_snprintf(idstr, "Phone%d", i); ptrT phone(getTStringA(idstr)); if (phone == NULL) break; n = v << XCHILD(_T("TEL")); AppendVcardFromDB(n, "NUMBER", idstr); mir_snprintf(idstr, "PhoneFlag%d", i); WORD nFlag = getWord(idstr, 0); if (nFlag & JABBER_VCTEL_HOME) n << XCHILD(_T("HOME")); if (nFlag & JABBER_VCTEL_WORK) n << XCHILD(_T("WORK")); if (nFlag & JABBER_VCTEL_VOICE) n << XCHILD(_T("VOICE")); if (nFlag & JABBER_VCTEL_FAX) n << XCHILD(_T("FAX")); if (nFlag & JABBER_VCTEL_PAGER) n << XCHILD(_T("PAGER")); if (nFlag & JABBER_VCTEL_MSG) n << XCHILD(_T("MSG")); if (nFlag & JABBER_VCTEL_CELL) n << XCHILD(_T("CELL")); if (nFlag & JABBER_VCTEL_VIDEO) n << XCHILD(_T("VIDEO")); if (nFlag & JABBER_VCTEL_BBS) n << XCHILD(_T("BBS")); if (nFlag & JABBER_VCTEL_MODEM) n << XCHILD(_T("MODEM")); if (nFlag & JABBER_VCTEL_ISDN) n << XCHILD(_T("ISDN")); if (nFlag & JABBER_VCTEL_PCS) n << XCHILD(_T("PCS")); } TCHAR szAvatarName[MAX_PATH], *szFileName; GetAvatarFileName(NULL, szAvatarName, _countof(szAvatarName)); if (bPhotoChanged) szFileName = szPhotoFileName; else szFileName = szAvatarName; // Set photo element, also update the global jabberVcardPhotoFileName to reflect the update debugLog(_T("Before update, file name = %s"), szFileName); if (szFileName == NULL || szFileName[0] == 0) { v << XCHILD(_T("PHOTO")); DeleteFile(szAvatarName); delSetting("AvatarSaved"); delSetting("AvatarHash"); } else { debugLog(_T("Saving picture from %s"), szFileName); struct _stat st; if (_tstat(szFileName, &st) >= 0) { // Note the FILE_SHARE_READ attribute so that the CopyFile can succeed HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { ptrA buffer((char*)mir_alloc(st.st_size)); if (buffer != NULL) { DWORD nRead; if (ReadFile(hFile, buffer, st.st_size, &nRead, NULL)) { ptrA str(mir_base64_encode((PBYTE)(LPSTR)buffer, nRead)); if (str != NULL) { n = v << XCHILD(_T("PHOTO")); TCHAR *szFileType; switch (ProtoGetBufferFormat(buffer)) { case PA_FORMAT_PNG: szFileType = _T("image/png"); break; case PA_FORMAT_GIF: szFileType = _T("image/gif"); break; case PA_FORMAT_BMP: szFileType = _T("image/bmp"); break; default: szFileType = _T("image/jpeg"); break; } n << XCHILD(_T("TYPE"), szFileType); n << XCHILD(_T("BINVAL"), _A2T(str)); // NEED TO UPDATE OUR AVATAR HASH: BYTE digest[MIR_SHA1_HASH_SIZE]; mir_sha1_ctx sha1ctx; mir_sha1_init(&sha1ctx); mir_sha1_append(&sha1ctx, (BYTE*)(LPSTR)buffer, nRead); mir_sha1_finish(&sha1ctx, digest); char buf[MIR_SHA1_HASH_SIZE * 2 + 1]; bin2hex(digest, sizeof(digest), buf); m_options.AvatarType = ProtoGetBufferFormat(buffer); if (bPhotoChanged) { DeleteFile(szAvatarName); GetAvatarFileName(NULL, szAvatarName, _countof(szAvatarName)); CopyFile(szFileName, szAvatarName, FALSE); } setString("AvatarHash", buf); setString("AvatarSaved", buf); } } } CloseHandle(hFile); } } } m_ThreadInfo->send(iq); }
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; }