/* Jabber Protocol Plugin for Miranda IM Copyright ( C ) 2002-04 Santithorn Bunchua Copyright ( C ) 2005-11 George Hazan Copyright ( C ) 2007 Maxim Mluhov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or ( at your option ) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Revision : $Revision: 13444 $ Last change on : $Date: 2011-03-13 23:44:13 +0300 (Вс, 13 мар 2011) $ Last change by : $Author: borkra $ */ #include "jabber.h" struct CAPTCHA_FORM_PARAMS { LPCTSTR from; LPCTSTR challenge; LPCTSTR fromjid; LPCTSTR sid; LPCTSTR to; LPCTSTR hint; HBITMAP bmp; int w,h; TCHAR Result[MAX_PATH]; }; INT_PTR CALLBACK JabberCaptchaFormDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { CAPTCHA_FORM_PARAMS *params = (CAPTCHA_FORM_PARAMS*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA ); switch (msg) { case WM_INITDIALOG: { TranslateDialogDefault( hwndDlg ); SendMessage( hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIconBig(IDI_KEYS)); SendMessage( hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedIcon(IDI_KEYS)); params = (CAPTCHA_FORM_PARAMS*)lParam; LPCTSTR hint = params->hint; if ( hint == NULL ) hint = TranslateT("Enter the text you see"); SetDlgItemText( hwndDlg, IDC_INSTRUCTION, TranslateTS( hint ) ); SetWindowLongPtr( hwndDlg, GWLP_USERDATA, ( LONG )params ); return TRUE; } case WM_CTLCOLORSTATIC: switch( GetWindowLongPtr((HWND)lParam, GWL_ID)) { case IDC_WHITERECT: case IDC_INSTRUCTION: case IDC_TITLE: return (BOOL)GetStockObject(WHITE_BRUSH); } return NULL; case WM_PAINT: if ( params ) { PAINTSTRUCT ps; HDC hdc, hdcMem; RECT rc; GetClientRect( hwndDlg, &rc ); hdc = BeginPaint( hwndDlg, &ps ); hdcMem = CreateCompatibleDC( hdc ); HGDIOBJ hOld = SelectObject( hdcMem, params->bmp ); int y = ( rc.bottom + rc.top - params->h ) / 2; int x = ( rc.right + rc.left - params->w ) / 2; BitBlt( hdc, x, y, params->w, params->h, hdcMem, 0,0, SRCCOPY ); SelectObject( hdcMem, hOld ); DeleteDC( hdcMem ); EndPaint( hwndDlg, &ps ); } break; case WM_COMMAND: switch ( LOWORD( wParam )) { case IDCANCEL: EndDialog( hwndDlg, 0 ); return TRUE; case IDC_SUBMIT: GetDlgItemText( hwndDlg, IDC_VALUE, params->Result, SIZEOF(params->Result) ); EndDialog( hwndDlg, 1 ); return TRUE; } break; case WM_CLOSE: EndDialog( hwndDlg, 0 ); break; case WM_DESTROY: WindowFreeIcon( hwndDlg ); break; } return FALSE; } bool CJabberProto::ProcessCaptcha (HXML node, HXML parentNode, ThreadData* info ) { CAPTCHA_FORM_PARAMS param; char *ImageBuf = 0; const TCHAR *PicType = 0; TCHAR *CaptchaPath = 0; HXML x = xmlGetChildByTag( node, "x", "xmlns", _T(JABBER_FEAT_DATA_FORMS)); if ( x == NULL ) return false; HXML y = xmlGetChildByTag(x, _T("field"), _T("var"), _T("from")); if ( y == NULL ) return false; if (( y = xmlGetChild( y, "value" )) == NULL ) return false; param.fromjid = xmlGetText( y ); if (( y = xmlGetChildByTag(x, _T("field"), _T("var"), _T("sid"))) == NULL ) return false; if (( y = xmlGetChild( y, "value" )) == NULL ) return false; param.sid = xmlGetText( y ); if (( y = xmlGetChildByTag(x, _T("field"), _T("var"), _T("ocr"))) == NULL ) return false; param.hint = xmlGetAttrValue (y, _T("label")); param.from = xmlGetAttrValue( parentNode, _T("from")); param.to = xmlGetAttrValue( parentNode, _T("to")); param.challenge = xmlGetAttrValue( parentNode, _T("id")); HXML o = xmlGetChild( parentNode, "data" ); if ( o == NULL || xmlGetText( o ) == NULL ) return false; GetCaptchaImage(parentNode, ImageBuf, PicType, CaptchaPath); char* p = mir_t2a( CaptchaPath ); param.bmp = ( HBITMAP ) JCallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )p ); DeleteFile(CaptchaPath); mir_free(CaptchaPath); mir_free(p); BITMAP bmp = {0}; GetObject( param.bmp, sizeof(bmp), &bmp ); param.w = bmp.bmWidth; param.h = bmp.bmHeight; int res = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CAPTCHAFORM), NULL, JabberCaptchaFormDlgProc, (LPARAM)¶m); if (lstrcmp(param.Result, _T("")) == 0 || !res) sendCaptchaError(info, param.from, param.to, param.challenge); else sendCaptchaResult (param.Result, info, param.from, param.challenge, param.fromjid, param.sid); return true; } void CJabberProto::GetCaptchaImage ( HXML node, char *ImageBuf, const TCHAR *PicType, TCHAR*& CaptchaPath ) { HXML o = xmlGetChild( node , "data" ); int bufferLen; char* buffer = JabberBase64DecodeT(xmlGetText( o ), &bufferLen ); if ( buffer == NULL ) return; const TCHAR* szPicType; HXML m = xmlGetChild( node , "TYPE" ); if ( m == NULL || xmlGetText( m ) == NULL ) { LBL_NoTypeSpecified: switch( JabberGetPictureType( buffer )) { case PA_FORMAT_GIF: szPicType = _T("image/gif"); break; case PA_FORMAT_BMP: szPicType = _T("image/bmp"); break; case PA_FORMAT_PNG: szPicType = _T("image/png"); break; case PA_FORMAT_JPEG: szPicType = _T("image/jpeg"); break; default: goto LBL_Ret; } } else { const TCHAR* tszType = xmlGetText( m ); if ( !_tcscmp( tszType, _T("image/jpeg")) || !_tcscmp( tszType, _T("image/png")) || !_tcscmp( tszType, _T("image/gif")) || !_tcscmp( tszType, _T("image/bmp"))) szPicType = tszType; else goto LBL_NoTypeSpecified; } DWORD nWritten; LBL_Ret: TCHAR* ext = _tcsstr((TCHAR*)szPicType, _T("/"))+1; TCHAR filename[MAX_PATH]; mir_sntprintf(filename, SIZEOF(filename), _T("%%TEMP%%\\captcha.%s"), ext); CaptchaPath = Utils_ReplaceVarsT(filename); HANDLE hFile = CreateFile( CaptchaPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) goto LBL_Ret; if ( !WriteFile( hFile, buffer, bufferLen, &nWritten, NULL )) goto LBL_Ret; CloseHandle( hFile ); ImageBuf = buffer; PicType = szPicType; } void CJabberProto::sendCaptchaResult(TCHAR* buf, ThreadData* info, LPCTSTR from, LPCTSTR challenge, LPCTSTR fromjid, LPCTSTR sid){ XmlNodeIq iq( _T("set"), SerialNext()); HXML query= iq < send (iq); } void CJabberProto::sendCaptchaError(ThreadData* info, LPCTSTR from, LPCTSTR to, LPCTSTR challenge ) { XmlNode message( _T("message")); HXML query= message << XATTR(_T("type"), _T("error")) << XATTR(_T("to"), from) << XATTR(_T("id"), challenge) << XATTR(_T("from"), to) << XCHILD(_T("error")) << XATTR(_T("type"), _T("modify")) << XCHILD(_T("not-acceptable")) << XATTR(_T("xmlns"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")); info -> send (message); }