char* TScramAuth::getInitialRequest() { T2Utf uname(info->conn.username); unsigned char nonce[24]; Utils_GetRandom(nonce, sizeof(nonce)); cnonce = mir_base64_encode((PBYTE)nonce, sizeof(nonce)); char buf[4096]; int cbLen = mir_snprintf(buf, "n,,n=%s,r=%s", uname, cnonce); msg1 = mir_strdup(buf + 3); return mir_base64_encode((PBYTE)buf, cbLen); }
void FacebookProto::StickerAsSmiley(std::string sticker, const std::string &url, MCONTACT hContact) { std::string b64 = ptrA(mir_base64_encode((PBYTE)sticker.c_str(), (unsigned)sticker.length())); b64 = utils::url::encode(b64); std::tstring filename = GetAvatarFolder() + _T("\\stickers\\"); ptrT dir(mir_tstrdup(filename.c_str())); filename += (TCHAR*)_A2T(b64.c_str()); filename += _T(".png"); // Check if we have this sticker already and download it it not if (GetFileAttributes(filename.c_str()) == INVALID_FILE_ATTRIBUTES) { HANDLE nlc = NULL; facy.save_url(url, filename, nlc); Netlib_CloseHandle(nlc); } SMADD_CONT cont; cont.cbSize = sizeof(SMADD_CONT); cont.hContact = hContact; cont.type = 0; cont.path = dir; CallService(MS_SMILEYADD_LOADCONTACTSMILEYS, 0, (LPARAM)&cont); }
// Adds new contact DWORD CMraProto::MraAddContact(MCONTACT hContact, DWORD dwContactFlag, DWORD dwGroupID, const CMStringA &szEmail, const CMStringW &wszCustomName, const CMStringA *szPhones, const CMString* wszAuthMessage) { if (szEmail.GetLength() <= 4 && !(dwContactFlag & CONTACT_FLAG_GROUP)) return 0; dwContactFlag |= CONTACT_FLAG_UNICODE_NAME; if (dwGroupID == -1) dwGroupID = 0; OutBuffer buf; buf.SetUL(dwContactFlag); buf.SetUL(dwGroupID); buf.SetLPSLowerCase(szEmail); buf.SetLPSW(wszCustomName); buf.SetLPS((szPhones == NULL) ? "" : *szPhones); // pack auth message OutBuffer buf2; buf2.SetUL(2); buf2.SetLPSW(_T(""));//***deb possible nick here buf2.SetLPSW((wszAuthMessage == NULL) ? _T("") : *wszAuthMessage); buf.SetLPS(CMStringA(ptrA(mir_base64_encode(buf2.Data(), (int)buf2.Len())))); buf.SetUL(0); return MraSendQueueCMD(hSendQueueHandle, 0, hContact, ACKTYPE_ADDED, NULL, 0, MRIM_CS_ADD_CONTACT, buf.Data(), buf.Len()); }
void CreateAuthString(char *auth, MCONTACT hContact, HWND hwndDlg) { DBVARIANT dbv; char *user = NULL, *pass = NULL; TCHAR *tlogin = NULL, *tpass = NULL, buf[MAX_PATH] = {0}; if (hContact && db_get_b(hContact, MODULE, "UseAuth", 0)) { if (!db_get_ts(hContact, MODULE, "Login", &dbv)) { tlogin = mir_tstrdup(dbv.ptszVal); db_free(&dbv); } tpass = db_get_tsa(hContact, MODULE, "Password"); } else if (hwndDlg && IsDlgButtonChecked(hwndDlg, IDC_USEAUTH)) { GetDlgItemText(hwndDlg, IDC_LOGIN, buf, SIZEOF(buf)); tlogin = mir_tstrdup(buf); GetDlgItemText(hwndDlg, IDC_PASSWORD, buf, SIZEOF(buf)); tpass = mir_tstrdup(buf); } user = mir_t2a(tlogin); pass = mir_t2a(tpass); char str[MAX_PATH]; int len = mir_snprintf(str, SIZEOF(str), "%s:%s", user, pass); mir_free(user); mir_free(pass); mir_free(tlogin); mir_free(tpass); mir_snprintf(auth, 250, "Basic %s", ptrA(mir_base64_encode((PBYTE)str, len))); }
void CSteamProto::OnGotRsaKey(const HttpResponse *response) { if (!CheckResponse(response)) return; // load rsa key parts JSONNode root = JSONNode::parse(response->pData); if (!root) return; if (!root["success"].as_bool()) return; std::string modulus = root["publickey_mod"].as_string(); // exponent "010001" is used as constant in CSteamProto::RsaEncrypt //std::string exponent = root["publickey_exp"].as_string(); std::string timestamp = root["timestamp"].as_string(); // encrcrypt password ptrA base64RsaEncryptedPassword; ptrA szPassword(getStringA("Password")); DWORD error = 0; DWORD encryptedSize = 0; if ((error = RsaEncrypt(modulus.c_str(), szPassword, NULL, encryptedSize)) != 0) { debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error); return; } BYTE *encryptedPassword = (BYTE*)mir_calloc(encryptedSize); if ((error = RsaEncrypt(modulus.c_str(), szPassword, encryptedPassword, encryptedSize)) != 0) { debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error); return; } base64RsaEncryptedPassword = mir_base64_encode(encryptedPassword, encryptedSize); mir_free(encryptedPassword); // run authorization request T2Utf username(getTStringA("Username")); ptrA guardId(getStringA("GuardId")); if (!guardId) guardId = mir_strdup(""); ptrA guardCode(getStringA("GuardCode")); if (!guardCode) guardCode = mir_strdup(""); ptrA captchaId(getStringA("CaptchaId")); if (!captchaId) captchaId = mir_strdup("-1"); ptrA captchaText(getStringA("CaptchaText")); if (!captchaText) captchaText = mir_strdup(""); PushRequest( new AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp.c_str(), "", guardCode, guardId, captchaId, captchaText), &CSteamProto::OnAuthorization); }
void fill_session_url(CMStringA &buf, CMStringA &token, CMStringA &secret, time_t &hosttime, const char *password, bool encryption) { /* AIM_SESSION_URL?query_string?sig_sha256=signature */ CMStringA query_string; query_string.Format("a=%s&distId=%s&f=xml&k=%s&ts=%llu&useTLS=%d", token, AIM_DEFAULT_DISTID, AIM_DEFAULT_CLIENT_KEY, hosttime, (int)encryption); BYTE session_key[MIR_SHA256_HASH_SIZE], signature[MIR_SHA256_HASH_SIZE]; mir_hmac_sha256(session_key, (BYTE*)password, mir_strlen(password), (BYTE*)secret.GetString(), secret.GetLength()); ptrA szKey(mir_base64_encode(session_key, sizeof(session_key))); generate_signature(signature, "GET", AIM_SESSION_URL, query_string, szKey); ptrA szEncoded(mir_base64_encode(signature, sizeof(signature))); buf.Format("%s?%s&sig_sha256=%s", AIM_SESSION_URL, query_string, (char*)szEncoded); }
// encrypt string using KeyX, return encoded string as ASCII or NULL LPSTR __cdecl cpp_encrypt(pCNTX ptr, LPCSTR szPlainMsg) { ptr->error = ERROR_NONE; pSIMDATA p = (pSIMDATA)ptr->pdata; BYTE dataflag = 0; size_t slen = strlen(szPlainMsg); LPSTR szMsg; if (ptr->features & FEATURES_GZIP) { size_t clen; szMsg = (LPSTR)cpp_gzip((BYTE*)szPlainMsg, slen, clen); if (clen >= slen) { free(szMsg); szMsg = _strdup(szPlainMsg); } else { slen = clen; dataflag |= DATA_GZIP; } } else szMsg = _strdup(szPlainMsg); string ciphered; CBC_Mode<AES>::Encryption enc(p->KeyX, Tiger::DIGESTSIZE, IV); StreamTransformationFilter cbcEncryptor(enc, new StringSink(ciphered)); cbcEncryptor.Put((PBYTE)szMsg, slen); cbcEncryptor.MessageEnd(); free(szMsg); unsigned clen = (unsigned)ciphered.length(); if (ptr->features & FEATURES_CRC32) { BYTE crc32[CRC32::DIGESTSIZE]; memset(crc32, 0, sizeof(crc32)); CRC32().CalculateDigest(crc32, (BYTE*)ciphered.data(), clen); ciphered.insert(0, (LPSTR)&crc32, CRC32::DIGESTSIZE); ciphered.insert(0, (LPSTR)&clen, 2); } if (ptr->features & FEATURES_GZIP) ciphered.insert(0, (LPSTR)&dataflag, 1); clen = (unsigned)ciphered.length(); if (ptr->features & FEATURES_BASE64) replaceStr(ptr->tmp, mir_base64_encode((PBYTE)ciphered.data(), clen)); else replaceStr(ptr->tmp, base16encode(ciphered.data(), clen)); return ptr->tmp; }
char* TPlainAuth::getInitialRequest() { T2Utf uname(info->conn.username), passw(info->conn.password); size_t size = 2 * mir_strlen(uname) + mir_strlen(passw) + mir_strlen(info->conn.server) + 4; char *toEncode = (char*)alloca(size); if (bOld) size = mir_snprintf(toEncode, size, "%s@%s%c%s%c%s", uname, info->conn.server, 0, uname, 0, passw); else size = mir_snprintf(toEncode, size, "%c%s%c%s", 0, uname, 0, passw); return mir_base64_encode((PBYTE)toEncode, (int)size); }
BOOL CJabberProto::OnIqRequestAvatar(HXML, CJabberIqInfo *pInfo) { if (!m_options.EnableAvatars) return TRUE; int pictureType = m_options.AvatarType; if (pictureType == PA_FORMAT_UNKNOWN) return TRUE; TCHAR *szMimeType; switch (pictureType) { case PA_FORMAT_JPEG: szMimeType = _T("image/jpeg"); break; case PA_FORMAT_GIF: szMimeType = _T("image/gif"); break; case PA_FORMAT_PNG: szMimeType = _T("image/png"); break; case PA_FORMAT_BMP: szMimeType = _T("image/bmp"); break; default: return TRUE; } TCHAR szFileName[MAX_PATH]; GetAvatarFileName(NULL, szFileName, _countof(szFileName)); FILE* in = _tfopen(szFileName, _T("rb")); if (in == NULL) return TRUE; long bytes = _filelength(_fileno(in)); ptrA buffer((char*)mir_alloc(bytes * 4 / 3 + bytes + 1000)); if (buffer == NULL) { fclose(in); return TRUE; } fread(buffer, bytes, 1, in); fclose(in); ptrA str(mir_base64_encode((PBYTE)(char*)buffer, bytes)); m_ThreadInfo->send(XmlNodeIq(_T("result"), pInfo) << XQUERY(JABBER_FEAT_AVATAR) << XCHILD(_T("query"), _A2T(str)) << XATTR(_T("mimetype"), szMimeType)); return TRUE; }
char* TMD5Auth::getChallenge(const TCHAR *challenge) { if (iCallCount > 0) return NULL; iCallCount++; unsigned resultLen; ptrA text((char*)mir_base64_decode( _T2A(challenge), &resultLen)); TStringPairs pairs(text); const char *realm = pairs["realm"], *nonce = pairs["nonce"]; char cnonce[40], tmpBuf[40]; DWORD digest[4], hash1[4], hash2[4]; mir_md5_state_t ctx; Utils_GetRandom(digest, sizeof(digest)); mir_snprintf(cnonce, _countof(cnonce), "%08x%08x%08x%08x", htonl(digest[0]), htonl(digest[1]), htonl(digest[2]), htonl(digest[3])); T2Utf uname(info->conn.username), passw(info->conn.password); ptrA serv(mir_utf8encode(info->conn.server)); mir_md5_init(&ctx); mir_md5_append(&ctx, (BYTE*)(char*)uname, (int)mir_strlen(uname)); mir_md5_append(&ctx, (BYTE*)":", 1); mir_md5_append(&ctx, (BYTE*)realm, (int)mir_strlen(realm)); mir_md5_append(&ctx, (BYTE*)":", 1); mir_md5_append(&ctx, (BYTE*)(char*)passw, (int)mir_strlen(passw)); mir_md5_finish(&ctx, (BYTE*)hash1); mir_md5_init(&ctx); mir_md5_append(&ctx, (BYTE*)hash1, 16); mir_md5_append(&ctx, (BYTE*)":", 1); mir_md5_append(&ctx, (BYTE*)nonce, (int)mir_strlen(nonce)); mir_md5_append(&ctx, (BYTE*)":", 1); mir_md5_append(&ctx, (BYTE*)cnonce, (int)mir_strlen(cnonce)); mir_md5_finish(&ctx, (BYTE*)hash1); mir_md5_init(&ctx); mir_md5_append(&ctx, (BYTE*)"AUTHENTICATE:xmpp/", 18); mir_md5_append(&ctx, (BYTE*)(char*)serv, (int)mir_strlen(serv)); mir_md5_finish(&ctx, (BYTE*)hash2); mir_md5_init(&ctx); mir_snprintf(tmpBuf, _countof(tmpBuf), "%08x%08x%08x%08x", htonl(hash1[0]), htonl(hash1[1]), htonl(hash1[2]), htonl(hash1[3])); mir_md5_append(&ctx, (BYTE*)tmpBuf, (int)mir_strlen(tmpBuf)); mir_md5_append(&ctx, (BYTE*)":", 1); mir_md5_append(&ctx, (BYTE*)nonce, (int)mir_strlen(nonce)); mir_snprintf(tmpBuf, _countof(tmpBuf), ":%08d:", iCallCount); mir_md5_append(&ctx, (BYTE*)tmpBuf, (int)mir_strlen(tmpBuf)); mir_md5_append(&ctx, (BYTE*)cnonce, (int)mir_strlen(cnonce)); mir_md5_append(&ctx, (BYTE*)":auth:", 6); mir_snprintf(tmpBuf, _countof(tmpBuf), "%08x%08x%08x%08x", htonl(hash2[0]), htonl(hash2[1]), htonl(hash2[2]), htonl(hash2[3])); mir_md5_append(&ctx, (BYTE*)tmpBuf, (int)mir_strlen(tmpBuf)); mir_md5_finish(&ctx, (BYTE*)digest); char *buf = (char*)alloca(8000); int cbLen = mir_snprintf(buf, 8000, "username=\"%s\",realm=\"%s\",nonce=\"%s\",cnonce=\"%s\",nc=%08d," "qop=auth,digest-uri=\"xmpp/%s\",charset=utf-8,response=%08x%08x%08x%08x", uname, realm, nonce, cnonce, iCallCount, serv, htonl(digest[0]), htonl(digest[1]), htonl(digest[2]), htonl(digest[3])); return mir_base64_encode((PBYTE)buf, cbLen); }
string base64encode(const string& buf) { return (char*)ptrA(mir_base64_encode((PBYTE)buf.data(), (unsigned)buf.length())); }
DWORD CMraProto::MraMessage(BOOL bAddToQueue, MCONTACT hContact, DWORD dwAckType, DWORD dwFlags, const CMStringA &szEmail, const CMStringW &lpwszMessage, LPBYTE lpbMultiChatData, size_t dwMultiChatDataSize) { debugLogA("Sending message: flags %08x, to '%S', message '%S'\n", dwFlags, szEmail, lpwszMessage); DWORD dwRet = 0; LPSTR lpszMessageConverted = (LPSTR)lpwszMessage.GetString(); LPSTR lpszMessageRTF = NULL; size_t dwMessageConvertedSize = lpwszMessage.GetLength()*sizeof(WCHAR), dwMessageRTFSize = 0; if (MraIsMessageFlashAnimation(lpwszMessage)) dwFlags |= MESSAGE_FLAG_FLASH; // pack auth message if (dwFlags & MESSAGE_FLAG_AUTHORIZE) { OutBuffer buf; buf.SetUL(2); buf.SetLPSW(_T(""));//***deb possible nick here buf.SetLPSW(lpwszMessage); lpszMessageConverted = mir_base64_encode(buf.Data(), (int)buf.Len()); dwMessageConvertedSize = mir_strlen(lpszMessageConverted); } // messages with Flash else if (dwFlags & MESSAGE_FLAG_FLASH) { dwFlags |= MESSAGE_FLAG_RTF; CMStringA lpszBuf(mir_u2a(lpwszMessage)); OutBuffer buf; buf.SetUL(4); buf.SetLPS(lpszBuf);// сообщение что у собеседника плохая версия :) buf.SetUL(4); buf.SetUL(getDword("RTFBackgroundColour", MRA_DEFAULT_RTF_BACKGROUND_COLOUR)); buf.SetLPS(lpszBuf);// сам мульт ANSI buf.SetLPSW(lpwszMessage);// сам мульт UNICODE DWORD dwBufSize = DWORD(buf.Len() + 128); lpszBuf.Truncate(dwBufSize); if (compress2((LPBYTE)(LPCSTR)lpszBuf, &dwBufSize, buf.Data(), (int)buf.Len(), Z_BEST_COMPRESSION) == Z_OK) { lpszMessageRTF = mir_base64_encode((LPBYTE)(LPCSTR)lpszBuf, dwBufSize); dwMessageRTFSize = mir_strlen(lpszMessageRTF); } } // standart message else if ((dwFlags & (MESSAGE_FLAG_CONTACT | MESSAGE_FLAG_NOTIFY | MESSAGE_FLAG_SMS)) == 0) { // Only if message is simple text message or RTF or ALARM if (dwFlags & MESSAGE_FLAG_RTF) { // add RFT part CMStringA lpbRTFData; lpbRTFData.Truncate(lpwszMessage.GetLength() * 16 + 4096); if (!MraConvertToRTFW(lpwszMessage, lpbRTFData)) { DWORD dwBackColour = getDword("RTFBackgroundColour", MRA_DEFAULT_RTF_BACKGROUND_COLOUR); OutBuffer buf; buf.SetUL(2); buf.SetLPS(lpbRTFData); buf.SetUL(4); buf.SetUL(dwBackColour); DWORD dwRTFDataSize = lpbRTFData.GetLength(); if (compress2((LPBYTE)(LPCSTR)lpbRTFData, &dwRTFDataSize, buf.Data(), (int)buf.Len(), Z_BEST_COMPRESSION) == Z_OK) { lpszMessageRTF = mir_base64_encode((LPBYTE)(LPCSTR)lpbRTFData, dwRTFDataSize); dwMessageRTFSize = mir_strlen(lpszMessageRTF); } } } } if (lpszMessageRTF == NULL || dwMessageRTFSize == 0) dwFlags &= ~(MESSAGE_FLAG_RTF | MESSAGE_FLAG_FLASH); if (lpbMultiChatData == NULL || dwMultiChatDataSize == 0) dwFlags &= ~MESSAGE_FLAG_MULTICHAT; OutBuffer buf; buf.SetUL(dwFlags); buf.SetLPSLowerCase(szEmail); buf.SetLPS(CMStringA(lpszMessageConverted, (int)dwMessageConvertedSize)); buf.SetLPS(lpszMessageRTF); if (dwFlags & MESSAGE_FLAG_MULTICHAT) buf.SetLPS(CMStringA((LPSTR)lpbMultiChatData, (int)dwMultiChatDataSize)); if (bAddToQueue) dwRet = MraSendQueueCMD(hSendQueueHandle, 0, hContact, dwAckType, NULL, 0, MRIM_CS_MESSAGE, buf.Data(), buf.Len()); else dwRet = MraSendCMD(MRIM_CS_MESSAGE, buf.Data(), buf.Len()); return dwRet; }
std::string b64encode(const std::string &s) { return std::string( ptrA( mir_base64_encode((BYTE*)s.c_str(), (unsigned)s.length()))); }
std::string base64_encode(void* pData, size_t len) { return (char*)ptrA(mir_base64_encode((BYTE*)pData, (unsigned)len)); }
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); }
HANDLE WhatsAppProto::SendFile(MCONTACT hContact, const TCHAR* desc, TCHAR **ppszFiles) { if (!isOnline()) return 0; ptrA jid(getStringA(hContact, "ID")); if (jid == NULL) return 0; // input validation char *name = mir_utf8encodeW(ppszFiles[0]); string mime = MediaUploader::getMimeFromExtension(split(name, '.')[1]); if (mime.empty()) return 0; // get file size FILE *hFile = _tfopen(ppszFiles[0], _T("rb")); if (hFile == NULL) { debugLogA(__FUNCTION__": cannot open file %s", ppszFiles[0]); return 0; } _fseeki64(hFile, 0, SEEK_END); uint64_t fileSize = _ftelli64(hFile); fclose(hFile); // get filetype from mimeType int fileType = FMessage::getMessage_WA_Type(split(mime, '/')[0]); // check max file sizes switch (fileType) { case FMessage::WA_TYPE_IMAGE: if (fileSize >= 5 * 1024 * 1024) return 0; break; case FMessage::WA_TYPE_AUDIO: if (fileSize >= 10 * 1024 * 1024) return 0; break; case FMessage::WA_TYPE_VIDEO: if (fileSize >= 20 * 1024 * 1024) return 0; break; default: return 0; } int msgId = GetSerial(); time_t now = time(NULL); std::string msgid = Utilities::intToStr(now) + "-" + Utilities::intToStr(msgId); FMessage * fmsg = new FMessage(std::string(jid), true, msgid); fmsg->media_url = name; fmsg->media_size = fileSize; fmsg->media_wa_type = fileType; fmsg->data = mir_utf8encodeW(desc); // calculate file hash unsigned char hash[MIR_SHA256_HASH_SIZE]; SHA256_CONTEXT sha256; mir_sha256_init(&sha256); FILE *fd = _tfopen(ppszFiles[0], _T("rb")); int read = 0; do { char buf[1024]; read = (int)fread(buf, 1, 1024, fd); mir_sha256_write(&sha256, buf, read); } while (read > 0); fclose(fd); mir_sha256_final(&sha256, hash); fmsg->media_name = mir_base64_encode((BYTE*)hash,sizeof(hash)); // request media upload url m_pConnection->sendMessage(fmsg); return (HANDLE)fmsg; // TODO what to return here to make the upload shown complete when done and how to handle errors? }
char* NtlmCreateResponseFromChallenge(HANDLE hSecurity, const char *szChallenge, const TCHAR* login, const TCHAR* psw, bool http, unsigned& complete) { if (hSecurity == NULL || ntlmCnt == 0) return NULL; SecBufferDesc outputBufferDescriptor, inputBufferDescriptor; SecBuffer outputSecurityToken, inputSecurityToken; TimeStamp tokenExpiration; ULONG contextAttributes; char *szOutputToken; NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity; if (mir_tstrcmpi(hNtlm->szProvider, _T("Basic"))) { bool isGSSAPI = mir_tstrcmpi(hNtlm->szProvider, _T("GSSAPI")) == 0; TCHAR *szProvider = isGSSAPI ? (TCHAR*)_T("Kerberos") : hNtlm->szProvider; bool hasChallenge = szChallenge != NULL && szChallenge[0] != '\0'; if (hasChallenge) { unsigned tokenLen; BYTE *token = (BYTE*)mir_base64_decode(szChallenge, &tokenLen); if (token == NULL) return NULL; if (isGSSAPI && complete) return CompleteGssapi(hSecurity, token, tokenLen); inputBufferDescriptor.cBuffers = 1; inputBufferDescriptor.pBuffers = &inputSecurityToken; inputBufferDescriptor.ulVersion = SECBUFFER_VERSION; inputSecurityToken.BufferType = SECBUFFER_TOKEN; inputSecurityToken.cbBuffer = tokenLen; inputSecurityToken.pvBuffer = token; // try to decode the domain name from the NTLM challenge if (login != NULL && login[0] != '\0' && !hNtlm->hasDomain) { NtlmType2packet* pkt = (NtlmType2packet*)token; if (!strncmp(pkt->sign, "NTLMSSP", 8) && pkt->type == 2) { wchar_t* domainName = (wchar_t*)&token[pkt->targetName.offset]; int domainLen = pkt->targetName.len; // Negotiate ANSI? if yes, convert the ANSI name to unicode if ((pkt->flags & 1) == 0) { int bufsz = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, NULL, 0); wchar_t* buf = (wchar_t*)alloca(bufsz * sizeof(wchar_t)); domainLen = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, buf, bufsz) - 1; domainName = buf; } else domainLen /= sizeof(wchar_t); if (domainLen) { size_t newLoginLen = mir_tstrlen(login) + domainLen + 1; TCHAR *newLogin = (TCHAR*)alloca(newLoginLen * sizeof(TCHAR)); _tcsncpy(newLogin, domainName, domainLen); newLogin[domainLen] = '\\'; mir_tstrcpy(newLogin + domainLen + 1, login); char* szChl = NtlmCreateResponseFromChallenge(hSecurity, NULL, newLogin, psw, http, complete); mir_free(szChl); } } } } else { if (SecIsValidHandle(&hNtlm->hClientContext)) DeleteSecurityContext(&hNtlm->hClientContext); if (SecIsValidHandle(&hNtlm->hClientCredential)) FreeCredentialsHandle(&hNtlm->hClientCredential); SEC_WINNT_AUTH_IDENTITY auth; if (login != NULL && login[0] != '\0') { memset(&auth, 0, sizeof(auth)); NetlibLogf(NULL, "Security login requested, user: %S pssw: %s", login, psw ? "(exist)" : "(no psw)"); const TCHAR* loginName = login; const TCHAR* domainName = _tcschr(login, '\\'); size_t domainLen = 0; size_t loginLen = mir_tstrlen(loginName); if (domainName != NULL) { loginName = domainName + 1; loginLen = mir_tstrlen(loginName); domainLen = domainName - login; domainName = login; } else if ((domainName = _tcschr(login, '@')) != NULL) { loginName = login; loginLen = domainName - login; domainLen = mir_tstrlen(++domainName); } auth.User = (PWORD)loginName; auth.UserLength = (ULONG)loginLen; auth.Password = (PWORD)psw; auth.PasswordLength = (ULONG)mir_tstrlen(psw); auth.Domain = (PWORD)domainName; auth.DomainLength = (ULONG)domainLen; auth.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; hNtlm->hasDomain = domainLen != 0; } SECURITY_STATUS sc = AcquireCredentialsHandle(NULL, szProvider, SECPKG_CRED_OUTBOUND, NULL, hNtlm->hasDomain ? &auth : NULL, NULL, NULL, &hNtlm->hClientCredential, &tokenExpiration); if (sc != SEC_E_OK) { ReportSecError(sc, __LINE__); return NULL; } } outputBufferDescriptor.cBuffers = 1; outputBufferDescriptor.pBuffers = &outputSecurityToken; outputBufferDescriptor.ulVersion = SECBUFFER_VERSION; outputSecurityToken.BufferType = SECBUFFER_TOKEN; outputSecurityToken.cbBuffer = hNtlm->cbMaxToken; outputSecurityToken.pvBuffer = alloca(outputSecurityToken.cbBuffer); SECURITY_STATUS sc = InitializeSecurityContext(&hNtlm->hClientCredential, hasChallenge ? &hNtlm->hClientContext : NULL, hNtlm->szPrincipal, isGSSAPI ? ISC_REQ_MUTUAL_AUTH | ISC_REQ_STREAM : 0, 0, SECURITY_NATIVE_DREP, hasChallenge ? &inputBufferDescriptor : NULL, 0, &hNtlm->hClientContext, &outputBufferDescriptor, &contextAttributes, &tokenExpiration); complete = (sc != SEC_I_COMPLETE_AND_CONTINUE && sc != SEC_I_CONTINUE_NEEDED); if (sc == SEC_I_COMPLETE_NEEDED || sc == SEC_I_COMPLETE_AND_CONTINUE) sc = CompleteAuthToken(&hNtlm->hClientContext, &outputBufferDescriptor); if (sc != SEC_E_OK && sc != SEC_I_CONTINUE_NEEDED) { ReportSecError(sc, __LINE__); return NULL; } szOutputToken = mir_base64_encode((PBYTE)outputSecurityToken.pvBuffer, outputSecurityToken.cbBuffer); } else { if (!login || !psw) return NULL; char *szLogin = mir_t2a(login); char *szPassw = mir_t2a(psw); size_t authLen = mir_strlen(szLogin) + mir_strlen(szPassw) + 5; char *szAuth = (char*)alloca(authLen); int len = mir_snprintf(szAuth, authLen, "%s:%s", szLogin, szPassw); szOutputToken = mir_base64_encode((BYTE*)szAuth, len); complete = true; mir_free(szPassw); mir_free(szLogin); } if (szOutputToken == NULL) return NULL; if (!http) return szOutputToken; ptrA szProvider(mir_t2a(hNtlm->szProvider)); size_t resLen = mir_strlen(szOutputToken) + mir_strlen(szProvider) + 10; char *result = (char*)mir_alloc(resLen); mir_snprintf(result, resLen, "%s %s", szProvider, szOutputToken); mir_free(szOutputToken); return result; }
char* CompleteGssapi(HANDLE hSecurity, unsigned char *szChallenge, unsigned chlsz) { if (!szChallenge || !szChallenge[0]) return NULL; NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity; unsigned char inDataBuffer[1024]; SecBuffer inBuffers[2] = { { sizeof(inDataBuffer), SECBUFFER_DATA, inDataBuffer }, { chlsz, SECBUFFER_STREAM, szChallenge } }; SecBufferDesc inBuffersDesc = { SECBUFFER_VERSION, 2, inBuffers }; unsigned long qop = 0; SECURITY_STATUS sc = DecryptMessage(&hNtlm->hClientContext, &inBuffersDesc, 0, &qop); if (sc != SEC_E_OK) { ReportSecError(sc, __LINE__); return NULL; } // unsigned char LayerMask = inDataBuffer[0]; // unsigned int MaxMessageSize = htonl(*(unsigned*)&inDataBuffer[1]); SecPkgContext_Sizes sizes; sc = QueryContextAttributes(&hNtlm->hClientContext, SECPKG_ATTR_SIZES, &sizes); if (sc != SEC_E_OK) { ReportSecError(sc, __LINE__); return NULL; } unsigned char *tokenBuffer = (unsigned char*)alloca(sizes.cbSecurityTrailer); unsigned char *paddingBuffer = (unsigned char*)alloca(sizes.cbBlockSize); unsigned char outDataBuffer[4] = { 1, 0, 16, 0 }; SecBuffer outBuffers[3] = { { sizes.cbSecurityTrailer, SECBUFFER_TOKEN, tokenBuffer }, { sizeof(outDataBuffer), SECBUFFER_DATA, outDataBuffer }, { sizes.cbBlockSize, SECBUFFER_PADDING, paddingBuffer } }; SecBufferDesc outBuffersDesc = { SECBUFFER_VERSION, 3, outBuffers }; sc = EncryptMessage(&hNtlm->hClientContext, SECQOP_WRAP_NO_ENCRYPT, &outBuffersDesc, 0); if (sc != SEC_E_OK) { ReportSecError(sc, __LINE__); return NULL; } unsigned i, ressz = 0; for (i = 0; i < outBuffersDesc.cBuffers; i++) ressz += outBuffersDesc.pBuffers[i].cbBuffer; unsigned char *response = (unsigned char*)alloca(ressz), *p = response; for (i = 0; i < outBuffersDesc.cBuffers; i++) { memcpy(p, outBuffersDesc.pBuffers[i].pvBuffer, outBuffersDesc.pBuffers[i].cbBuffer); p += outBuffersDesc.pBuffers[i].cbBuffer; } return mir_base64_encode(response, ressz); }
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; }