Problems with the original code: A process can only establish one connection.
After modification, multiple connections can be supported.
class CMsgWriter;
class CSecurity;
+ 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
+ };
+
class CConnection : public CMsgHandler {
public:
void serverCutText(const char* str) override;
void handleClipboardCaps(uint32_t flags,
- const uint32_t* lengths) override;
+ const uint32_t* lengths) override;
void handleClipboardRequest(uint32_t flags) override;
void handleClipboardPeek() override;
void handleClipboardNotify(uint32_t flags) override;
// 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) = 0;
+
+ // showMsgBox() displays a message box with the specified style and
+ // contents. The return value is true if the user clicked OK/Yes.
+ virtual bool showMsgBox(MsgBoxFlags flags, const char *title,
+ const char *text) = 0;
+
// authSuccess() is called when authentication has succeeded.
virtual void authSuccess();
#ifndef __RFB_CSECURITY_H__
#define __RFB_CSECURITY_H__
-#include <rfb/UserPasswdGetter.h>
-#include <rfb/UserMsgBox.h>
-
namespace rfb {
class CConnection;
class CSecurity {
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;
};
std::string password;
rdr::RandomStream rs;
- (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);
+ cc->getUserPasswd(isSecure(), &username, &password);
std::vector<uint8_t> bBytes(keyLength);
if (!rs.hasData(keyLength))
std::string password;
rdr::RandomStream rs;
- (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);
+ cc->getUserPasswd(isSecure(), &username, &password);
std::vector<uint8_t> bBytes(8);
if (!rs.hasData(8))
#include <rfb/CConnection.h>
#include <rfb/CSecurityPlain.h>
-#include <rfb/UserPasswdGetter.h>
#include <rdr/OutStream.h>
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());
#include <rfb/CConnection.h>
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
-#include <rfb/UserMsgBox.h>
#include <rfb/util.h>
#include <rdr/AESInStream.h>
#include <rdr/AESOutStream.h>
"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 Exception("server key mismatch");
}
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)
#include <nettle/rsa.h>
#include <rfb/CSecurity.h>
#include <rfb/Security.h>
-#include <rfb/UserMsgBox.h>
#include <rdr/InStream.h>
#include <rdr/OutStream.h>
#include <rdr/RandomStream.h>
namespace rfb {
- class UserMsgBox;
class CSecurityRSAAES : public CSecurity {
public:
CSecurityRSAAES(CConnection* cc, uint32_t secType,
#include <rfb/CConnection.h>
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
-#include <rfb/UserMsgBox.h>
#include <rfb/util.h>
#include <rdr/TLSException.h>
#include <rdr/TLSInStream.h>
"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 AuthCancelledException();
"\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 AuthCancelledException();
"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 AuthCancelledException();
"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 AuthCancelledException();
"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 AuthCancelledException();
"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 AuthCancelledException();
"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 AuthCancelledException();
"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 AuthCancelledException();
"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 AuthCancelledException();
"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 AuthCancelledException();
#include <rfb/CSecurity.h>
#include <rfb/Security.h>
-#include <rfb/UserMsgBox.h>
#include <rdr/InStream.h>
#include <rdr/OutStream.h>
#include <gnutls/gnutls.h>
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];
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"
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;
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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 <string>
-
-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
void setColourMapEntries(int, int, uint16_t*) override;
void bell() override;
void serverCutText(const char*) override;
+ virtual void getUserPasswd(bool secure, std::string *user, std::string *password) override;
+ virtual bool showMsgBox(rfb::MsgBoxFlags flags, const char *title, const char *text) override;
public:
double cpuTime;
protected:
rdr::FileInStream *in;
DummyOutStream *out;
+
};
DummyOutStream::DummyOutStream()
{
}
+void CConn::getUserPasswd(bool, std::string *, std::string *)
+{
+}
+
+bool CConn::showMsgBox(rfb::MsgBoxFlags, const char *, const char *)
+{
+ return true;
+}
+
struct stats
{
double decodeTime;
void setColourMapEntries(int, int, uint16_t*) override;
void bell() override;
void serverCutText(const char*) override;
+ virtual void getUserPasswd(bool secure, std::string *user, std::string *password) override;
+ virtual bool showMsgBox(rfb::MsgBoxFlags flags, const char *title, const char *text) override;
public:
double decodeTime;
{
}
+void CConn::getUserPasswd(bool, std::string *, std::string *)
+{
+}
+
+bool CConn::showMsgBox(rfb::MsgBoxFlags, const char *, const char *)
+{
+ return true;
+}
+
Manager::Manager(class rfb::SConnection *conn_) :
EncodeManager(conn_)
{
vlog.info("%s", e.str());
disconnect();
} catch (rfb::AuthFailureException& e) {
- reset_password_data();
+ cc->resetPassword();
vlog.error(_("Authentication failed: %s"), e.str());
abort_connection(_("Failed to authenticate with the server. Reason "
"given by the server:\n\n%s"), e.str());
recursing = false;
}
+void CConn::resetPassword()
+{
+ dlg.resetPassword();
+}
+
////////////////////// CConnection callback methods //////////////////////
+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);
+}
+
// initDone() is called when the serverInit message has been received. At
// this point we create the desktop window and display it. We also tell the
// server the pixel format and encodings to use and request the first update.
#include <rfb/CConnection.h>
#include <rdr/FdInStream.h>
+#include "UserDialog.h"
namespace network { class Socket; }
// Callback when socket is ready (or broken)
static void socketEvent(FL_SOCKET fd, void *data);
+ // Forget any saved password
+ void resetPassword();
+
// CConnection callback methods
+
+ bool showMsgBox(rfb::MsgBoxFlags flags, const char *title,
+ const char *text) override;
+ void getUserPasswd(bool secure, std::string *user,
+ std::string *password) override;
+
void initDone() override;
void setDesktopSize(int w, int h) override;
struct timeval updateStartTime;
size_t updateStartPos;
unsigned long long bpsEstimate;
+
+ UserDialog dlg;
};
#endif
throw rfb::AuthCancelledException();
}
-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];
#ifndef __USERDIALOG_H__
#define __USERDIALOG_H__
-#include <rfb/UserPasswdGetter.h>
-#include <rfb/UserMsgBox.h>
+#include <rfb/CConnection.h>
-class UserDialog : public rfb::UserPasswdGetter,
- public rfb::UserMsgBox
+class UserDialog
{
public:
UserDialog();
// 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);
void resetPassword();
- private:
+private:
std::string savedUsername;
std::string savedPassword;
};
static char *exitError = nullptr;
static bool fatalError = false;
-static UserDialog dlg;
-
static const char *about_text()
{
static char buffer[1024];
return exitMainloop;
}
-void reset_password_data()
-{
- dlg.resetPassword();
-}
-
void about_vncviewer()
{
fl_message_title(_("About TigerVNC Viewer"));
create_base_dirs();
- CSecurity::upg = &dlg;
-#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE)
- CSecurity::msg = &dlg;
-#endif
-
Socket *sock = nullptr;
#ifndef WIN32
void disconnect();
bool should_disconnect();
-void reset_password_data();
void about_vncviewer();