diff options
| author | George Hazan <ghazan@miranda.im> | 2019-10-07 20:40:13 +0300 |
|---|---|---|
| committer | George Hazan <ghazan@miranda.im> | 2019-10-07 20:40:20 +0300 |
| commit | 8d0500df234fc5b59ea7687bd5f55f19d7b8e28c (patch) | |
| tree | a090b606b6e5fa25574c4836121cebae667de5cb /protocols/WhatsAppWeb/src/server.cpp | |
| parent | 5ffd6fe3ab6f29444c699720b9ea588b57313c27 (diff) | |
WhatsAppWeb: QR code viewer
Diffstat (limited to 'protocols/WhatsAppWeb/src/server.cpp')
| -rw-r--r-- | protocols/WhatsAppWeb/src/server.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp new file mode 100644 index 0000000000..8b94cb675c --- /dev/null +++ b/protocols/WhatsAppWeb/src/server.cpp @@ -0,0 +1,151 @@ +/* + +WhatsAppWeb plugin for Miranda NG +Copyright © 2019 George Hazan + +*/ + +#include "stdafx.h" + +class CWhatsAppQRDlg : public CProtoDlgBase<WhatsAppProto> +{ + QRcode *m_qr; + +public: + CWhatsAppQRDlg(WhatsAppProto *ppro, const CMStringA &szData) : + CProtoDlgBase<WhatsAppProto>(ppro, IDD_SHOWQR) + { + m_qr = QRcode_encodeString(szData, 0, QR_ECLEVEL_L, QR_MODE_8, 1); + } + + ~CWhatsAppQRDlg() + { + QRcode_free(m_qr); + } + + bool OnInitDialog() override + { + HWND hwndRc = GetDlgItem(m_hwnd, IDC_QRPIC); + RECT rc; + GetClientRect(hwndRc, &rc); + + ::SetForegroundWindow(m_hwnd); + + int scale = 8; // (rc.bottom - rc.top) / m_qr->width; + int rowLen = m_qr->width * scale * 3; + if (rowLen % 4) + rowLen = (rowLen / 4 + 1) * 4; + int dataLen = rowLen * m_qr->width * scale; + + mir_ptr<BYTE> pData((BYTE *)mir_alloc(dataLen)); + if (pData == nullptr) + return false; + + memset(pData, 0xFF, dataLen); // white background by default + + const BYTE *s = m_qr->data; + for (int y = 0; y < m_qr->width; y++) { + BYTE *d = pData.get() + rowLen * y * scale; + for (int x = 0; x < m_qr->width; x++) { + if (*s & 1) + for (int i = 0; i < scale; i++) + for (int j = 0; j < scale; j++) { + d[j * 3 + i * rowLen] = 0; + d[1 + j * 3 + i * rowLen] = 0; + d[2 + j * 3 + i * rowLen] = 0; + } + + d += scale * 3; + s++; + } + } + + BITMAPFILEHEADER fih = {}; + fih.bfType = 0x4d42; // "BM" + fih.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dataLen; + fih.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + + BITMAPINFOHEADER bih = {}; + bih.biSize = sizeof(BITMAPINFOHEADER); + bih.biWidth = m_qr->width * scale; + bih.biHeight = -bih.biWidth; + bih.biPlanes = 1; + bih.biBitCount = 24; + bih.biCompression = BI_RGB; + + wchar_t wszTempPath[MAX_PATH], wszTempFile[MAX_PATH]; + GetTempPathW(_countof(wszTempPath), wszTempPath); + GetTempFileNameW(wszTempPath, L"wa_", TRUE, wszTempFile); + FILE *f = _wfopen(wszTempFile, L"wb"); + fwrite(&fih, sizeof(BITMAPFILEHEADER), 1, f); + fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, f); + fwrite(pData, sizeof(unsigned char), dataLen, f); + fclose(f); + + SendMessage(hwndRc, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)Image_Load(wszTempFile)); + + DeleteFileW(wszTempFile); + return true; + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +static int random_func(uint8_t *pData, size_t size, void *) +{ + Utils_GetRandom(pData, size); + return 0; +} + +bool WhatsAppProto::ShowQrCode() +{ + CMStringA szPubKey(getMStringA(DBKEY_PUBKEY)); + if (szPubKey.IsEmpty()) { + // generate new pair of private & public keys for this account + signal_context *pTmpCtx; + signal_context_create(&pTmpCtx, nullptr); + + signal_crypto_provider prov; + memset(&prov, 0xFF, sizeof(prov)); + prov.random_func = random_func; + signal_context_set_crypto_provider(pTmpCtx, &prov); + + ec_key_pair *pKeys; + if (curve_generate_key_pair(pTmpCtx, &pKeys)) { + signal_context_destroy(pTmpCtx); + return false; + } + + auto *pPubKey = ec_key_pair_get_public(pKeys); + signal_buffer *pBuf; + ec_public_key_serialize(&pBuf, pPubKey); + szPubKey = ptrA(mir_base64_encode(&pBuf->data, pBuf->len)); + signal_buffer_free(pBuf); + setString(DBKEY_PUBKEY, szPubKey); + + auto *pPrivKey = ec_key_pair_get_private(pKeys); + ec_private_key_serialize(&pBuf, pPrivKey); + CMStringA szPrivKey(ptrA(mir_base64_encode(&pBuf->data, pBuf->len))); + signal_buffer_free(pBuf); + setString(DBKEY_PRIVATEKEY, szPrivKey); + } + + CMStringA szQrData(FORMAT, "%s,%s,%s", m_szJid.c_str(), szPubKey.c_str(), m_szClientId.c_str()); + CWhatsAppQRDlg(this, szQrData).DoModal(); + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void WhatsAppProto::ServerThread(void *) +{ + m_pConn = new WAConnection(); + + ptrA szClientToken(getStringA(DBKEY_CLIENT_SECRET)); + if (szClientToken == nullptr) { + if (!ShowQrCode()) { + delete m_pConn; + return; + } + } +}
\ No newline at end of file |
