From b81551f235798bbe1cd0556bd29b50b92f1c9c81 Mon Sep 17 00:00:00 2001 From: Kang Lin Date: Tue, 30 Jul 2024 12:53:52 +0800 Subject: [PATCH] CConnection: Modify UserPasswdGetter and UserMsgBox interface to CConnection Problems with the original code: A process can only establish one connection. After modification, multiple connections can be supported. --- common/rfb/CConnection.cxx | 8 ++++++ common/rfb/CConnection.h | 28 ++++++++++++++++++--- common/rfb/CSecurity.h | 10 -------- common/rfb/CSecurityDH.cxx | 2 +- common/rfb/CSecurityMSLogonII.cxx | 2 +- common/rfb/CSecurityPlain.cxx | 3 +-- common/rfb/CSecurityRSAAES.cxx | 7 +++--- common/rfb/CSecurityRSAAES.h | 2 -- common/rfb/CSecurityTLS.cxx | 23 +++++++++-------- common/rfb/CSecurityTLS.h | 1 - common/rfb/CSecurityVncAuth.cxx | 2 +- common/rfb/SecurityClient.cxx | 10 -------- common/rfb/UserMsgBox.h | 41 ------------------------------- common/rfb/UserPasswdGetter.h | 36 --------------------------- tests/perf/encperf.cxx | 2 +- vncviewer/CConn.cxx | 10 ++++++++ vncviewer/CConn.h | 11 ++++++++- vncviewer/UserDialog.cxx | 16 ++++++------ vncviewer/UserDialog.h | 12 ++++----- vncviewer/vncviewer.cxx | 6 ----- 20 files changed, 85 insertions(+), 147 deletions(-) delete mode 100644 common/rfb/UserMsgBox.h delete mode 100644 common/rfb/UserPasswdGetter.h diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx index 0db5f4c8a7..500213cd4c 100644 --- a/common/rfb/CConnection.cxx +++ b/common/rfb/CConnection.cxx @@ -609,6 +609,14 @@ void CConnection::handleClipboardProvide(uint32_t flags, handleClipboardData(serverClipboard.c_str()); } +void CConnection::getUserPasswd(bool, std::string*, std::string*) +{} + +bool CConnection::showMsgBox(MsgBoxFlags, const char *, const char *) +{ + return true; +} + void CConnection::authSuccess() { } diff --git a/common/rfb/CConnection.h b/common/rfb/CConnection.h index dca98a92e9..64aaa69e90 100644 --- a/common/rfb/CConnection.h +++ b/common/rfb/CConnection.h @@ -36,8 +36,22 @@ namespace rfb { class CMsgWriter; class CSecurity; class IdentityVerifier; - - class CConnection : public CMsgHandler { + + enum class MsgBoxFlags{ + M_OK = 0, + M_OKCANCEL = 1, + M_YESNO = 4, + M_ICONERROR = 0x10, + M_ICONQUESTION = 0x20, + M_ICONWARNING = 0x30, + M_ICONINFORMATION = 0x40, + M_DEFBUTTON1 = 0, + M_DEFBUTTON2 = 0x100 + }; + + class CConnection + : public CMsgHandler + { public: CConnection(); @@ -126,7 +140,15 @@ namespace rfb { // Methods to be overridden in a derived class - + + // getUserPasswd gets the username and password. This might involve a + // dialog, getpass(), etc. The user buffer pointer can be null, in which + // case no user name will be retrieved. + virtual void getUserPasswd(bool secure, std::string* user, + std::string* password); + + virtual bool showMsgBox(MsgBoxFlags flags, const char *title, const char *text); + // authSuccess() is called when authentication has succeeded. virtual void authSuccess(); diff --git a/common/rfb/CSecurity.h b/common/rfb/CSecurity.h index 549db79407..be74a1fd47 100644 --- a/common/rfb/CSecurity.h +++ b/common/rfb/CSecurity.h @@ -38,9 +38,6 @@ #ifndef __RFB_CSECURITY_H__ #define __RFB_CSECURITY_H__ -#include -#include - namespace rfb { class CConnection; class CSecurity { @@ -51,13 +48,6 @@ namespace rfb { virtual int getType() const = 0; virtual bool isSecure() const { return false; } - /* - * Use variable directly instead of dumb get/set methods. - * It MUST be set by viewer. - */ - static UserPasswdGetter *upg; - static UserMsgBox *msg; - protected: CConnection* cc; }; diff --git a/common/rfb/CSecurityDH.cxx b/common/rfb/CSecurityDH.cxx index 6d9650bd22..c54ff215e3 100644 --- a/common/rfb/CSecurityDH.cxx +++ b/common/rfb/CSecurityDH.cxx @@ -108,7 +108,7 @@ void CSecurityDH::writeCredentials() std::string password; rdr::RandomStream rs; - (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password); + cc->getUserPasswd(isSecure(), &username, &password); std::vector bBytes(keyLength); if (!rs.hasData(keyLength)) diff --git a/common/rfb/CSecurityMSLogonII.cxx b/common/rfb/CSecurityMSLogonII.cxx index e721cdfcfa..7f8449c25b 100644 --- a/common/rfb/CSecurityMSLogonII.cxx +++ b/common/rfb/CSecurityMSLogonII.cxx @@ -97,7 +97,7 @@ void CSecurityMSLogonII::writeCredentials() std::string password; rdr::RandomStream rs; - (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password); + cc->getUserPasswd(isSecure(), &username, &password); std::vector bBytes(8); if (!rs.hasData(8)) diff --git a/common/rfb/CSecurityPlain.cxx b/common/rfb/CSecurityPlain.cxx index d9599f9ca2..1cbf62e171 100644 --- a/common/rfb/CSecurityPlain.cxx +++ b/common/rfb/CSecurityPlain.cxx @@ -23,7 +23,6 @@ #include #include -#include #include @@ -36,7 +35,7 @@ bool CSecurityPlain::processMsg() std::string username; std::string password; - (CSecurity::upg)->getUserPasswd(cc->isSecure(), &username, &password); + cc->getUserPasswd(cc->isSecure(), &username, &password); // Return the response to the server os->writeU32(username.size()); diff --git a/common/rfb/CSecurityRSAAES.cxx b/common/rfb/CSecurityRSAAES.cxx index 96d96b01ad..1eea133884 100644 --- a/common/rfb/CSecurityRSAAES.cxx +++ b/common/rfb/CSecurityRSAAES.cxx @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -215,7 +214,7 @@ void CSecurityRSAAES::verifyServer() "Fingerprint: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n" "Please verify that the information is correct and press \"Yes\". " "Otherwise press \"No\"", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.c_str())) + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, title, text.c_str())) throw AuthFailureException("server key mismatch"); } @@ -438,9 +437,9 @@ void CSecurityRSAAES::writeCredentials() std::string password; if (subtype == secTypeRA2UserPass) - (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password); + cc->getUserPasswd(isSecure(), &username, &password); else - (CSecurity::upg)->getUserPasswd(isSecure(), nullptr, &password); + cc->getUserPasswd(isSecure(), nullptr, &password); if (subtype == secTypeRA2UserPass) { if (username.size() > 255) diff --git a/common/rfb/CSecurityRSAAES.h b/common/rfb/CSecurityRSAAES.h index 29bfd57506..35b0513bb2 100644 --- a/common/rfb/CSecurityRSAAES.h +++ b/common/rfb/CSecurityRSAAES.h @@ -27,13 +27,11 @@ #include #include #include -#include #include #include #include namespace rfb { - class UserMsgBox; class CSecurityRSAAES : public CSecurity { public: CSecurityRSAAES(CConnection* cc, uint32_t secType, diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index 8d8b58fdaa..840aef243f 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -441,7 +440,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Unknown certificate issuer", text.c_str())) throw AuthFailureException("Unknown certificate issuer"); @@ -461,8 +460,8 @@ void CSecurityTLS::checkSession() "\n" "Do you want to make an exception for this " "server?", info.data); - - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Certificate is not yet valid", text.c_str())) throw AuthFailureException("Certificate is not yet valid"); @@ -481,7 +480,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Expired certificate", text.c_str())) throw AuthFailureException("Expired certificate"); @@ -500,7 +499,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Insecure certificate algorithm", text.c_str())) throw AuthFailureException("Insecure certificate algorithm"); @@ -525,7 +524,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", client->getServerName(), info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Certificate hostname mismatch", text.c_str())) throw AuthFailureException("Certificate hostname mismatch"); @@ -551,7 +550,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Unexpected server certificate", text.c_str())) throw AuthFailureException("Unexpected server certificate"); @@ -574,7 +573,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Unexpected server certificate", text.c_str())) throw AuthFailureException("Unexpected server certificate"); @@ -595,7 +594,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Unexpected server certificate", text.c_str())) throw AuthFailureException("Unexpected server certificate"); @@ -616,7 +615,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Unexpected server certificate", text.c_str())) throw AuthFailureException("Unexpected server certificate"); @@ -643,7 +642,7 @@ void CSecurityTLS::checkSession() "Do you want to make an exception for this " "server?", client->getServerName(), info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, + if (!cc->showMsgBox(MsgBoxFlags::M_YESNO, "Unexpected server certificate", text.c_str())) throw AuthFailureException("Unexpected server certificate"); diff --git a/common/rfb/CSecurityTLS.h b/common/rfb/CSecurityTLS.h index 8688b742c8..848ef9bb8c 100644 --- a/common/rfb/CSecurityTLS.h +++ b/common/rfb/CSecurityTLS.h @@ -28,7 +28,6 @@ #include #include -#include #include #include #include diff --git a/common/rfb/CSecurityVncAuth.cxx b/common/rfb/CSecurityVncAuth.cxx index e5f842baac..2fd83fe936 100644 --- a/common/rfb/CSecurityVncAuth.cxx +++ b/common/rfb/CSecurityVncAuth.cxx @@ -54,7 +54,7 @@ bool CSecurityVncAuth::processMsg() uint8_t challenge[vncAuthChallengeSize]; is->readBytes(challenge, vncAuthChallengeSize); std::string passwd; - (CSecurity::upg)->getUserPasswd(cc->isSecure(), nullptr, &passwd); + cc->getUserPasswd(cc->isSecure(), nullptr, &passwd); // Calculate the correct response uint8_t key[8]; diff --git a/common/rfb/SecurityClient.cxx b/common/rfb/SecurityClient.cxx index 63e0cadc0f..72c1e0fbfd 100644 --- a/common/rfb/SecurityClient.cxx +++ b/common/rfb/SecurityClient.cxx @@ -41,11 +41,6 @@ using namespace rdr; using namespace rfb; -UserPasswdGetter *CSecurity::upg = nullptr; -#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE) -UserMsgBox *CSecurity::msg = nullptr; -#endif - StringParameter SecurityClient::secTypes ("SecurityTypes", "Specify which security scheme to use (None, VncAuth, Plain" @@ -67,11 +62,6 @@ ConfViewer); CSecurity* SecurityClient::GetCSecurity(CConnection* cc, uint32_t secType) { - assert (CSecurity::upg != nullptr); /* (upg == nullptr) means bug in the viewer */ -#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE) - assert (CSecurity::msg != nullptr); -#endif - if (!IsSupported(secType)) goto bail; diff --git a/common/rfb/UserMsgBox.h b/common/rfb/UserMsgBox.h deleted file mode 100644 index 392950d127..0000000000 --- a/common/rfb/UserMsgBox.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright (C) 2010 TigerVNC Team - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -#ifndef __RFB_USERMSGBOX_H__ -#define __RFB_USERMSGBOX_H__ - -namespace rfb { - class UserMsgBox { - public: - enum MsgBoxFlags{ - M_OK = 0, - M_OKCANCEL = 1, - M_YESNO = 4, - M_ICONERROR = 0x10, - M_ICONQUESTION = 0x20, - M_ICONWARNING = 0x30, - M_ICONINFORMATION = 0x40, - M_DEFBUTTON1 = 0, - M_DEFBUTTON2 = 0x100 - }; - /* TODO Implement as function with variable arguments */ - virtual bool showMsgBox(int flags,const char* title, const char* text)=0; - }; -} - -#endif diff --git a/common/rfb/UserPasswdGetter.h b/common/rfb/UserPasswdGetter.h deleted file mode 100644 index db7df39654..0000000000 --- a/common/rfb/UserPasswdGetter.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -#ifndef __RFB_USERPASSWDGETTER_H__ -#define __RFB_USERPASSWDGETTER_H__ - -#include - -namespace rfb { - class UserPasswdGetter { - public: - // getUserPasswd gets the username and password. This might involve a - // dialog, getpass(), etc. The user buffer pointer can be null, in which - // case no user name will be retrieved. - virtual void getUserPasswd(bool secure, std::string* user, - std::string* password)=0; - - virtual ~UserPasswdGetter() {} - }; -} - -#endif diff --git a/tests/perf/encperf.cxx b/tests/perf/encperf.cxx index 25dca4908c..06cc496386 100644 --- a/tests/perf/encperf.cxx +++ b/tests/perf/encperf.cxx @@ -117,7 +117,7 @@ class CConn : public rfb::CConnection { rdr::FileInStream *in; DummyOutStream *out; rfb::SimpleUpdateTracker updates; - class SConn *sc; + class SConn *sc; }; class Manager : public rfb::EncodeManager { diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx index 31f5b74dd8..fa2bf12ef9 100644 --- a/vncviewer/CConn.cxx +++ b/vncviewer/CConn.cxx @@ -597,3 +597,13 @@ void CConn::handleUpdateTimeout(void *data) Fl::repeat_timeout(1.0, handleUpdateTimeout, data); } + +bool CConn::showMsgBox(MsgBoxFlags flags, const char *title, const char *text) +{ + return dlg.showMsgBox(flags, title, text); +} + +void CConn::getUserPasswd(bool secure, std::string *user, std::string *password) +{ + dlg.getUserPasswd(secure, user, password); +} \ No newline at end of file diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h index fcaf49f6e9..498f5d740b 100644 --- a/vncviewer/CConn.h +++ b/vncviewer/CConn.h @@ -24,6 +24,7 @@ #include #include +#include "UserDialog.h" namespace network { class Socket; } @@ -43,7 +44,13 @@ class CConn : public rfb::CConnection // Callback when socket is ready (or broken) static void socketEvent(FL_SOCKET fd, void *data); - + + // UserMsgBox interface + virtual bool showMsgBox(rfb::MsgBoxFlags flags, const char *title, const char *text) override; + + // UserPasswdGetter interface + virtual void getUserPasswd(bool secure, std::string *user, std::string *password) override; + // CConnection callback methods void initDone() override; @@ -105,6 +112,8 @@ class CConn : public rfb::CConnection struct timeval updateStartTime; size_t updateStartPos; unsigned long long bpsEstimate; + + UserDialog dlg; }; #endif diff --git a/vncviewer/UserDialog.cxx b/vncviewer/UserDialog.cxx index 958b9d66d2..ae34640a3b 100644 --- a/vncviewer/UserDialog.cxx +++ b/vncviewer/UserDialog.cxx @@ -207,7 +207,7 @@ void UserDialog::getUserPasswd(bool secure_, std::string* user, throw rfb::Exception(_("Authentication cancelled")); } -bool UserDialog::showMsgBox(int flags, const char* title, const char* text) +bool UserDialog::showMsgBox(MsgBoxFlags flags, const char* title, const char* text) { char buffer[1024]; @@ -218,16 +218,16 @@ bool UserDialog::showMsgBox(int flags, const char* title, const char* text) // bits for now. fl_message_title(title); - - switch (flags & 0xf) { - case M_OKCANCEL: + + switch ((MsgBoxFlags)((int)flags & 0xf)) { + case MsgBoxFlags::M_OKCANCEL: return fl_choice("%s", nullptr, fl_ok, fl_cancel, buffer) == 1; - case M_YESNO: + case MsgBoxFlags::M_YESNO: return fl_choice("%s", nullptr, fl_yes, fl_no, buffer) == 1; - case M_OK: + case MsgBoxFlags::M_OK: default: - if (((flags & 0xf0) == M_ICONERROR) || - ((flags & 0xf0) == M_ICONWARNING)) + if ((((int)flags & 0xf0) == (int)MsgBoxFlags::M_ICONERROR) || + (((int)flags & 0xf0) == (int)MsgBoxFlags::M_ICONWARNING)) fl_alert("%s", buffer); else fl_message("%s", buffer); diff --git a/vncviewer/UserDialog.h b/vncviewer/UserDialog.h index db4e7c45a5..27c6a91bd2 100644 --- a/vncviewer/UserDialog.h +++ b/vncviewer/UserDialog.h @@ -19,11 +19,9 @@ #ifndef __USERDIALOG_H__ #define __USERDIALOG_H__ -#include -#include +#include -class UserDialog : public rfb::UserPasswdGetter, - public rfb::UserMsgBox +class UserDialog { public: UserDialog(); @@ -32,11 +30,11 @@ class UserDialog : public rfb::UserPasswdGetter, // UserPasswdGetter callbacks void getUserPasswd(bool secure, std::string* user, - std::string* password) override; + std::string* password); // UserMsgBox callbacks - - bool showMsgBox(int flags, const char* title, const char* text) override; + + bool showMsgBox(rfb::MsgBoxFlags flags, const char* title, const char* text); }; #endif diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx index 6ddff94703..26782815fc 100644 --- a/vncviewer/vncviewer.cxx +++ b/vncviewer/vncviewer.cxx @@ -607,7 +607,6 @@ static int mktunnel() int main(int argc, char** argv) { const char *localedir; - UserDialog dlg; argv0 = argv[0]; @@ -742,11 +741,6 @@ int main(int argc, char** argv) vlog.error(_("Could not create VNC state directory: %s"), strerror(errno)); } - CSecurity::upg = &dlg; -#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE) - CSecurity::msg = &dlg; -#endif - Socket *sock = nullptr; #ifndef WIN32