diff options
author | admin@progandy.co.cc <admin@progandy.co.cc@eced67a3-f377-a0ae-92ae-d6de1850b05a> | 2010-09-12 13:33:13 +0000 |
---|---|---|
committer | admin@progandy.co.cc <admin@progandy.co.cc@eced67a3-f377-a0ae-92ae-d6de1850b05a> | 2010-09-12 13:33:13 +0000 |
commit | 8411617ad832612d074884ce7304516fe2459b48 (patch) | |
tree | a02d6d93c88418524972346284f6738420f9efc5 | |
parent | 2ef110b55c664e80dddca099f1376c874f28fbc9 (diff) |
- [ issue 2 ] implemented SMP
- fixed some memory leaks
- ugly workaround for SMP in ICQ
git-svn-id: http://mirotr.googlecode.com/svn/trunk@8 eced67a3-f377-a0ae-92ae-d6de1850b05a
-rw-r--r-- | MirOTR/DLG_smp.cpp | 96 | ||||
-rw-r--r-- | MirOTR/MirOTR.vcproj | 28 | ||||
-rw-r--r-- | MirOTR/dialogs.cpp | 370 | ||||
-rw-r--r-- | MirOTR/dialogs.h | 4 | ||||
-rw-r--r-- | MirOTR/language.h | 23 | ||||
-rw-r--r-- | MirOTR/options.cpp | 6 | ||||
-rw-r--r-- | MirOTR/otr.cpp | 9 | ||||
-rw-r--r-- | MirOTR/resources/resource.rc | 3 | ||||
-rw-r--r-- | MirOTR/svcs_proto.cpp | 17 | ||||
-rw-r--r-- | MirOTR/utils.cpp | 17 | ||||
-rw-r--r-- | MirOTR/utils.h | 2 | ||||
-rw-r--r-- | MirOTR/version.h | 2 |
12 files changed, 406 insertions, 171 deletions
diff --git a/MirOTR/DLG_smp.cpp b/MirOTR/DLG_smp.cpp deleted file mode 100644 index b701b7f..0000000 --- a/MirOTR/DLG_smp.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "stdafx.h"
-#include <map>
-//TODO: Social Millionaire Protocol
-typedef std::map<HANDLE, HWND> SmpForContactMap;
-SmpForContactMap smp_for_contact;
-
-HWND smp_find_for_contact(HANDLE hContact) {
- SmpForContactMap::iterator iter = smp_for_contact.find(hContact);
- if (iter == smp_for_contact.end()) return null;
- return iter->second;
-}
-
-/* Create the SMP dialog. responder is true if this is called in - * response to someone else's run of SMP. */ -static void dialog_socialist_millionaires(ConnContext *context, - TCHAR *question, bool responder) -{ - if (context == NULL) return; - TCHAR primary[1024]; - - if (responder && question) { - (HANDLE)context->app_data - mir_sntprintf(primary, 1024, TranslateT(LANG_SMP_AUTH_FROM), - contact_get_nameT((HANDLE)context->app_data)); - } else { - mir_sntprintf(primary, 1024, TranslateT(LANG_SMP_AUTH), - contact_get_nameT((HANDLE)context->app_data)); - } - - /* fprintf(stderr, "Question = ``%s''\n", question); */ - //TCHAR* proto_name = mir_a2t(context->protocol); - //if (!proto_name) proto_name = mir_tstrdup(TranslateT(LANG_UNKNOWN)); - - - dialog = create_smp_dialog(_("Authenticate Buddy"), - primary, context, responder, question); - - //mir_free(proto_name); -} - -/* Call this to update the status of an ongoing socialist millionaires - * protocol. Progress_level is a percentage, from 0.0 (aborted) to - * 1.0 (complete). Any other value represents an intermediate state. */ -static void otrg_gtk_dialog_update_smp(ConnContext *context, - double progress_level) -{ - PurpleConversation *conv = otrg_plugin_context_to_conv(context, 0); - GtkProgressBar *bar; - SMPData *smp_data = purple_conversation_get_data(conv, "otr-smpdata"); - - if (!smp_data) return; - - bar = GTK_PROGRESS_BAR(smp_data->smp_progress_bar); - gtk_progress_bar_set_fraction(bar, progress_level); - - /* If the counter is reset to absolute zero, the protocol has aborted */ - if (progress_level == 0.0) { - GtkDialog *dialog = GTK_DIALOG(smp_data->smp_progress_dialog); - - gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_ACCEPT, 1); - gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_REJECT, 0); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), - GTK_RESPONSE_ACCEPT); - - gtk_label_set_text(GTK_LABEL(smp_data->smp_progress_label), - _("An error occurred during authentication.")); - return; - } else if (progress_level == 1.0) { - /* If the counter reaches 1.0, the protocol is complete */ - GtkDialog *dialog = GTK_DIALOG(smp_data->smp_progress_dialog); - - gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_ACCEPT, 1); - gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_REJECT, 0); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), - GTK_RESPONSE_ACCEPT); - - if (context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) { - if (context->active_fingerprint->trust && - context->active_fingerprint->trust[0]) { - gtk_label_set_text(GTK_LABEL(smp_data->smp_progress_label), - _("Authentication successful.")); - } else { - gtk_label_set_text(GTK_LABEL(smp_data->smp_progress_label), - _("Your buddy has successfully authenticated you. " - "You may want to authenticate your buddy as " - "well by asking your own question.")); - } - } else { - gtk_label_set_text(GTK_LABEL(smp_data->smp_progress_label), - _("Authentication failed.")); - } - } else { - /* Clear the progress label */ - gtk_label_set_text(GTK_LABEL(smp_data->smp_progress_label), ""); - } -}
\ No newline at end of file diff --git a/MirOTR/MirOTR.vcproj b/MirOTR/MirOTR.vcproj index 905d4b3..11c59a0 100644 --- a/MirOTR/MirOTR.vcproj +++ b/MirOTR/MirOTR.vcproj @@ -281,34 +281,6 @@ >
</File>
<File
- RelativePath=".\DLG_smp.cpp"
- >
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release ANSI|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
RelativePath=".\dllmain.cpp"
>
<FileConfiguration
diff --git a/MirOTR/dialogs.cpp b/MirOTR/dialogs.cpp index a064a74..50c25aa 100644 --- a/MirOTR/dialogs.cpp +++ b/MirOTR/dialogs.cpp @@ -4,26 +4,304 @@ #include <commctrl.h>
#include <process.h>
-static void VerifyFingerprint(ConnContext *context, bool verify) {
- TCHAR msg[1024];
- if (verify) {
- lib_cs_lock();
- otrl_context_set_trust(context->active_fingerprint, "verified");
- otrl_privkey_write_fingerprints(otr_user_state, g_fingerprint_store_filename);
- lib_cs_unlock();
- mir_sntprintf(msg, 1024, TranslateT(LANG_FINGERPRINT_VERIFIED), contact_get_nameT((HANDLE)context->app_data));
- } else {
- lib_cs_lock();
- otrl_context_set_trust(context->active_fingerprint, NULL);
- otrl_privkey_write_fingerprints(otr_user_state, g_fingerprint_store_filename);
- lib_cs_unlock();
- mir_sntprintf(msg, 1024, TranslateT(LANG_FINGERPRINT_NOT_VERIFIED), contact_get_nameT((HANDLE)context->app_data));
+struct SmpData {
+ HWND dialog;
+ TrustLevel oldlevel;
+ ConnContext *context;
+ bool responder;
+ TCHAR *question;
+};
+typedef std::map<HANDLE, SmpData> SmpForContactMap;
+SmpForContactMap smp_for_contact;
+
+
+INT_PTR CALLBACK DlgSMPUpdateProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ {
+ if (!lParam) {
+ EndDialog(hwndDlg, IDCANCEL);
+ return FALSE;
+ }
+ TranslateDialogDefault( hwndDlg );
+
+ SmpData *data = (SmpData*)lParam;
+ ConnContext *context = data->context;
+ data->dialog = hwndDlg;
+ //smp_for_contact.insert(SmpForContactMap::value_type(context->app_data, *data));
+ if (smp_for_contact[context->app_data].dialog) SendMessage(smp_for_contact[context->app_data].dialog, WMU_REFRESHSMP, 0, 0);
+ smp_for_contact[context->app_data].context = data->context;
+ smp_for_contact[context->app_data].dialog = hwndDlg;
+ smp_for_contact[context->app_data].oldlevel = data->oldlevel;
+ smp_for_contact[context->app_data].responder = data->responder;
+ mir_free(data);
+
+ TCHAR title[512], *proto = mir_a2t(contact_get_proto((HANDLE)context->app_data));
+ const TCHAR *name =contact_get_nameT((HANDLE)context->app_data);
+ mir_sntprintf(title, 512, TranslateT(LANG_SMP_PROGRESS_TITLE), name, proto);
+ SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)title);
+ mir_sntprintf(title, 512, TranslateT(LANG_SMP_PROGRESS_DESC), name, proto);
+ mir_free(proto);
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_HEADPRO, title);
+ SetWindowLongPtr(hwndDlg, GWL_USERDATA, (LONG_PTR)context);
+
+ // Move window to screen center
+ // Get the owner window and dialog box rectangles.
+ HWND hwndOwner; RECT rcOwner, rcDlg, rc;
+ if ((hwndOwner = GetParent(hwndDlg)) == NULL)
+ {
+ hwndOwner = GetDesktopWindow();
+ }
+
+ GetWindowRect(hwndOwner, &rcOwner);
+ GetWindowRect(hwndDlg, &rcDlg);
+ CopyRect(&rc, &rcOwner);
+
+ // Offset the owner and dialog box rectangles so that right and bottom
+ // values represent the width and height, and then offset the owner again
+ // to discard space taken up by the dialog box.
+
+ OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
+ OffsetRect(&rc, -rc.left, -rc.top);
+ OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
+
+ // The new position is the sum of half the remaining space and the owner's
+ // original position.
+
+ SetWindowPos(hwndDlg,
+ HWND_TOP,
+ rcOwner.left + (rc.right / 2),
+ rcOwner.top + (rc.bottom / 2),
+ 0, 0, // Ignores size arguments.
+ SWP_NOSIZE);
+
+ // end center dialog
+
+ SendDlgItemMessage(hwndDlg, IDC_PGB_SMP, PBM_SETRANGE, 0, MAKELONG(0, 100));
+ SendDlgItemMessage(hwndDlg, IDC_PGB_SMP, PBM_SETPOS, 10, 0);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), true);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), false);
+
+ return TRUE;
+ }
+
+ case WMU_REFRESHSMP:
+ {
+ ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
+ SendDlgItemMessage(hwndDlg, IDC_PGB_SMP, PBM_SETPOS, wParam, 0);
+ switch (wParam) {
+ case 0:
+ EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), false);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), true);
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_ERROR));
+ smp_for_contact.erase(context->app_data);
+ break;
+ case 100:
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), false);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), true);
+ smp_for_contact.erase(context->app_data);
+ if (context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) { + if (context->active_fingerprint->trust && + context->active_fingerprint->trust[0]) { + SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_SUCCESS)); + } else { + SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_SUCCESS_VERIFY)); + } + } else { + SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_FAILED)); + }
+ }
+ break;
+ default:
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, _T(""));
+ }
+ }
+
+ case WM_COMMAND:
+ switch ( HIWORD( wParam )) {
+ case BN_CLICKED:
+ {
+ ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
+ switch ( LOWORD( wParam )) {
+ case IDCANCEL:
+ otr_abort_smp(context);
+ //break;
+ case IDOK:
+ smp_for_contact.erase(context->app_data);
+ EndDialog(hwndDlg, LOWORD( wParam ));
+ break;
+ }
+ }break;
+ }
+
+ }
+
+ return FALSE;
+}
+
+void SMPInitUpdateDialog(ConnContext *context, bool responder) {
+ if (!context) return;
+ SmpData *data = (SmpData*)mir_calloc(sizeof(SmpData));
+ data->context = context;
+ data->oldlevel = otr_context_get_trust(context);
+ data->responder = responder;
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SMP_PROGRESS), 0, DlgSMPUpdateProc, (LPARAM) data);
+}
+
+INT_PTR CALLBACK DlgSMPResponseProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ {
+ if (!lParam) {
+ EndDialog(hwndDlg, IDCANCEL);
+ return FALSE;
+ }
+ TranslateDialogDefault( hwndDlg );
+
+ SmpData *data = (SmpData*)lParam;
+ ConnContext *context = data->context;
+ data->dialog = hwndDlg;
+ //smp_for_contact.insert(SmpForContactMap::value_type(context->app_data, *data));
+ if (smp_for_contact[context->app_data].dialog) SendMessage(smp_for_contact[context->app_data].dialog, WMU_REFRESHSMP, 0, 0);
+ smp_for_contact[context->app_data].context = data->context;
+ smp_for_contact[context->app_data].dialog = hwndDlg;
+ smp_for_contact[context->app_data].oldlevel = data->oldlevel;
+ smp_for_contact[context->app_data].responder = data->responder;
+
+ TCHAR buff[512], *proto=mir_a2t(contact_get_proto(context->app_data));
+ mir_sntprintf(buff, 512, TranslateT(LANG_SMP_VERIFY_TITLE), contact_get_nameT(context->app_data), proto);
+ mir_free(proto);
+ SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)buff);
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_HEAD, buff);
+ SetWindowLongPtr(hwndDlg, GWL_USERDATA, (LONG_PTR)context);
+
+ if (data->question) {
+ mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPQUESTION_RESPOND_DESC), contact_get_nameT(context->app_data));
+
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);
+
+ SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, data->question);
+ SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, TRUE, 0);
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, TranslateT(LANG_SMP_QUESTION));
+
+ SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, _T(""));
+ SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, FALSE, 0);
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_SMP_ANSWER));
+
+
+ ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
+
+ mir_free(data->question);
+ } else {
+ mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPPASSWORD_RESPOND_DESC), contact_get_nameT((HANDLE)context->app_data));
+
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);
+
+ SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, _T(""));
+ SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, TRUE, 0);
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, _T(""));
+
+ SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, _T(""));
+ SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, FALSE, 0);
+ SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_SMP_PASSWORD));
+
+
+ ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
+ }
+ mir_free(data);
+
+ // Move window to screen center
+ // Get the owner window and dialog box rectangles.
+ HWND hwndOwner; RECT rcOwner, rcDlg, rc;
+ if ((hwndOwner = GetParent(hwndDlg)) == NULL)
+ {
+ hwndOwner = GetDesktopWindow();
+ }
+
+ GetWindowRect(hwndOwner, &rcOwner);
+ GetWindowRect(hwndDlg, &rcDlg);
+ CopyRect(&rc, &rcOwner);
+
+ // Offset the owner and dialog box rectangles so that right and bottom
+ // values represent the width and height, and then offset the owner again
+ // to discard space taken up by the dialog box.
+
+ OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
+ OffsetRect(&rc, -rc.left, -rc.top);
+ OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
+
+ // The new position is the sum of half the remaining space and the owner's
+ // original position.
+
+ SetWindowPos(hwndDlg,
+ HWND_TOP,
+ rcOwner.left + (rc.right / 2),
+ rcOwner.top + (rc.bottom / 2),
+ 0, 0, // Ignores size arguments.
+ SWP_NOSIZE);
+
+ // end center dialog
+
+
+
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ switch ( HIWORD( wParam )) {
+ case BN_CLICKED:
+ {
+ ConnContext *context = (ConnContext *)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
+ switch ( LOWORD( wParam )) {
+ case IDOK:
+ {
+ SMPInitUpdateDialog(context, true);
+
+ int len = SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, WM_GETTEXTLENGTH, 0, 0);
+ TCHAR *answer = new TCHAR[len+1];
+ GetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, answer, len+1);
+ char *ans = mir_utf8encodeT(answer);
+ delete answer;
+
+ otr_continue_smp(context, (const unsigned char *)ans, strlen(ans));
+ mir_free(ans);
+
+ EndDialog(hwndDlg, LOWORD( wParam ));
+ }break;
+ case IDCANCEL:
+ smp_for_contact.erase(context->app_data);
+ EndDialog(hwndDlg, LOWORD( wParam ));
+ break;
+ }
+ }
+ }
+ break;
+
}
- msg[1023] = '\0';
- ShowMessage((HANDLE)context->app_data, msg);
- SetEncryptionStatus(context->app_data, otr_context_get_trust(context));
+
+ return FALSE;
}
+/*
+void SMPInitResponseDialog(ConnContext *context, const TCHAR *question) {
+ if (!context) return;
+ SmpData *data = (SmpData*)mir_calloc(sizeof(SmpData));
+ data->context = context;
+ data->oldlevel = TRUST_NOT_PRIVATE;
+ data->responder = true;
+ data->question = (question) ? mir_tstrdup(question) : NULL;
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SMP_INPUT), 0, DlgSMPResponseProc, (LPARAM) data);
+}
+*/
+
INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch ( msg ) {
@@ -36,8 +314,14 @@ INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA TranslateDialogDefault( hwndDlg );
ConnContext *context = (ConnContext*)lParam;
- TCHAR title[512];
- mir_sntprintf(title, 512, TranslateT(LANG_SMP_VERIFY_TITLE), contact_get_nameT((HANDLE)context->app_data));
+ if (smp_for_contact.find(context->app_data) != smp_for_contact.end()) {
+ EndDialog(hwndDlg, IDCANCEL);
+ return FALSE;
+ }
+
+ TCHAR title[512], *proto = mir_a2t(contact_get_proto((HANDLE)context->app_data));
+ mir_sntprintf(title, 512, TranslateT(LANG_SMP_VERIFY_TITLE), contact_get_nameT((HANDLE)context->app_data), proto);
+ mir_free(proto);
SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)title);
SetDlgItemText(hwndDlg, IDC_STC_SMP_HEAD, title);
SetWindowLongPtr(hwndDlg, GWL_USERDATA, lParam);
@@ -126,6 +410,11 @@ INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA case IDOK:
GetDlgItemText(hwndDlg, IDC_CBO_SMP_CHOOSE, msg, 255);
if (_tcsncmp(msg, TranslateT(LANG_SMPTYPE_QUESTION), 255)==0) {
+ if (smp_for_contact.find(context->app_data) != smp_for_contact.end()) {
+ TCHAR msg[512];
+ mir_sntprintf(msg, 512, TranslateT(LANG_SMP_IN_PROGRESS), contact_get_nameT((HANDLE)context->app_data));
+ ShowError(msg);
+ }else {
int len = SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, WM_GETTEXTLENGTH, 0, 0);
TCHAR *question = new TCHAR[len+1];
GetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, question, len+1);
@@ -138,19 +427,28 @@ INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA char *ans = mir_utf8encodeT(answer);
delete answer;
+ SMPInitUpdateDialog(context, false);
otr_start_smp(context, quest, (const unsigned char*)ans, strlen(ans));
mir_free(quest);
mir_free(ans);
+ }
}else if (_tcsncmp(msg, TranslateT(LANG_SMPTYPE_PASSWORD), 255)==0) {
+ if (smp_for_contact.find(context->app_data) != smp_for_contact.end()) {
+ TCHAR msg[512];
+ mir_sntprintf(msg, 512, TranslateT(LANG_SMP_IN_PROGRESS), contact_get_nameT((HANDLE)context->app_data));
+ ShowError(msg);
+ }else {
int len = SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, WM_GETTEXTLENGTH, 0, 0);
TCHAR *answer = new TCHAR[len+1];
GetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, answer, len+1);
char *ans = mir_utf8encodeT(answer);
delete answer;
+ SMPInitUpdateDialog(context, false);
otr_start_smp(context, NULL, (const unsigned char*)ans, strlen(ans));
mir_free(ans);
+ }
}else break;
EndDialog(hwndDlg, LOWORD( wParam ));
@@ -183,9 +481,9 @@ INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA GetDlgItemText(hwndDlg, IDC_CBO_SMP_CHOOSE, buff, 255);
if (_tcsncmp(buff, TranslateT(LANG_SMPTYPE_QUESTION), 255)==0) {
if (trusted)
- mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPQUESTION_VERIFY_DESC), contact_get_nameT((HANDLE)context->app_data));
- else
mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPQUESTION_VERIFIED_DESC), contact_get_nameT((HANDLE)context->app_data));
+ else
+ mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPQUESTION_VERIFY_DESC), contact_get_nameT((HANDLE)context->app_data));
SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);
@@ -203,9 +501,9 @@ INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
} else if (_tcsncmp(buff, TranslateT(LANG_SMPTYPE_PASSWORD), 255)==0) {
if (trusted)
- mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPPASSWORD_VERIFY_DESC), contact_get_nameT((HANDLE)context->app_data));
- else
mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPPASSWORD_VERIFIED_DESC), contact_get_nameT((HANDLE)context->app_data));
+ else
+ mir_sntprintf(buff, 512, TranslateT(LANG_OTR_SMPPASSWORD_VERIFY_DESC), contact_get_nameT((HANDLE)context->app_data));
SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);
@@ -223,9 +521,9 @@ INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
} else if (_tcsncmp(buff, TranslateT(LANG_SMPTYPE_FINGERPRINT), 255)==0) {
if (trusted)
- mir_sntprintf(buff, 512, TranslateT(LANG_OTR_FPVERIFY_DESC), contact_get_nameT((HANDLE)context->app_data));
- else
mir_sntprintf(buff, 512, TranslateT(LANG_OTR_FPVERIFIED_DESC), contact_get_nameT((HANDLE)context->app_data));
+ else
+ mir_sntprintf(buff, 512, TranslateT(LANG_OTR_FPVERIFY_DESC), contact_get_nameT((HANDLE)context->app_data));
SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);
@@ -267,6 +565,19 @@ void SMPInitDialog(ConnContext* context) { }
void SMPDialogUpdate(ConnContext *context, int percent) {
+ if (!context) return;
+ SmpForContactMap::iterator it = smp_for_contact.find(context->app_data);
+ if (it == smp_for_contact.end()) return;
+ if (it->second.dialog) PostMessage(it->second.dialog, WMU_REFRESHSMP, percent, 0);
+ TrustLevel level = otr_context_get_trust(context);
+ if (!it->second.responder && it->second.oldlevel != level) {
+ if (level == TRUST_PRIVATE)
+ VerifyFingerprintMessage(context, true);
+ else if (level == TRUST_UNVERIFIED)
+ VerifyFingerprintMessage(context, false);
+ }
+ //if (percent == 100)
+ /*
switch (percent){
case 0:
VerifyFingerprint(context, false);
@@ -279,10 +590,19 @@ void SMPDialogUpdate(ConnContext *context, int percent) { default:
ShowWarning(_T("Received an SMP update"));
}
+ */
}
void SMPDialogReply(ConnContext *context, const char* question){
+ SmpData *data = (SmpData*)mir_calloc(sizeof(SmpData));
+ data->context = context;
+ data->oldlevel = TRUST_NOT_PRIVATE;
+ data->responder = true;
+ data->question = (question) ? mir_utf8decodeT(question) : NULL;
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SMP_INPUT), 0, DlgSMPResponseProc, (LPARAM) data);
+ /*
ShowError(_T("SMP requires user password (NOT IMPL YET)"));
otr_abort_smp(context);
+ */
//otr_continue_smp(context, pass, strlen(pass));
}
diff --git a/MirOTR/dialogs.h b/MirOTR/dialogs.h index 27593db..0422dc3 100644 --- a/MirOTR/dialogs.h +++ b/MirOTR/dialogs.h @@ -3,4 +3,6 @@ void VerifyContextDialog(ConnContext* context); void SMPInitDialog(ConnContext* context);
INT_PTR CALLBACK DlgProcVerifyContext(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void SMPDialogUpdate(ConnContext *context, int percent);
-void SMPDialogReply(ConnContext *context, const char* question);
\ No newline at end of file +void SMPDialogReply(ConnContext *context, const char* question);
+
+#define WMU_REFRESHSMP (WM_USER + 245)
\ No newline at end of file diff --git a/MirOTR/language.h b/MirOTR/language.h index 1e6b81a..952a41f 100644 --- a/MirOTR/language.h +++ b/MirOTR/language.h @@ -85,19 +85,32 @@ #define LANG_YOUR_PRIVKEY LPGEN("Your Fingerprint to tell your contact (use a trusted channel!)")
#define LANG_CONTACT_FINGERPRINT LPGEN("VERIFY: Fingerprint from contact")
-#define LANG_SMP_VERIFY_TITLE LPGEN("OTR Authenticate %s")
-#define LANG_SMPTYPE_QUESTION LPGEN("Question / Answer")
+#define LANG_SMP_VERIFY_TITLE LPGEN("OTR Authenticate: %s (%s)")
+#define LANG_SMPTYPE_QUESTION LPGEN("Challenge Question")
#define LANG_SMPTYPE_PASSWORD LPGEN("Known Password")
#define LANG_SMPTYPE_FINGERPRINT LPGEN("Manual fingerprint comparison")
-#define LANG_SMP_ANSWER LPGEN("Answer")
+#define LANG_SMP_ANSWER LPGEN("Secret Answer")
#define LANG_SMP_QUESTION LPGEN("Question")
#define LANG_SMP_PASSWORD LPGEN("Password")
+#define LANG_SMP_SUCCESS LPGEN("Authentication sucessful.")
+#define LANG_SMP_SUCCESS_VERIFY LPGEN("You contact authenticated you sucessful. You can send your own request to authenticate him.")
+#define LANG_SMP_ERROR LPGEN("Error during authentication.")
+#define LANG_SMP_FAILED LPGEN("Authentication failed")
+#define LANG_SMP_IN_PROGRESS LPGEN("Authentication for '%s' is already in progress.")
+
+#define LANG_SMP_PROGRESS_TITLE LPGEN("OTR Authenticating: %s (%s)")
+#define LANG_SMP_PROGRESS_DESC LPGEN("Authenticating contact:\n%s (%s)")
+
#define LANG_OTR_SMPQUESTION_VERIFY_DESC LPGEN("OTR encrypted session with '%s' (UNVERIFIED).\nUse a question only your partner can answer.")
#define LANG_OTR_SMPQUESTION_VERIFIED_DESC LPGEN("OTR encrypted session with '%s' (VERIFIED).\nVerify the session again using a question only your partner can answer.")
#define LANG_OTR_SMPPASSWORD_VERIFY_DESC LPGEN("OTR encrypted session with '%s' (UNVERIFIED).\nUse a known password.")
#define LANG_OTR_SMPPASSWORD_VERIFIED_DESC LPGEN("OTR encrypted session with '%s' (VERIFIED).\nVerify the session again using a known password.")
-#define LANG_FINGERPRINT_STILL_IN_USE LPGEN("Fingerprint '%s' still in use in conversation with '%s'. You cannot delete it!")
-#define LANG_FINGERPRINT_NOT_DELETED LPGEN("Fingerprint '%s' in use in conversation with '%s'. It could not be deleted!")
\ No newline at end of file +#define LANG_OTR_SMPQUESTION_RESPOND_DESC LPGEN("Your contact '%s' wants to verify your identity with a question only you can answer.")
+
+#define LANG_OTR_SMPPASSWORD_RESPOND_DESC LPGEN("Your contact '%s' wants to verify your identity with a secret password you should know.")
+
+#define LANG_FINGERPRINT_STILL_IN_USE LPGEN("Fingerprint '%s' still in use in conversation with '%s' (%s). You cannot delete it!")
+#define LANG_FINGERPRINT_NOT_DELETED LPGEN("Fingerprint '%s' in use in conversation with '%s' (%s). It could not be deleted!")
\ No newline at end of file diff --git a/MirOTR/options.cpp b/MirOTR/options.cpp index 993f7fd..8672071 100644 --- a/MirOTR/options.cpp +++ b/MirOTR/options.cpp @@ -848,12 +848,14 @@ static INT_PTR CALLBACK DlgProcMirOTROptsFinger(HWND hwndDlg, UINT msg, WPARAM w case FPM_VERIFY:
otrl_context_set_trust(it->first, "verified");
if (it->first == it->first->context->active_fingerprint)
- SetEncryptionStatus((HANDLE)it->first->context->app_data, otr_context_get_trust(it->first->context));
+ VerifyFingerprint(it->first->context, true);
+ //SetEncryptionStatus((HANDLE)it->first->context->app_data, otr_context_get_trust(it->first->context));
break;
case FPM_NOTRUST:
otrl_context_set_trust(it->first, NULL);
if (it->first == it->first->context->active_fingerprint)
- SetEncryptionStatus((HANDLE)it->first->context->app_data, otr_context_get_trust(it->first->context));
+ VerifyFingerprint(it->first->context, false);
+ //SetEncryptionStatus((HANDLE)it->first->context->app_data, otr_context_get_trust(it->first->context));
break;
}
}
diff --git a/MirOTR/otr.cpp b/MirOTR/otr.cpp index f409e03..eb6728c 100644 --- a/MirOTR/otr.cpp +++ b/MirOTR/otr.cpp @@ -108,7 +108,7 @@ extern "C" { //QueueUserAPC(newKeyAPC, Global::mainThread, (DWORD)nkd);
if (opdata) protocol = contact_get_proto((HANDLE)opdata);
if (!protocol) return;
- DialogBoxParamW(hInst, MAKEINTRESOURCE(IDD_GENKEYNOTIFY), 0, GenKeyDlgFunc, (LPARAM)protocol );
+ DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_GENKEYNOTIFY), 0, GenKeyDlgFunc, (LPARAM)protocol );
}
@@ -314,8 +314,11 @@ extern "C" { }
int max_message_size(void *opdata, ConnContext *context) {
- int s = CallProtoService(context->protocol, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, 0);
- return s;
+ // ugly wokaround for ICQ. ICQ protocol reports more than 7k, but in SMP this is too long.
+ // possibly ICQ doesn't allow single words without spaces to become longer than ~2340?
+ if (strcmp("ICQ", context->protocol)==0 || strncmp("ICQ_", context->protocol, 4)==0)
+ return 2340;
+ return CallProtoService(context->protocol, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, (LPARAM)context->app_data);
}
const char *account_name(void *opdata, const char *account, const char *protocol) {
diff --git a/MirOTR/resources/resource.rc b/MirOTR/resources/resource.rc index 35564ac..eea7258 100644 --- a/MirOTR/resources/resource.rc +++ b/MirOTR/resources/resource.rc @@ -110,6 +110,7 @@ BEGIN CONTROL "",IDC_PGB_SMP,"msctls_progress32",WS_CHILDWINDOW|WS_VISIBLE|PBS_SMOOTH,3,36,194,18
CONTROL "",IDC_STC_SMP_PROGRESS,"Static",WS_CHILDWINDOW|WS_VISIBLE,3,57,194,20
CONTROL "&Cancel",IDCANCEL,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,70,80,60,16
+ CONTROL "&OK",IDOK,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,135,80,60,16
END
IDD_SMP_INPUT DIALOGEX 10,10,200,200
@@ -120,7 +121,7 @@ BEGIN CONTROL IDI_OTR,IDC_ICO_SMP,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_CENTERIMAGE|SS_ICON,3,3,32,32
CONTROL "Socialist Millionaires Protocol\r\nVerification",IDC_STC_SMP_HEAD,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_NOPREFIX,39,9,156,21
CONTROL "",IDC_CBO_SMP_CHOOSE,"ComboBox",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP|CBS_HASSTRINGS|CBS_DROPDOWNLIST,3,36,194,60
- CONTROL "",IDC_STC_SMP_INFO,"Static",WS_CHILDWINDOW|WS_VISIBLE,3,60,195,35
+ CONTROL "",IDC_STC_SMP_INFO,"Static",WS_CHILDWINDOW|WS_VISIBLE,3,60,194,35
CONTROL "",IDC_STC_SMP_FIELD1,"Static",WS_CHILDWINDOW|WS_VISIBLE,3,105,194,10
CONTROL "",IDC_EDT_SMP_FIELD1,"Edit",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,3,117,194,13,WS_EX_CLIENTEDGE
CONTROL "",IDC_STC_SMP_FIELD2,"Static",WS_CHILDWINDOW|WS_VISIBLE,3,141,194,10
diff --git a/MirOTR/svcs_proto.cpp b/MirOTR/svcs_proto.cpp index 2d2bde6..6e78a23 100644 --- a/MirOTR/svcs_proto.cpp +++ b/MirOTR/svcs_proto.cpp @@ -14,9 +14,8 @@ int SVC_OTRSendMessage(WPARAM wParam,LPARAM lParam){ char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0);
if(proto && g_metaproto && strcmp(proto, g_metaproto) == 0) // bypass for metacontacts
- return CallService(MS_PROTO_CHAINSEND, wParam, lParam);
- char *username = contact_get_id(ccs->hContact); - if(!proto || !username) return 1; // error
+ return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + if(!proto || !ccs->hContact) return 1; // error
gcry_error_t err;
char *newmessage = 0;
@@ -43,7 +42,8 @@ int SVC_OTRSendMessage(WPARAM wParam,LPARAM lParam){ if (!(ccs->wParam & PREF_UTF)) mir_free(oldmessage_utf);
return CallService(MS_PROTO_CHAINSEND, wParam, lParam);
}
- +
+ char *username = contact_get_id(ccs->hContact); err = otrl_message_sending(otr_user_state, &ops, (void*)ccs->hContact, proto, proto, username, oldmessage_utf, NULL, &newmessage, add_appdata, (void*)ccs->hContact); @@ -148,9 +148,8 @@ int SVC_OTRRecvMessage(WPARAM wParam,LPARAM lParam){ return 1; //error
else if(proto && g_metaproto && strcmp(proto, g_metaproto) == 0) // bypass for metacontacts
return CallService(MS_PROTO_CHAINRECV, wParam, lParam);
-
- char *uname = contact_get_id(ccs->hContact);
- if(!uname) return 1; // error
+
+ if (!ccs->hContact) return 1; //error
char *oldmessage = pre->szMessage;
char *oldmessage_utf = NULL;
@@ -172,11 +171,13 @@ int SVC_OTRRecvMessage(WPARAM wParam,LPARAM lParam){ ConnContext *context; //NextExpectedSMP nextMsg; + char *uname = contact_get_id(ccs->hContact); lib_cs_lock(); ignore_msg = otrl_message_receiving(otr_user_state, &ops, (void*)ccs->hContact, proto, proto, uname, oldmessage_utf, &newmessage, &tlvs, add_appdata, (void*)ccs->hContact); lib_cs_unlock(); + mir_free(uname); if( !(pre->flags & PREF_UTF)) mir_free(oldmessage_utf); oldmessage_utf = NULL; @@ -282,8 +283,6 @@ int SVC_OTRRecvMessage(WPARAM wParam,LPARAM lParam){ } otrl_tlv_free(tlvs); - mir_free(uname); - /* If we're supposed to ignore this incoming message (because it's a * protocol message), set it to NULL, so that other plugins that * catch receiving-im-msg don't return 0, and cause it to be diff --git a/MirOTR/utils.cpp b/MirOTR/utils.cpp index 59dd5b2..6fe6dde 100644 --- a/MirOTR/utils.cpp +++ b/MirOTR/utils.cpp @@ -71,6 +71,23 @@ TrustLevel otr_context_get_trust(ConnContext *context) return level; } +/* Set verification of fingerprint */ +void VerifyFingerprint(ConnContext *context, bool verify) {
+ lib_cs_lock();
+ otrl_context_set_trust(context->active_fingerprint, (verify)?"verified":NULL);
+ otrl_privkey_write_fingerprints(otr_user_state, g_fingerprint_store_filename);
+ lib_cs_unlock();
+ VerifyFingerprintMessage(context, verify);
+} + +void VerifyFingerprintMessage(ConnContext *context, bool verify) { + TCHAR msg[1024]; + mir_sntprintf(msg, 1024, (verify)?TranslateT(LANG_FINGERPRINT_VERIFIED):TranslateT(LANG_FINGERPRINT_NOT_VERIFIED), contact_get_nameT((HANDLE)context->app_data));
+ msg[1023] = '\0';
+ ShowMessage((HANDLE)context->app_data, msg);
+ SetEncryptionStatus(context->app_data, otr_context_get_trust(context)); +} + /* Convert a 20-byte hash value to a 45-byte human-readable value */ void otrl_privkey_hash_to_humanT(TCHAR human[45], const unsigned char hash[20]) { diff --git a/MirOTR/utils.h b/MirOTR/utils.h index ac1ad1b..5dc0526 100644 --- a/MirOTR/utils.h +++ b/MirOTR/utils.h @@ -17,6 +17,8 @@ typedef enum { TRUST_PRIVATE } TrustLevel; TrustLevel otr_context_get_trust(ConnContext *context); +void VerifyFingerprint(ConnContext *context, bool verify); +void VerifyFingerprintMessage(ConnContext *context, bool verify); void otrl_privkey_hash_to_humanT(TCHAR human[45], const unsigned char hash[20]); diff --git a/MirOTR/version.h b/MirOTR/version.h index 04ace48..9f34a9e 100644 --- a/MirOTR/version.h +++ b/MirOTR/version.h @@ -8,7 +8,7 @@ #define VER_BUILD 1
#define __STRINGIZE(x) #x
-#define VER_STRING "0.9.1.1"
+#define VER_STRING "0.9.4.1"
#ifdef _UNICODE #define SHORT_NAME_STRING "Miranda OTR"
|