summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoradmin@progandy.co.cc <admin@progandy.co.cc@eced67a3-f377-a0ae-92ae-d6de1850b05a>2010-09-12 13:33:13 +0000
committeradmin@progandy.co.cc <admin@progandy.co.cc@eced67a3-f377-a0ae-92ae-d6de1850b05a>2010-09-12 13:33:13 +0000
commit8411617ad832612d074884ce7304516fe2459b48 (patch)
treea02d6d93c88418524972346284f6738420f9efc5
parent2ef110b55c664e80dddca099f1376c874f28fbc9 (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.cpp96
-rw-r--r--MirOTR/MirOTR.vcproj28
-rw-r--r--MirOTR/dialogs.cpp370
-rw-r--r--MirOTR/dialogs.h4
-rw-r--r--MirOTR/language.h23
-rw-r--r--MirOTR/options.cpp6
-rw-r--r--MirOTR/otr.cpp9
-rw-r--r--MirOTR/resources/resource.rc3
-rw-r--r--MirOTR/svcs_proto.cpp17
-rw-r--r--MirOTR/utils.cpp17
-rw-r--r--MirOTR/utils.h2
-rw-r--r--MirOTR/version.h2
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"