From 93cdc938be59db040fa2eb26c478d2328c34da7b Mon Sep 17 00:00:00 2001 From: Jay Threeth Date: Sat, 2 Apr 2011 18:56:23 -0700 Subject: checkpoint, non functional --- linden/indra/cmake/gpg.vs.cmake | 6 + linden/indra/cmake/libgcrypt.cmake | 8 + linden/indra/cmake/libgpg-error.cmake | 8 + linden/indra/cmake/libotr.cmake | 8 + linden/indra/cmake/libotrb.cmake | 4 + linden/indra/newview/app_settings/settings.xml | 71 +++ linden/indra/newview/llfirstuse.h | 4 + linden/indra/newview/llimpanel.h | 60 ++- linden/indra/newview/llprefsadvanced.cpp | 19 + linden/indra/newview/llstartup.cpp | 13 +- linden/indra/newview/otr_floater_smp_dialog.cpp | 438 ++++++++++++++++++ linden/indra/newview/otr_floater_smp_dialog.h | 63 +++ linden/indra/newview/otr_floater_smp_progress.cpp | 288 ++++++++++++ linden/indra/newview/otr_floater_smp_progress.h | 61 +++ linden/indra/newview/otr_wrapper.cpp | 487 +++++++++++++++++++++ linden/indra/newview/otr_wrapper.h | 58 +++ .../default/xui/en-us/floater_instant_message.xml | 40 ++ .../skins/default/xui/en-us/notifications.xml | 23 + .../default/xui/en-us/otr_floater_smp_dialog.xml | 131 ++++++ .../default/xui/en-us/otr_floater_smp_progress.xml | 52 +++ .../xui/en-us/panel_preferences_advanced.xml | 43 ++ 21 files changed, 1883 insertions(+), 2 deletions(-) create mode 100644 linden/indra/cmake/gpg.vs.cmake create mode 100644 linden/indra/cmake/libgcrypt.cmake create mode 100644 linden/indra/cmake/libgpg-error.cmake create mode 100644 linden/indra/cmake/libotr.cmake create mode 100644 linden/indra/cmake/libotrb.cmake create mode 100644 linden/indra/newview/otr_floater_smp_dialog.cpp create mode 100644 linden/indra/newview/otr_floater_smp_dialog.h create mode 100644 linden/indra/newview/otr_floater_smp_progress.cpp create mode 100644 linden/indra/newview/otr_floater_smp_progress.h create mode 100644 linden/indra/newview/otr_wrapper.cpp create mode 100644 linden/indra/newview/otr_wrapper.h create mode 100644 linden/indra/newview/skins/default/xui/en-us/otr_floater_smp_dialog.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/otr_floater_smp_progress.xml (limited to 'linden/indra') diff --git a/linden/indra/cmake/gpg.vs.cmake b/linden/indra/cmake/gpg.vs.cmake new file mode 100644 index 0000000..a5220f4 --- /dev/null +++ b/linden/indra/cmake/gpg.vs.cmake @@ -0,0 +1,6 @@ +# -*- cmake -*- + +# gpg.vs is just a place to put windows specific nastyness needed to +# make the libgcrypt, libgpg-error, and libotr compile. + +set(gpg.vs_INCLUDE_DIRS ) diff --git a/linden/indra/cmake/libgcrypt.cmake b/linden/indra/cmake/libgcrypt.cmake new file mode 100644 index 0000000..0134618 --- /dev/null +++ b/linden/indra/cmake/libgcrypt.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- + +set(LIBGCRYPT_INCLUDE_DIRS + ) + +set(LIBGCRYPT_LIBRARIES + libgcrypt + ) diff --git a/linden/indra/cmake/libgpg-error.cmake b/linden/indra/cmake/libgpg-error.cmake new file mode 100644 index 0000000..71deeaa --- /dev/null +++ b/linden/indra/cmake/libgpg-error.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- + +set(LIBGPG-ERROR_INCLUDE_DIRS + ) + +set(LIBGPG-ERROR_LIBRARIES + libgpg-error + ) diff --git a/linden/indra/cmake/libotr.cmake b/linden/indra/cmake/libotr.cmake new file mode 100644 index 0000000..3c07be2 --- /dev/null +++ b/linden/indra/cmake/libotr.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- + +set(LIBOTR_INCLUDE_DIRS + ) + +set(LIBOTR_LIBRARIES + libotr + ) diff --git a/linden/indra/cmake/libotrb.cmake b/linden/indra/cmake/libotrb.cmake new file mode 100644 index 0000000..eb8522f --- /dev/null +++ b/linden/indra/cmake/libotrb.cmake @@ -0,0 +1,4 @@ +# -*- cmake -*- +include(Prebuilt) + +set(OTR_LIBRARY otr) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index b6858b7..e55684a 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -198,6 +198,30 @@ Value 0 + + EmeraldUseOTR + + Comment + Setting this to 0 will require the use of OTR in every IM, 1 will try OTR when available, 2 will accept incoming OTR requests, and 3 will deny OTR usage + Persist + 1 + Type + U32 + Value + 2 + + EmeraldOTRInTypingStop + + Comment + Setting this to true will make all encrypted OTR messages be sent in an IM_TYPING_STOP packet. This is non-standard behavior, but prevents OTR encrypted IM from being saved and delivered as offline IM. Though it currently works the grid owners may decide to disable the feature at any time. + Persist + 1 + Type + Boolean + Value + 0 + + AppearanceAnimate Comment @@ -5644,6 +5668,40 @@ 0 + + OtrFloaterSmpDialogRect + + Comment + Rectangle for OTR's Authorize Buddy Dialog + Persist + 1 + Type + Rect + Value + + 0 + 440 + 470 + 0 + + + OtrFloaterSmpProgRect + + Comment + Rectangle for OTR's Authorize Buddy Progress bar Dialog + Persist + 1 + Type + Rect + Value + + 0 + 440 + 470 + 0 + + + FloaterActiveSpeakersRect Comment @@ -13805,6 +13863,19 @@ Value 1 + + WarnEmeraldOTR + + Comment + Enables OTR info dialog + Persist + 1 + Type + Boolean + Value + 1 + + WarnFirstAppearance Comment diff --git a/linden/indra/newview/llfirstuse.h b/linden/indra/newview/llfirstuse.h index 8c2ca35..c7a3634 100644 --- a/linden/indra/newview/llfirstuse.h +++ b/linden/indra/newview/llfirstuse.h @@ -115,6 +115,10 @@ public: static void useLoginScreen(); static void callbackClientTags(const LLSD& notification, const LLSD& response); static void ClientTags(); +#if USE_OTR // [$PLOTR$] + static void callbackEmeraldOTR(const LLSD& notification, const LLSD& response); + static void EmeraldOTR(); +#endif // USE_OTR // [/$PLOTR$] static void voiceLicenseAgreement(); static void callbackPrivacy(const LLSD& notification, const LLSD& response); static void Privacy(); diff --git a/linden/indra/newview/llimpanel.h b/linden/indra/newview/llimpanel.h index b5a0165..5a36648 100644 --- a/linden/indra/newview/llimpanel.h +++ b/linden/indra/newview/llimpanel.h @@ -42,6 +42,12 @@ #include "llvoiceclient.h" #include "llstyle.h" +#if USE_OTR // [$PLOTR$] +# include "otr_wrapper.h" +class OtrFloaterSmpDialog; +class OtrFloaterSmpProgress; +#endif // USE_OTR // [/$PLOTR$] + class LLLineEditor; class LLViewerTextEditor; class LLInventoryItem; @@ -175,6 +181,22 @@ private: BOOL mReceivedCall; }; +#if USE_OTR // [$PLOTR$] +extern void otr_authenticate_key(LLUUID session_id, const char *trust); +extern void otr_log_message_getstring_name(LLUUID session_id, const char *message_name); +extern void otr_log_message_getstring(LLUUID session_id, const char *message_name); +extern void otr_log_message(LLUUID session_id, const char *message); +extern void otr_show_status(LLUUID session_id); +extern void otr_deliver_message(const std::string& utf8_text, + const LLUUID& im_session_id, + const LLUUID& other_participant_id, + EInstantMessage dialog); +extern void deliver_message(const std::string& utf8_text, + const LLUUID& im_session_id, + const LLUUID& other_participant_id, + EInstantMessage dialog); +#endif // USE_OTR // [/$PLOTR$] + class LLFloaterIMPanel : public LLFloater { public: @@ -299,7 +321,43 @@ private: void removeTypingIndicator(const LLIMInfo* im_info); void sendTypingState(BOOL typing); - + +#if USE_OTR // [$PLOTR$] +public: + static void onClickOtr(LLUICtrl* source, void* userdata); + void doOtrMenu(); + void showOtrStatus(); + void otrLogMessage(std::string message); + void otrLogMessageGetstring(const char *message_name); + void otrLogMessageGetstringName(const char *message_name); + bool otherIsOtrAuthenticated(); + void otrAuthenticateKey(const char *trust); + void doOtrStart(); + void doOtrStop(bool pretend_they_did=false); + void pretendTheyOtrStop(); + ConnContext *getOtrContext(int add_if_not = 0, int *context_added = NULL); + void startSmpProgress(LLUUID session_id, LLUUID other_id, + std::string a_question, std::string a_secret_answer, + bool is_reply = false); + void startSmpProgress(LLUUID session_id, LLUUID other_id, + std::string a_secret, + bool is_reply = false); + void endSmpProgress(); + void endSmpDialog(); + void handleOtrTlvs(OtrlTLV *tlvs); +private: + void startSmpDialog(LLUUID session_id, LLUUID other_id, + std::string my_fingerprint, std::string other_fingerprint); + void startSmpDialogQA(LLUUID session_id, LLUUID other_id, + std::string question, OtrlTLV *tlv); + void startSmpDialogSS(LLUUID session_id, LLUUID other_id, + OtrlTLV *tlv); + void doOtrAuth(); + OtrlMessageState mOtrLastStatus; + OtrFloaterSmpDialog *mOtrSmpDialog; + OtrFloaterSmpProgress *mOtrSmpProgress; +#endif // USE_OTR // [/$PLOTR$] + private: LLLineEditor* mInputEditor; LLViewerTextEditor* mHistoryEditor; diff --git a/linden/indra/newview/llprefsadvanced.cpp b/linden/indra/newview/llprefsadvanced.cpp index 99bc4fd..17f7b09 100644 --- a/linden/indra/newview/llprefsadvanced.cpp +++ b/linden/indra/newview/llprefsadvanced.cpp @@ -47,6 +47,10 @@ #include "boost/algorithm/string.hpp" +#if USE_OTR // [$PLOTR$] +#include "llweb.h" +#endif // USE_OTR // [/$PLOTR$] + LLPrefsAdvanced* LLPrefsAdvanced::sInstance; LLPrefsAdvanced::LLPrefsAdvanced() @@ -116,6 +120,11 @@ BOOL LLPrefsAdvanced::postBuild() initHelpBtn("EmeraldHelp_SpellCheck", "EmeraldHelp_SpellCheck"); +#if USE_OTR // [$PLOTR$] + childSetValue("EmeraldUseOTR", LLSD((S32)gSavedSettings.getU32("EmeraldUseOTR"))); + getChild("otr_help_btn")->setClickedCallback(onClickOtrHelp, this); +#endif // USE_OTR // [/$PLOTR$] + refresh(); return TRUE; @@ -202,6 +211,9 @@ void LLPrefsAdvanced::apply() LLComboBox* crash_behavior_combobox = getChild("crash_behavior_combobox"); gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, crash_behavior_combobox->getCurrentIndex()); +#if USE_OTR // [$PLOTR$] + gSavedSettings.setU32("EmeraldUseOTR", (U32)childGetValue("EmeraldUseOTR").asReal()); +#endif // USE_OTR // [/$PLOTR$] } void LLPrefsAdvanced::cancel() @@ -349,3 +361,10 @@ void LLPrefsAdvanced::onClickCommandLine(void* data) FloaterCommandLine::getInstance()->open(); FloaterCommandLine::getInstance()->center(); } + +#if USE_OTR // [$PLOTR$] +void LLPrefsAdvanced::onClickOtrHelp(void* data) +{ + LLWeb::loadURL("http://www.cypherpunks.ca/otr/"); +} +#endif // USE_OTR // [/$PLOTR$] diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index d9ab5e7..d13e112 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -215,6 +215,10 @@ #include "hippogridmanager.h" #include "hippolimits.h" +#if USE_OTR // [$PLOTR$] +#include "otr_wrapper.h" +#endif // USE_OTR // [/$PLOTR$] + #include "lggautocorrect.h" // // exported globals @@ -2825,6 +2829,9 @@ bool idle_startup() } LLFirstUse::ClientTags(); +#if USE_OTR // [$PLOTR$] + LLFirstUse::EmeraldOTR(); +#endif // USE_OTR // [/$PLOTR$] // Add login location to teleport history 'teleported-into' LLVector3 agent_pos=gAgent.getPositionAgent(); @@ -2867,7 +2874,11 @@ bool idle_startup() { gAgent.requestEnterGodMode(); } - + +#if USE_OTR // [$PLOTR$] + OTR_Wrapper::init(); +#endif // USE_OTR // [/$PLOTR$] + // Start automatic replay if the flag is set. if (gSavedSettings.getBOOL("StatsAutoRun")) { diff --git a/linden/indra/newview/otr_floater_smp_dialog.cpp b/linden/indra/newview/otr_floater_smp_dialog.cpp new file mode 100644 index 0000000..06acdae --- /dev/null +++ b/linden/indra/newview/otr_floater_smp_dialog.cpp @@ -0,0 +1,438 @@ +/* otr_floater_smp_dialog.cpp - SMP dialog box + $PLOTR$ See http://www.cypherpunks.ca/otr/ + + Copyright (C) 2009 Chris Tuchs + + This is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This 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 Lesser General Public + License along with the viewer; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "llviewerprecompiledheaders.h" + +#include "llagent.h" +#include "llcachename.h" +#include "llcombobox.h" +#include "llimpanel.h" +#include "lluictrlfactory.h" +#include "llweb.h" + +#include "otr_floater_smp_progress.h" +#include "otr_floater_smp_dialog.h" + +std::string OtrFloaterSmpDialog::getStringName(const char *message_name) +{ + LLUIString message = getString(message_name); + std::string them; + if (!gCacheName->getFullName(mOtherParticipantUUID, them)) them = getString("otr_generic_name"); + message.setArg("[NAME]", them); + return message.getString(); +} + +void OtrFloaterSmpDialog::init() +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "otr_floater_smp_dialog.xml"); +} + +OtrFloaterSmpDialog::OtrFloaterSmpDialog( + LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string my_fingerprint, std::string other_fingerprint) + : LLFloater(std::string("otr_floater_smp_dialog"), std::string("OtrFloaterSmpDialogRect"), LLStringUtil::null), + mIMPanel(im_panel), mIsReply(false), + mSessionUUID(session_id), mOtherParticipantUUID(other_id), + mQuestion(""), + mMyFingerprint(my_fingerprint), mOtherFingerprint(other_fingerprint) +{ + init(); +} + +OtrFloaterSmpDialog::OtrFloaterSmpDialog( + LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string question, OtrlTLV *tlv) + : LLFloater(std::string("otr_floater_smp_dialog"), std::string("OtrFloaterSmpDialogRect"), LLStringUtil::null), + mIMPanel(im_panel), mIsReply(true), + mSessionUUID(session_id), mOtherParticipantUUID(other_id), + mQuestion(question), + mMyFingerprint(""), mOtherFingerprint("") +{ + init(); + LLComboBox *combo = getChild("otr_smp_how_combo"); + if (!combo) + { + llwarns << "$PLOTR$ Can't find OTR SMP how combo" << llendl; + return; + } + combo->removeall(); + combo->add(getString("otr_smp_how_by_qa_challenge"), ADD_BOTTOM, TRUE); + combo->selectFirstItem(); + doComboMenu(); +} + +OtrFloaterSmpDialog::OtrFloaterSmpDialog( + LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + OtrlTLV *tlv) + : LLFloater(std::string("otr_floater_smp_dialog"), std::string("OtrFloaterSmpDialogRect"), LLStringUtil::null), + mIMPanel(im_panel), mIsReply(true), + mSessionUUID(session_id), mOtherParticipantUUID(other_id), + mQuestion(""), + mMyFingerprint(""), mOtherFingerprint("") +{ + init(); + LLComboBox *combo = getChild("otr_smp_how_combo"); + if (!combo) + { + llwarns << "$PLOTR$ Can't find OTR SMP how combo" << llendl; + return; + } + combo->removeall(); + combo->add(getString("otr_smp_how_by_ss_challenge"), ADD_BOTTOM, TRUE); + combo->selectFirstItem(); + doComboMenu(); +} + +OtrFloaterSmpDialog::~OtrFloaterSmpDialog() +{ +} + +BOOL OtrFloaterSmpDialog::postBuild() +{ + childSetAction("otr_smp_help_btn", onClickHelp, this); + childSetAction("otr_smp_cancel_btn", onClickCancel, this); + childSetAction("otr_smp_auth_btn", onClickAuth, this); + LLComboBox *veri = getChild("otr_smp_veri_combo"); + veri->setCommitCallback(onClickVeri); + veri->setCallbackUserData(this); + LLComboBox *combo = getChild("otr_smp_how_combo"); + combo->setCommitCallback(onClickCombo); + combo->setCallbackUserData(this); + combo->removeall(); + combo->add(getString("otr_smp_how_by_qa"), ADD_BOTTOM, TRUE); + combo->add(getString("otr_smp_how_by_ss"), ADD_BOTTOM, TRUE); + combo->add(getString("otr_smp_how_by_mfv"), ADD_BOTTOM, TRUE); + combo->selectFirstItem(); + doComboMenu(); + LLTextBox *why = getChild("otr_smp_why"); + if (why) why->setWrappedText(getString("otr_smp_why_text")); + LLTextBox *how = getChild("otr_smp_how_text"); + if (mIsReply) + { + if (how) how->setWrappedText(getStringName("otr_smp_how_name_challenge_me")); + setTitle(getStringName("otr_smp_name_auth_me")); + } + else + { + if (how) how->setWrappedText(getStringName("otr_smp_how_I_challenge_name")); + setTitle(getStringName("otr_smp_I_auth_name")); + } + return TRUE; +} + +void OtrFloaterSmpDialog::show() +{ + this->open(); /*Flawfinder: ignore*/ + this->setFocus(TRUE); + this->center(); +} + +void OtrFloaterSmpDialog::doVeriMenu() +{ + LLComboBox *veri = getChild("otr_smp_veri_combo"); + if (!veri) + { + llwarns << "$PLOTR$ Can't find OTR SMP verified combo" << llendl; + return; + } + LLButton* auth_btn = getChild("otr_smp_auth_btn"); + if (!auth_btn) + { + llwarns << "$PLOTR$ Can't find OTR SMP authenticate button" << llendl; + return; + } + if (getString("otr_smp_veri_no") == veri->getSimple()) + { + auth_btn->setEnabled(FALSE); + } + else + { + auth_btn->setEnabled(TRUE); + } +} + +void OtrFloaterSmpDialog::doComboMenu() +{ + LLComboBox *combo = getChild("otr_smp_how_combo"); + if (!combo) + { + llwarns << "$PLOTR$ Can't find OTR SMP how combo" << llendl; + return; + } + LLTextBox *howto = getChild("otr_smp_howto"); + if (!howto) + { + llwarns << "$PLOTR$ Can't find OTR SMP howto control" << llendl; + return; + } + LLTextBox *label1 = getChild("otr_smp_label1"); + if (!label1) + { + llwarns << "$PLOTR$ Can't find OTR SMP label1 control" << llendl; + return; + } + LLLineEditor *edit1 = getChild("otr_smp_edit1"); + if (!edit1) + { + llwarns << "$PLOTR$ Can't find OTR SMP edit1 control" << llendl; + return; + } + LLTextBox *label2 = getChild("otr_smp_label2"); + if (!label2) + { + llwarns << "$PLOTR$ Can't find OTR SMP label2 control" << llendl; + return; + } + LLLineEditor *edit2 = getChild("otr_smp_edit2"); + if (!edit2) + { + llwarns << "$PLOTR$ Can't find OTR SMP edit2 control" << llendl; + return; + } + LLComboBox *veri = getChild("otr_smp_veri_combo"); + if (!veri) + { + llwarns << "$PLOTR$ Can't find OTR SMP verified combo" << llendl; + return; + } + std::string choice = combo->getSimple(); + if (getString("otr_smp_how_by_qa") == choice) + { + howto->setWrappedText(getString("otr_smp_howto_qa")); + label1->setWrappedText(getString("otr_smp_howto_qa_t1")); + edit1->clear(); + edit1->setEnabled(TRUE); + label2->setWrappedText(getString("otr_smp_howto_qa_t2")); + edit2->clear(); + edit2->setEnabled(TRUE); + veri->removeall(); + veri->setLabel(getString("otr_empty_string")); + } + else if (getString("otr_smp_how_by_qa_challenge") == choice) + { + howto->setWrappedText(getString("otr_smp_howto_qa")); + label1->setWrappedText(getString("otr_smp_howto_qa_t1")); + edit1->setText(mQuestion); + edit1->setEnabled(FALSE); + label2->setWrappedText(getString("otr_smp_howto_qa_t2")); + edit2->clear(); + edit2->setEnabled(TRUE); + veri->removeall(); + veri->setLabel(getString("otr_empty_string")); + } + else if (getString("otr_smp_how_by_ss") == choice) + { + howto->setWrappedText(getString("otr_smp_howto_ss")); + label1->setWrappedText(getString("otr_smp_howto_ss_t1")); + edit1->clear(); + edit1->setEnabled(TRUE); + label2->setWrappedText(getString("otr_smp_howto_ss_t2")); + edit2->clear(); + edit2->setEnabled(FALSE); + veri->removeall(); + veri->setLabel(getString("otr_empty_string")); + } + else if (getString("otr_smp_how_by_ss_challenge") == choice) + { + howto->setWrappedText(getString("otr_smp_howto_ss")); + label1->setWrappedText(getString("otr_smp_howto_ss_t1")); + edit1->clear(); + edit1->setEnabled(TRUE); + label2->setWrappedText(getString("otr_smp_howto_ss_t2")); + edit2->clear(); + edit2->setEnabled(FALSE); + veri->removeall(); + veri->setLabel(getString("otr_empty_string")); + } + else if (getString("otr_smp_how_by_mfv") == choice) + { + howto->setWrappedText(getString("otr_smp_howto_mfv")); + label1->setWrappedText(getString("otr_smp_howto_mfv_t1")); + edit1->setText(mMyFingerprint); + edit1->setEnabled(FALSE); + label2->setWrappedText(getString("otr_smp_howto_mfv_t2")); + edit2->setText(mOtherFingerprint); + edit2->setEnabled(FALSE); + veri->add(getString("otr_smp_veri_no"), ADD_BOTTOM, TRUE); + veri->add(getString("otr_smp_veri_yes"), ADD_BOTTOM, TRUE); + veri->selectFirstItem(); + } + else + { + llwarns << "$PLOTR$ unknown smp howto choice" << llendl; + } + doVeriMenu(); +} + +// static +void OtrFloaterSmpDialog::onClickCombo(LLUICtrl* source, void* userdata) +{ + OtrFloaterSmpDialog* self = (OtrFloaterSmpDialog*)userdata; + if (!self) + { + llwarns << "$PLOTR$ can't find OTR SMP dialog." << llendl; + } + else + { + self->doComboMenu(); + } +} + +// static +void OtrFloaterSmpDialog::onClickVeri(LLUICtrl* source, void* userdata) +{ + OtrFloaterSmpDialog* self = (OtrFloaterSmpDialog*)userdata; + if (!self) + { + llwarns << "$PLOTR$ can't find OTR SMP dialog." << llendl; + } + else + { + self->doVeriMenu(); + } +} + +// static +void OtrFloaterSmpDialog::onClickHelp(void*) +{ + LLWeb::loadURL("http://www.cypherpunks.ca/otr/help/3.2.0/authenticate.php"); +} + +// virtual +void OtrFloaterSmpDialog::onClose(bool app_quitting) +{ + destroy(); + if (!mIMPanel) + { + llwarns << "$PLOTR$ Can't find mIMPanel." << llendl; + } + else + { + mIMPanel->endSmpDialog(); + } +} + +// static +void OtrFloaterSmpDialog::onClickCancel(void* userdata) +{ + OtrFloaterSmpDialog *self= (OtrFloaterSmpDialog*)userdata; + if (!self) + { + llwarns << "$PLOTR$ can't find OTR SMP dialog." << llendl; + return; + } + self->close(); +} + +void OtrFloaterSmpDialog::doClickAuth() +{ + LLComboBox *combo = getChild("otr_smp_how_combo"); + if (!combo) + { + llwarns << "$PLOTR$ Can't find OTR SMP how combo" << llendl; + return; + } + LLTextBox *howto = getChild("otr_smp_howto"); + if (!howto) + { + llwarns << "$PLOTR$ Can't find OTR SMP howto control" << llendl; + return; + } + LLTextBox *label1 = getChild("otr_smp_label1"); + if (!label1) + { + llwarns << "$PLOTR$ Can't find OTR SMP label1 control" << llendl; + return; + } + LLLineEditor *edit1 = getChild("otr_smp_edit1"); + if (!edit1) + { + llwarns << "$PLOTR$ Can't find OTR SMP edit1 control" << llendl; + return; + } + LLTextBox *label2 = getChild("otr_smp_label2"); + if (!label2) + { + llwarns << "$PLOTR$ Can't find OTR SMP label2 control" << llendl; + return; + } + LLLineEditor *edit2 = getChild("otr_smp_edit2"); + if (!edit2) + { + llwarns << "$PLOTR$ Can't find OTR SMP edit2 control" << llendl; + return; + } + LLComboBox *veri = getChild("otr_smp_veri_combo"); + if (!veri) + { + llwarns << "$PLOTR$ Can't find OTR SMP verified combo" << llendl; + return; + } + std::string choice = combo->getSimple(); + if (getString("otr_smp_how_by_qa") == choice) + { + llinfos << "$PLOTR$ OTR SMP QA method chosen" << llendl; + std::string question = edit1->getText(); + std::string answer = edit2->getText(); + mIMPanel->startSmpProgress(mSessionUUID, mOtherParticipantUUID, question, answer); + } + else if (getString("otr_smp_how_by_ss") == choice) + { + llinfos << "$PLOTR$ OTR SMP SS method chosen" << llendl; + std::string secret = edit1->getText(); + mIMPanel->startSmpProgress(mSessionUUID, mOtherParticipantUUID, secret); + } + else if (getString("otr_smp_how_by_mfv") == choice) + { + if (getString("otr_smp_veri_yes") == veri->getSimple()) + { + llinfos << "$PLOTR$ OTR SMP MFV authenticating " << mOtherParticipantUUID << llendl; + otr_authenticate_key(mSessionUUID, "mfv"); + } + } + else if (getString("otr_smp_how_by_qa_challenge") == choice) + { + std::string answer = edit2->getText(); + mIMPanel->startSmpProgress(mSessionUUID, mOtherParticipantUUID, mQuestion, answer, true); + } + else if (getString("otr_smp_how_by_ss_challenge") == choice) + { + std::string secret = edit1->getText(); + mIMPanel->startSmpProgress(mSessionUUID, mOtherParticipantUUID, secret, true); + } + else + { + llwarns << "$PLOTR$ unknown smp howto choice" << llendl; + } +} + +// static +void OtrFloaterSmpDialog::onClickAuth(void* userdata) +{ + OtrFloaterSmpDialog *self= (OtrFloaterSmpDialog*)userdata; + if (!self) + { + llwarns << "$PLOTR$ can't find OTR SMP dialog." << llendl; + return; + } + self->doClickAuth(); + self->close(); +} + diff --git a/linden/indra/newview/otr_floater_smp_dialog.h b/linden/indra/newview/otr_floater_smp_dialog.h new file mode 100644 index 0000000..bb01b71 --- /dev/null +++ b/linden/indra/newview/otr_floater_smp_dialog.h @@ -0,0 +1,63 @@ +/* otr_floater_smp_dialog.h - SMP dialog box [$PLOTR$] + See http://www.cypherpunks.ca/otr/ + + Copyright (C) 2009 Chris Tuchs + + This is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This 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 Lesser General Public + License along with the viewer; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef OTR_FLOATER_SMP_DIALOG_H_INCLUDED +#define OTR_FLOATER_SMP_DIALOG_H_INCLUDED 1 + +#include "llfloater.h" +class LLFloaterIMPanel; + +class OtrFloaterSmpDialog +: public LLFloater +{ +private: + LLUUID mOtherParticipantUUID; + LLUUID mSessionUUID; + std::string mQuestion; + std::string mMyFingerprint; + std::string mOtherFingerprint; + LLFloaterIMPanel *mIMPanel; + bool mIsReply; + + static void onClickHelp(void* userdata); + static void onClickCancel(void* userdata); + void doComboMenu(); + static void onClickCombo(LLUICtrl* source, void* userdata); + void doVeriMenu(); + static void onClickVeri(LLUICtrl* source, void* userdata); + void doClickAuth(); + static void onClickAuth(void* userdata); + std::string getStringName(const char *message_name); + +public: + OtrFloaterSmpDialog(LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string my_fingerprint, std::string other_fingerprint); + OtrFloaterSmpDialog(LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string question, OtrlTLV *tlv); + OtrFloaterSmpDialog(LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + OtrlTLV *tlv); + virtual ~OtrFloaterSmpDialog(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + + void show(); + void init(); +}; +#endif // ndef OTR_FLOATER_SMP_DIALOG_H_INCLUDED [/$PLOTR$] diff --git a/linden/indra/newview/otr_floater_smp_progress.cpp b/linden/indra/newview/otr_floater_smp_progress.cpp new file mode 100644 index 0000000..76bfc6e --- /dev/null +++ b/linden/indra/newview/otr_floater_smp_progress.cpp @@ -0,0 +1,288 @@ +/* otr_floater_smp_progress.cpp - SMP progress dialog box [$PLOTR$] + See http://www.cypherpunks.ca/otr/ + + Copyright (C) 2009 Chris Tuchs + + This is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This 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 Lesser General Public + License along with the viewer; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "llviewerprecompiledheaders.h" + +#include "llagent.h" +#include "llcachename.h" +#include "llimpanel.h" +#include "llprogressbar.h" +#include "lluictrlfactory.h" +#include "llweb.h" + +#include "otr_wrapper.h" +#include "otr_floater_smp_progress.h" + +void OtrFloaterSmpProgress::init() +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "otr_floater_smp_progress.xml"); + childSetAction("otr_smp_prog_help_btn", onClickHelp, this); + childSetAction("otr_smp_prog_cancel_btn", onClickCancel, this); + childSetAction("otr_smp_prog_ok_btn", onClickOk, this); + setDefaultBtn("otr_smp_prog_cancel_btn"); + LLUIString title = mIsReply + ? getString("otr_smp_prog_name_auth_me") + : getString("otr_smp_prog_I_auth_name"); + std::string them; + if (!gCacheName->getFullName(mOtherParticipantUUID, them)) them = getString("otr_generic_name"); + title.setArg("[NAME]", them); + setTitle(title.getString()); +} + +OtrFloaterSmpProgress::OtrFloaterSmpProgress( + LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string a_question, std::string a_secret_answer, bool is_reply) +: LLFloater(std::string("otr_floater_smp_progress"), std::string("OtrFloaterSmpProgRect"), LLStringUtil::null), + mIMPanel(im_panel), mIsReply(is_reply), + mSessionUUID(session_id), mOtherParticipantUUID(other_id), + mQuestion(a_question), mSecretAnswer(a_secret_answer), + mSecretAnswerOnly(false) +{ + init(); + if (!gOTR) + { + llwarns << "$PLOTR$ Can't find gOTR." << llendl; + setFinalStatus("otr_smp_prog_auth_errored"); + return; + } + if (!mIMPanel) + { + llwarns << "$PLOTR$ Can't find mIMPanel." << llendl; + setFinalStatus("otr_smp_prog_auth_errored"); + return; + } + ConnContext *context = mIMPanel->getOtrContext(); + if (!context) + { + llwarns << "$PLOTR$ Can't find context." << llendl; + setFinalStatus("otr_smp_prog_auth_errored"); + return; + } + if (mIsReply) + { + otrl_message_respond_smp( + gOTR->get_userstate(), + gOTR->get_uistate(), + &mSessionUUID, + context, + (const unsigned char *)mSecretAnswer.c_str(), + mSecretAnswer.length()); + setPercent(50); + setStatusName("otr_smp_prog_name_auth_me"); + } + else + { + otrl_message_initiate_smp_q( + gOTR->get_userstate(), + gOTR->get_uistate(), + &mSessionUUID, + context, + mQuestion.c_str(), + (const unsigned char *)mSecretAnswer.c_str(), + mSecretAnswer.length()); + setStatusName("otr_smp_prog_I_auth_name"); + } +} + +OtrFloaterSmpProgress::OtrFloaterSmpProgress( + LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string a_secret_answer, bool is_reply) +: LLFloater(std::string("otr_floater_smp_progress"), std::string("OtrFloaterSmpProgRect"), LLStringUtil::null), + mIMPanel(im_panel), mIsReply(is_reply), + mSessionUUID(session_id), mOtherParticipantUUID(other_id), + mSecretAnswer(a_secret_answer), + mSecretAnswerOnly(true) +{ + init(); + if (!gOTR) + { + llwarns << "$PLOTR$ Can't find gOTR." << llendl; + setFinalStatus("otr_smp_prog_auth_errored"); + return; + } + if (!mIMPanel) + { + llwarns << "$PLOTR$ Can't find mIMPanel." << llendl; + setFinalStatus("otr_smp_prog_auth_errored"); + return; + } + ConnContext *context = mIMPanel->getOtrContext(); + if (!context) + { + llwarns << "$PLOTR$ Can't find context." << llendl; + setFinalStatus("otr_smp_prog_auth_errored"); + return; + } + if (mIsReply) + { + otrl_message_respond_smp( + gOTR->get_userstate(), + gOTR->get_uistate(), + &mSessionUUID, + context, + (const unsigned char *)mSecretAnswer.c_str(), + mSecretAnswer.length()); + setPercent(50); + setStatusName("otr_smp_prog_name_auth_me"); + } + else + { + otrl_message_initiate_smp( + gOTR->get_userstate(), + gOTR->get_uistate(), + &mSessionUUID, + context, + (const unsigned char *)mSecretAnswer.c_str(), + mSecretAnswer.length()); + setStatusName("otr_smp_prog_I_auth_name"); + } +} + +OtrFloaterSmpProgress::~OtrFloaterSmpProgress() +{ +} + +BOOL OtrFloaterSmpProgress::postBuild() +{ + mProgressBar = getChild("otr_smp_prog_progress_bar"); + LLButton* cancel_btn = getChild("otr_smp_prog_cancel_btn"); + cancel_btn->setEnabled(TRUE); + LLButton* ok_btn = getChild("otr_smp_prog_ok_btn"); + ok_btn->setEnabled(FALSE); + return TRUE; +} + +void OtrFloaterSmpProgress::show() +{ + this->open(); /*Flawfinder: ignore*/ + this->center(); +} + +void OtrFloaterSmpProgress::setPercent(float percent) +{ + mProgressBar->setPercent(percent); + if (100 <= percent) + { + LLButton* cancel_btn = getChild("otr_smp_prog_cancel_btn"); + cancel_btn->setEnabled(FALSE); + LLButton* ok_btn = getChild("otr_smp_prog_ok_btn"); + ok_btn->setEnabled(TRUE); + } + else + { + LLButton* cancel_btn = getChild("otr_smp_prog_cancel_btn"); + cancel_btn->setEnabled(TRUE); + LLButton* ok_btn = getChild("otr_smp_prog_ok_btn"); + ok_btn->setEnabled(FALSE); + } +} + +void OtrFloaterSmpProgress::setStatus(const char *message_string_name) +{ + LLTextBox *status = getChild("otr_smp_prog_status"); + if (!status) + { + llwarns << "$PLOTR$ Can't find OTR progress status textbox" << llendl; + return; + } + status->setWrappedText(getString(message_string_name)); +} + +void OtrFloaterSmpProgress::setStatusName(const char *message_string_name) +{ + LLTextBox *status = getChild("otr_smp_prog_status"); + if (!status) + { + llwarns << "$PLOTR$ Can't find OTR progress status textbox" << llendl; + return; + } + LLUIString msg = getString(message_string_name); + std::string them; + if (!gCacheName->getFullName(mOtherParticipantUUID, them)) them = getString("otr_generic_name"); + msg.setArg("[NAME]", them); + status->setWrappedText(msg.getString()); +} + +void OtrFloaterSmpProgress::setFinalStatus(const char *message_string_name) +{ + setPercent(100); + setStatusName(message_string_name); +} + +// static +void OtrFloaterSmpProgress::onClickHelp(void*) +{ + LLWeb::loadURL("http://www.cypherpunks.ca/otr/help/3.2.0/authenticate.php"); +} + +// static +void OtrFloaterSmpProgress::onClickCancel(void* userdata) +{ + OtrFloaterSmpProgress *self= (OtrFloaterSmpProgress*)userdata; + if (!self) + { + llwarns << "$PLOTR$ can't find OTR SMP PROG dialog." << llendl; + return; + } + if (!self->mIMPanel) + { + llwarns << "$PLOTR$ Can't find mIMPanel." << llendl; + return; + } + ConnContext *context = self->mIMPanel->getOtrContext(); + if (!context) + { + llwarns << "$PLOTR$ Can't find context." << llendl; + return; + } + otrl_message_abort_smp( + gOTR->get_userstate(), + gOTR->get_uistate(), + &(self->mSessionUUID), + context); + self->close(); +} + +// static +void OtrFloaterSmpProgress::onClickOk(void* userdata) +{ + OtrFloaterSmpProgress *self= (OtrFloaterSmpProgress*)userdata; + if (!self) + { + llwarns << "$PLOTR$ can't find OTR SMP PROG dialog." << llendl; + return; + } + self->close(); +} + +// virtual +void OtrFloaterSmpProgress::onClose(bool app_quitting) +{ + destroy(); + if (!mIMPanel) + { + llwarns << "$PLOTR$ Can't find mIMPanel." << llendl; + } + else + { + mIMPanel->endSmpProgress(); + } +} +// [/$PLOTR$] diff --git a/linden/indra/newview/otr_floater_smp_progress.h b/linden/indra/newview/otr_floater_smp_progress.h new file mode 100644 index 0000000..05ff208 --- /dev/null +++ b/linden/indra/newview/otr_floater_smp_progress.h @@ -0,0 +1,61 @@ +/* otr_floater_smp_progress.h - SMP progress dialog box [$PLOTR$] + See http://www.cypherpunks.ca/otr/ + + Copyright (C) 2009 Chris Tuchs + + This is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This 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 Lesser General Public + License along with the viewer; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef OTR_FLOATER_SMP_PROGRESS_H_INCLUDED +#define OTR_FLOATER_SMP_PROGRESS_H_INCLUDED 1 + +#include "llfloater.h" +class LLFloaterIMPanel; +class LLProgressBar; + +class OtrFloaterSmpProgress +: public LLFloater +{ +private: + LLUUID mOtherParticipantUUID; + LLUUID mSessionUUID; + std::string mQuestion; + std::string mSecretAnswer; + bool mSecretAnswerOnly; + LLFloaterIMPanel *mIMPanel; + LLProgressBar* mProgressBar; + bool mIsReply; + + static void onClickHelp(void* userdata); + static void onClickCancel(void* userdata); + static void onClickOk(void* userdata); + + void init(); +public: + OtrFloaterSmpProgress(LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string a_question, std::string a_secret_answer, bool is_reply = false); + OtrFloaterSmpProgress(LLFloaterIMPanel *im_panel, LLUUID session_id, LLUUID other_id, + std::string a_secret_answer, bool is_reply = false); + void setPercent(float percent); + void setStatus(const char *message_string_name); + void setStatusName(const char *message_string_name); + void setFinalStatus(const char *message_string_name); + virtual ~OtrFloaterSmpProgress(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + + void show(); +}; +#endif // ndef OTR_FLOATER_SMP_PROGRESS_H_INCLUDED [/$PLOTR$] diff --git a/linden/indra/newview/otr_wrapper.cpp b/linden/indra/newview/otr_wrapper.cpp new file mode 100644 index 0000000..abd1c91 --- /dev/null +++ b/linden/indra/newview/otr_wrapper.cpp @@ -0,0 +1,487 @@ +/* otr_wrapper.cpp - wrap libotr for use in the second life viewer + $PLOTR$ See http://www.cypherpunks.ca/otr/ + + Copyright (C) 2009 Chris Tuchs + + This is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This 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 Lesser General Public + License along with the viewer; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "llviewerprecompiledheaders.h" +#include "llviewercontrol.h" +#include "llimpanel.h" +#include "otr_wrapper.h" +#include "llagent.h" +#include "llimview.h" + + +OTR_Wrapper *gOTR = 0; + +OTR_Wrapper::OTR_Wrapper() +{ +} + +OTR_Wrapper::~OTR_Wrapper() +{ + if (gOTR) + { + otrl_userstate_free(gOTR->userstate); + } +} + +#define otrwui_tracing 1 // $TODO$ use some debug compile flag? +#if otrwui_tracing +extern "C" void otrwui_trace(const char *msg) +{ + llinfos << "$PLOTR$TRACE$" << msg << llendl; +} +#else +#define otrwui_trace(x) /* nothing */ +#endif + +static void otrwui_tbd(const char *msg) +{ + llinfos << "$PLOTR$TBD$" << msg << llendl; +} + +static OtrlPolicy otrwui_policy(void *opdata, ConnContext *context) +{ + OtrlPolicy result = 0; + U32 useotr = gSavedSettings.getU32("EmeraldUseOTR"); + if (3 < useotr) + { + llwarns << "$PLOTR$ Unknown setting for EmeraldUseOTR" << useotr << llendl; + useotr = 2; + } + if (0 == useotr) // Require use of OTR in IMs + { + result = (0 +// | OTRL_POLICY_ALLOW_V1 // don't even expose this? + | OTRL_POLICY_ALLOW_V2 + | OTRL_POLICY_REQUIRE_ENCRYPTION + | OTRL_POLICY_SEND_WHITESPACE_TAG + | OTRL_POLICY_WHITESPACE_START_AKE + | OTRL_POLICY_ERROR_START_AKE + ); + } + else if (1 == useotr) // Request OTR if available + { + result = (0 +// | OTRL_POLICY_ALLOW_V1 // don't even expose this? + | OTRL_POLICY_ALLOW_V2 +// | OTRL_POLICY_REQUIRE_ENCRYPTION + | OTRL_POLICY_SEND_WHITESPACE_TAG + | OTRL_POLICY_WHITESPACE_START_AKE + | OTRL_POLICY_ERROR_START_AKE + ); + } + else if (2 == useotr) // Accept OTR requests + { + result = (0 +// | OTRL_POLICY_ALLOW_V1 // don't even expose this? + | OTRL_POLICY_ALLOW_V2 +// | OTRL_POLICY_REQUIRE_ENCRYPTION +// | OTRL_POLICY_SEND_WHITESPACE_TAG + | OTRL_POLICY_WHITESPACE_START_AKE + | OTRL_POLICY_ERROR_START_AKE + ); + } + else if (3 == useotr) // Decline use of OTR + { + result = (0 +// | OTRL_POLICY_ALLOW_V1 // don't even expose this? +// | OTRL_POLICY_ALLOW_V2 +// | OTRL_POLICY_REQUIRE_ENCRYPTION +// | OTRL_POLICY_SEND_WHITESPACE_TAG +// | OTRL_POLICY_WHITESPACE_START_AKE +// | OTRL_POLICY_ERROR_START_AKE + ); + } + return result; +} + + + +static void otrwui_create_privkey( + void *opdata, const char *accountname, + const char *protocol) +{ + otrwui_trace("otrwui_create_privkey()"); + /* Create a private key for the given accountname/protocol if + * desired. */ + if (gOTR) + { + LLUUID session_id = *((LLUUID*)opdata); + otr_log_message_getstring(session_id, "otr_gen_key_please_wait"); + std::string path = + gDirUtilp->getExpandedFilename( + LL_PATH_PER_SL_ACCOUNT, OTR_PRIVATE_KEYS_FILE); + otrl_privkey_generate( + gOTR->get_userstate(), path.c_str(), accountname, protocol); + } +} + +static int otrwui_is_logged_in( + void *opdata, const char *accountname, + const char *protocol, const char *recipient) +{ + /* Report whether you think the given user is online. Return 1 if + * you think he is, 0 if you think he isn't, -1 if you're not sure. + * + * If you return 1, messages such as heartbeats or other + * notifications may be sent to the user, which could result in "not + * logged in" errors if you're wrong. */ + LLUUID recipient_uuid(recipient); + const LLRelationship* info = NULL; + info = LLAvatarTracker::instance().getBuddyInfo(recipient_uuid); + int result; + if (!info) result = 1; // hack, should be -1. but we'll pretend non-friends are always online + else if (!info->isOnline()) result = 0; + else result = 1; +#if otrwui_tracing + std::string msg = "otrwui_is_logged_in()"; + switch(result) + { + case -1: msg += " -1 unknown"; break; + case 0: msg += " 0 no, logged out"; break; + case 1: msg += " 1 yes, logged in"; break; + default: msg += " ? imposible result"; break; + } + otrwui_trace(msg.c_str()); +#endif + return result; +} + +static void otrwui_inject_message( + void *opdata, const char *accountname, + const char *protocol, const char *recipient, const char *message) +{ + otrwui_trace("otrwui_inject_message()"); + /* Send the given IM to the given recipient from the given + * accountname/protocol. */ + if (!opdata) + { + // don't know how to deliver this with no opdata. + llwarns << "$PLOTR$ otrwui_inject_message() called with NULL opdata; not delivering message" << llendl; + } + else + { + LLUUID sessionUUID = *((LLUUID*)opdata); + LLUUID otherUUID(recipient); + otr_deliver_message(message, sessionUUID, otherUUID, IM_NOTHING_SPECIAL); + } +} + +static void otrwui_notify( + void *opdata, OtrlNotifyLevel level, + const char *accountname, const char *protocol, + const char *username, const char *title, + const char *primary, const char *secondary) +{ + /* Display a notification message for a particular accountname / + * protocol / username conversation. */ + std::string trace = "otrwui_notify: \n"; + trace += "title("; trace += title; trace += ")\n"; + trace += "primary("; trace += primary; trace += ")\n"; + trace += "secondary("; trace += secondary; trace += ")"; + otrwui_tbd(trace.c_str()); // $TODO$ write me +} + +static int otrwui_display_otr_message( + void *opdata, const char *accountname, + const char *protocol, const char *username, const char *msg) +{ + /* Display an OTR control message for a particular accountname / + * protocol / username conversation. Return 0 if you are able to + * successfully display it. If you return non-0 (or if this + * function is NULL), the control message will be displayed inline, + * as a received message, or else by using the above notify() + * callback. */ + otrwui_trace("otrwui_log_message()"); + LLUUID sessionUUID = *((LLUUID*)opdata); + otr_log_message(sessionUUID, msg); + return 0; +} + +static void otrwui_update_context_list( + void *opdata) +{ + /* When the list of ConnContexts changes (including a change in + * state), this is called so the UI can be updated. */ + otrwui_tbd("otrwui_update_context_list"); // $TODO$ write me +} + +static const char *otrwui_protocol_name( + void *opdata, const char *protocol) +{ + /* Return a newly allocated string containing a human-friendly name + * for the given protocol id */ + otrwui_trace("otrwui_protocol_name()"); + return "SecondLife"; +} + +static void otrwui_protocol_name_free( + void *opdata, const char *protocol_name) +{ + /* Deallocate a string allocated by protocol_name */ + otrwui_trace("otrwui_protocol_name_free()"); + return; // no need to deallocate a const char * +} + +static void otrwui_new_fingerprint( + void *opdata, OtrlUserState us, + const char *accountname, const char *protocol, + const char *username, unsigned char fingerprint[20]) +{ + /* A new fingerprint for the given user has been received. */ + std::string trace= "otrwui_new_fingerprint: "; + trace += username; trace += "@"; trace += protocol; + trace += " has a new fingerprint ("; + char fingerprint_copy[45]; + otrl_privkey_hash_to_human(fingerprint_copy, fingerprint); + trace += fingerprint_copy; trace += ")"; + otrwui_tbd(trace.c_str()); // $TODO$ write me +} + +static void otrwui_write_fingerprints( + void *opdata) +{ + otrwui_trace("otrwui_write_fingerprints()"); + /* The list of known fingerprints has changed. Write them to disk. */ + if (gOTR) + { + std::string path = + gDirUtilp->getExpandedFilename( + LL_PATH_PER_SL_ACCOUNT, OTR_PUBLIC_KEYS_FILE); + otrl_privkey_write_fingerprints(gOTR->get_userstate(), path.c_str()); + } +} + +static void otrwui_gone_secure( + void *opdata, ConnContext *context) +{ + otrwui_trace("otrwui_gone_secure()"); + /* A ConnContext has entered a secure state. */ + if (! opdata) + { + otrwui_tbd("otrwui_gone_secure() called with null opdata"); + return; + } + LLUUID session_id = *((LLUUID*)opdata); + if (context && context->active_fingerprint && + context->active_fingerprint->trust && + *(context->active_fingerprint->trust)) + { + //otr_log_message_getstring_name(session_id, "otr_log_start_private"); + } + else + { + //otr_log_message_getstring_name(session_id, "otr_log_start_unverified"); + } + otr_show_status(session_id); +} + +static void otrwui_gone_insecure( + void *opdata, ConnContext *context) +{ + otrwui_trace("otrwui_gone_insecure()"); + /* A ConnContext has left a secure state. */ + if (! opdata) + { + otrwui_tbd("otrwui_gone_insecure() called with null opdata"); + return; + } + LLUUID session_id = *((LLUUID*)opdata); + otr_log_message_getstring(session_id, "otr_log_gone_insecure"); + otr_show_status(session_id); +} + +static void otrwui_still_secure( + void *opdata, ConnContext *context, int is_reply) +{ + otrwui_trace("otrwui_still_secure()"); + /* We have completed an authentication, using the D-H keys we + * already knew. is_reply indicates whether we initiated the AKE. */ + if (! opdata) + { + otrwui_tbd("otrwui_still_secure() called with null opdata"); + return; + } + LLUUID session_id = *((LLUUID*)opdata); + if (context && context->active_fingerprint && + context->active_fingerprint->trust && + *(context->active_fingerprint->trust)) + { + //otr_log_message_getstring_name(session_id, "otr_log_still_private"); + } + else + { + //otr_log_message_getstring_name(session_id, "otr_log_still_unverified"); + } + otr_show_status(session_id); +} + +static void otrwui_log_message( + void *opdata, const char *message) +{ + /* Log a message. The passed message will end in "\n". */ + otrwui_trace("otrwui_log_message()"); + llinfos << message << llendl; +} + +static int otrwui_max_message_size( + void *opdata, ConnContext *context) +{ + /* Find the maximum message size supported by this protocol. */ + return (MAX_MSG_BUF_SIZE - 24); +} + +static const char *otrwui_account_name( + void *opdata, const char *account, + const char *protocol) +{ + /* Return a newly allocated string containing a human-friendly + * representation for the given account */ + otrwui_trace("otrwui_account_name"); + std::string name; + LLUUID uuid = LLUUID(account); + if (!gCacheName->getFullName(uuid, name)) name = account; + char *result = (char *)malloc(name.length()+1); + strncpy(result, name.c_str(), name.length()+1); + return result; +} + +static void otrwui_account_name_free( + void *opdata, const char *account_name) +{ + /* Deallocate a string returned by account_name */ + otrwui_trace("otrwui_account_name_free"); + free((void *)account_name); +} + +// static +void OTR_Wrapper::stopAll() +{ + otrwui_trace("OTR_Wrapper::stopAll()"); + if (!gOTR) return; + if (gOTR->userstate) + { + for (ConnContext *context = gOTR->userstate->context_root; context; context = context->next) + { + if (context && (OTRL_MSGSTATE_ENCRYPTED == context->msgstate)) + { + LLUUID their_uuid = LLUUID(context->username); + LLUUID session_uuid = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, their_uuid); + LLFloaterIMPanel* pan = gIMMgr->findFloaterBySession(session_uuid); + if (pan) + { + llinfos << "$PLOTR$ found IM pannel, pan->doOtrStop()" << llendl; + pan->doOtrStop(); + } + else + { + char my_uuid[UUID_STR_SIZE]; + gAgent.getID().toString(&(my_uuid[0])); + llinfos << "$PLOTR$ didn't find IM panel, going lower level" + << " c->accountname:" << context->accountname // this avatar, aka me + << " c->protocol:" << context->protocol // secondlife, IRC, yahoo... + << " c->username:" << context->username // other participant + << " session_uuid:" << session_uuid + << llendl; + otrl_message_disconnect( + gOTR->get_userstate(), + gOTR->get_uistate(), + &session_uuid, + context->accountname, + context->protocol, + context->username); + } + } + } + } +} + +// static +void OTR_Wrapper::logout() +{ + otrwui_trace("OTR_Wrapper::logout()"); + if (!gOTR) return; + OTR_Wrapper::stopAll(); + delete gOTR; + gOTR = NULL; +} + +// static +void OTR_Wrapper::init() +{ + otrwui_trace("OTR_Wrapper::init()"); + if (! gOTR) + { + gOTR = new OTR_Wrapper; + if (!gOTR) + { + llwarns << "$PLOTR$ Can't new otr_wrapper." << llendl; + } + else + { + llinfos << "$PLOTR$ newed otr_wrapper." << llendl; + gOTR->uistate.policy = &otrwui_policy; + gOTR->uistate.create_privkey = &otrwui_create_privkey; + gOTR->uistate.is_logged_in = &otrwui_is_logged_in; + gOTR->uistate.inject_message = &otrwui_inject_message; + gOTR->uistate.notify = &otrwui_notify; + gOTR->uistate.display_otr_message = &otrwui_display_otr_message; + gOTR->uistate.update_context_list = &otrwui_update_context_list; + gOTR->uistate.protocol_name = &otrwui_protocol_name; + gOTR->uistate.protocol_name_free = &otrwui_protocol_name_free; + gOTR->uistate.new_fingerprint = &otrwui_new_fingerprint; + gOTR->uistate.write_fingerprints = &otrwui_write_fingerprints; + gOTR->uistate.gone_secure = &otrwui_gone_secure; + gOTR->uistate.gone_insecure = &otrwui_gone_insecure; + gOTR->uistate.still_secure = &otrwui_still_secure; + gOTR->uistate.log_message = &otrwui_log_message; + gOTR->uistate.max_message_size = &otrwui_max_message_size; + gOTR->uistate.account_name = &otrwui_account_name; + gOTR->uistate.account_name_free = &otrwui_account_name_free; + OTRL_INIT; + gOTR->userstate = otrl_userstate_create(); + std::string privpath = + gDirUtilp->getExpandedFilename( + LL_PATH_PER_SL_ACCOUNT, OTR_PRIVATE_KEYS_FILE); + otrl_privkey_read(gOTR->userstate, privpath.c_str()); + std::string pubpath = + gDirUtilp->getExpandedFilename( + LL_PATH_PER_SL_ACCOUNT, OTR_PUBLIC_KEYS_FILE); + otrl_privkey_read_fingerprints(gOTR->userstate, pubpath.c_str(), NULL, NULL); +#if 0 // this will gen a key, if the user doesn't have one, at init() time + if (gOTR && gOTR->userstate) + { + OtrlPrivKey *r = gOTR->userstate->privkey_root; + OtrlPrivKey *k = gOTR->userstate->privkey_root; + while (k && (k != r)) + { + if (0 == strcmp(gOTR->get_protocolid(), k->protocol)) + { + return; + } + } + char my_uuid[UUID_STR_SIZE]; + gAgent.getID().toString(&(my_uuid[0])); + otrl_privkey_generate(gOTR->userstate, privpath.c_str(), + my_uuid, gOTR->get_protocolid()); + } +#endif + } + } +} diff --git a/linden/indra/newview/otr_wrapper.h b/linden/indra/newview/otr_wrapper.h new file mode 100644 index 0000000..dd6d12c --- /dev/null +++ b/linden/indra/newview/otr_wrapper.h @@ -0,0 +1,58 @@ +/* otr_wrapper.h - wrap libotr for use in the second life viewer + $PLOTR$ See http://www.cypherpunks.ca/otr/ + + Copyright (C) 2009 Chris Tuchs + + This is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This 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 Lesser General Public + License along with the viewer; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef OTR_WRAPPER_H_INCLUDED +#define OTR_WRAPPER_H_INCLUDED 1 + +extern "C" { +#if WIN32 +#include // various defines needed for OTR on windows +#endif +#include // gcrypt dependancies +#include // OTR +#include // OTR +#include // OTR +#include <../libotr/libotr-3.2.0/src/message.h> // OTR +#include +} + +class OTR_Wrapper +{ +private: + OtrlUserState userstate; // Global state of OTR: known public keys etc. + OtrlMessageAppOps uistate; // UI functions collected into a structure for libotr + OTR_Wrapper(); + ~OTR_Wrapper(); + +public: + static void init(); + static void stopAll(); + static void logout(); + OtrlUserState get_userstate() { return this->userstate; } + OtrlMessageAppOps *get_uistate() { return &(this->uistate); } + const char * get_protocolid() { return "SecondLife"; } +}; + +extern OTR_Wrapper *gOTR; // the singleton OTR wrapper + +#define OTR_PRIVATE_KEYS_FILE "OTR-my-private-key.dat" +#define OTR_PUBLIC_KEYS_FILE "OTR-public-keys.dat" + +#endif // ndef OTR_WRAPPER_H_INCLUDED diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml index 4ccfe60..5ad564a 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml @@ -37,6 +37,42 @@ Text chat is not available for this call. + + + OTR is generating keys. This will happen once for each of your avatars and should take less than 45 seconds. + Your buddy + [NAME] has ended the private conversation, so your message was not sent. You should restart the private conversation, or end the private conversation. + OTR has been deactivated by preferences (edit > preferences > Emerald tab > IM tab) + Unable to encrypt your message for some reason; it has not been sent. + Unable to start private conversation. + [NAME] appears offline; OTR will not try to start a private conversation. + [NAME] appears offline; You may "End private conversation" and send your message un-encrypted. + Attempting to start a private conversation with [NAME]. + You have ended the unverified conversation with [NAME]. + You have ended the private conversation with [NAME]. + You have ended the OTR conversation with [NAME]. + [NAME] is attempting to start a private conversation. + [NAME] has ended the unverified conversation. + [NAME] has ended the private conversation. + [NAME] has ended the OTR conversation. + [NAME] is now authenticated. + Private conversation with [NAME] started. + Unverified conversation started. [NAME] has not been authenticated, you should "authenticate buddy," see http://www.cypherpunks.ca/otr/help/3.2.0/authenticate.php + Private conversation ended. + Private conversation with [NAME] resumed. + Unverified conversation resumed. [NAME] has not been authenticated, you should "authenticate buddy," see http://www.cypherpunks.ca/otr/help/3.2.0/authenticate.php + OTR: Not Private + OTR: Unverified + OTR: Private + OTR: Finished + Start private conversation + Refresh private conversation + Restart private conversation + End private conversation + Authenticate buddy + What is OTR? + What is this? + Add Friend @@ -72,6 +108,10 @@ image_unselected="icn_speaker_dark.tga" label="" left_delta="56" name="mute_btn" tool_tip="Mute voice" width="25" /> + + + + + +OTR encrypts your IMs so they can't be read by anyone other than the person you are talking to. + +Do you want to automatically secure your IMs? +
+