You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1114 lines
42 KiB
1114 lines
42 KiB
6 months ago
|
From 2be25eac8a96b3910701052d768ee465def36d56 Mon Sep 17 00:00:00 2001
|
||
|
From: Jan Grulich <jgrulich@redhat.com>
|
||
|
Date: Tue, 28 May 2024 13:07:58 +0200
|
||
|
Subject: vncconfig: add option to force view only remote client connections
|
||
|
|
||
|
|
||
|
diff --git a/common/network/Socket.h b/common/network/Socket.h
|
||
|
index 901bab1..576fe15 100644
|
||
|
--- a/common/network/Socket.h
|
||
|
+++ b/common/network/Socket.h
|
||
|
@@ -111,41 +111,6 @@ namespace network {
|
||
|
SocketException(const char* text, int err_) : rdr::SystemException(text, err_) {}
|
||
|
};
|
||
|
|
||
|
- class SocketServer {
|
||
|
- public:
|
||
|
- virtual ~SocketServer() {}
|
||
|
-
|
||
|
- // addSocket() tells the server to serve the Socket. The caller
|
||
|
- // retains ownership of the Socket - the only way for the server
|
||
|
- // to discard a Socket is by calling shutdown() on it.
|
||
|
- // outgoing is set to true if the socket was created by connecting out
|
||
|
- // to another host, or false if the socket was created by accept()ing
|
||
|
- // an incoming connection.
|
||
|
- virtual void addSocket(network::Socket* sock, bool outgoing=false) = 0;
|
||
|
-
|
||
|
- // removeSocket() tells the server to stop serving the Socket. The
|
||
|
- // caller retains ownership of the Socket - the server must NOT
|
||
|
- // delete the Socket! This call is used mainly to cause per-Socket
|
||
|
- // resources to be freed.
|
||
|
- virtual void removeSocket(network::Socket* sock) = 0;
|
||
|
-
|
||
|
- // getSockets() gets a list of sockets. This can be used to generate an
|
||
|
- // fd_set for calling select().
|
||
|
- virtual void getSockets(std::list<network::Socket*>* sockets) = 0;
|
||
|
-
|
||
|
- // processSocketReadEvent() tells the server there is a Socket read event.
|
||
|
- // The implementation can indicate that the Socket is no longer active
|
||
|
- // by calling shutdown() on it. The caller will then call removeSocket()
|
||
|
- // soon after processSocketEvent returns, to allow any pre-Socket
|
||
|
- // resources to be tidied up.
|
||
|
- virtual void processSocketReadEvent(network::Socket* sock) = 0;
|
||
|
-
|
||
|
- // processSocketReadEvent() tells the server there is a Socket write event.
|
||
|
- // This is only necessary if the Socket has been put in non-blocking
|
||
|
- // mode and needs this callback to flush the buffer.
|
||
|
- virtual void processSocketWriteEvent(network::Socket* sock) = 0;
|
||
|
- };
|
||
|
-
|
||
|
}
|
||
|
|
||
|
#endif // __NETWORK_SOCKET_H__
|
||
|
diff --git a/common/rfb/AccessRights.cxx b/common/rfb/AccessRights.cxx
|
||
|
new file mode 100644
|
||
|
index 0000000..65e6ce2
|
||
|
--- /dev/null
|
||
|
+++ b/common/rfb/AccessRights.cxx
|
||
|
@@ -0,0 +1,36 @@
|
||
|
+/* Copyright 2024 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.
|
||
|
+ */
|
||
|
+
|
||
|
+#include "AccessRights.h"
|
||
|
+
|
||
|
+namespace rfb
|
||
|
+{
|
||
|
+
|
||
|
+ // AccessRights values
|
||
|
+ const AccessRights AccessNone = 0x0000;
|
||
|
+ const AccessRights AccessView = 0x0001;
|
||
|
+ const AccessRights AccessKeyEvents = 0x0002;
|
||
|
+ const AccessRights AccessPtrEvents = 0x0004;
|
||
|
+ const AccessRights AccessCutText = 0x0008;
|
||
|
+ const AccessRights AccessSetDesktopSize = 0x0010;
|
||
|
+ const AccessRights AccessNonShared = 0x0020;
|
||
|
+ const AccessRights AccessDefault = 0x03ff;
|
||
|
+ const AccessRights AccessNoQuery = 0x0400;
|
||
|
+ const AccessRights AccessFull = 0xffff;
|
||
|
+
|
||
|
+} /* namespace rfb */
|
||
|
diff --git a/common/rfb/AccessRights.h b/common/rfb/AccessRights.h
|
||
|
new file mode 100644
|
||
|
index 0000000..adf4393
|
||
|
--- /dev/null
|
||
|
+++ b/common/rfb/AccessRights.h
|
||
|
@@ -0,0 +1,41 @@
|
||
|
+/* Copyright 2024 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 COMMON_RFB_ACCESSRIGHTS_H_
|
||
|
+#define COMMON_RFB_ACCESSRIGHTS_H_
|
||
|
+
|
||
|
+#include <stdint.h>
|
||
|
+
|
||
|
+namespace rfb
|
||
|
+{
|
||
|
+
|
||
|
+ typedef uint16_t AccessRights;
|
||
|
+ extern const AccessRights AccessNone; // No rights at all
|
||
|
+ extern const AccessRights AccessView; // View display contents
|
||
|
+ extern const AccessRights AccessKeyEvents; // Send key events
|
||
|
+ extern const AccessRights AccessPtrEvents; // Send pointer events
|
||
|
+ extern const AccessRights AccessCutText; // Send/receive clipboard events
|
||
|
+ extern const AccessRights AccessSetDesktopSize; // Change desktop size
|
||
|
+ extern const AccessRights AccessNonShared; // Exclusive access to the server
|
||
|
+ extern const AccessRights AccessDefault; // The default rights, INCLUDING FUTURE ONES
|
||
|
+ extern const AccessRights AccessNoQuery; // Connect without local user accepting
|
||
|
+ extern const AccessRights AccessFull; // All of the available AND FUTURE rights
|
||
|
+
|
||
|
+} /* namespace rfb */
|
||
|
+
|
||
|
+#endif /* COMMON_RFB_ACCESSRIGHTS_H_ */
|
||
|
diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
|
||
|
index ea1954e..1603aa5 100644
|
||
|
--- a/common/rfb/CMakeLists.txt
|
||
|
+++ b/common/rfb/CMakeLists.txt
|
||
|
@@ -3,6 +3,7 @@ include_directories(${JPEG_INCLUDE_DIR})
|
||
|
include_directories(${PIXMAN_INCLUDE_DIRS})
|
||
|
|
||
|
add_library(rfb STATIC
|
||
|
+ AccessRights.cxx
|
||
|
Blacklist.cxx
|
||
|
Congestion.cxx
|
||
|
CConnection.cxx
|
||
|
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
|
||
|
index 3587484..eaa1c6f 100644
|
||
|
--- a/common/rfb/SConnection.cxx
|
||
|
+++ b/common/rfb/SConnection.cxx
|
||
|
@@ -42,24 +42,12 @@ using namespace rfb;
|
||
|
|
||
|
static LogWriter vlog("SConnection");
|
||
|
|
||
|
-// AccessRights values
|
||
|
-const SConnection::AccessRights SConnection::AccessView = 0x0001;
|
||
|
-const SConnection::AccessRights SConnection::AccessKeyEvents = 0x0002;
|
||
|
-const SConnection::AccessRights SConnection::AccessPtrEvents = 0x0004;
|
||
|
-const SConnection::AccessRights SConnection::AccessCutText = 0x0008;
|
||
|
-const SConnection::AccessRights SConnection::AccessSetDesktopSize = 0x0010;
|
||
|
-const SConnection::AccessRights SConnection::AccessNonShared = 0x0020;
|
||
|
-const SConnection::AccessRights SConnection::AccessDefault = 0x03ff;
|
||
|
-const SConnection::AccessRights SConnection::AccessNoQuery = 0x0400;
|
||
|
-const SConnection::AccessRights SConnection::AccessFull = 0xffff;
|
||
|
-
|
||
|
-
|
||
|
-SConnection::SConnection()
|
||
|
+SConnection::SConnection(AccessRights accessRights)
|
||
|
: readyForSetColourMapEntries(false),
|
||
|
is(0), os(0), reader_(0), writer_(0), ssecurity(0),
|
||
|
authFailureTimer(this, &SConnection::handleAuthFailureTimeout),
|
||
|
state_(RFBSTATE_UNINITIALISED), preferredEncoding(encodingRaw),
|
||
|
- accessRights(0x0000), clientClipboard(NULL), hasLocalClipboard(false),
|
||
|
+ accessRights(accessRights), clientClipboard(NULL), hasLocalClipboard(false),
|
||
|
unsolicitedClipboardAttempt(false)
|
||
|
{
|
||
|
defaultMajorVersion = 3;
|
||
|
@@ -252,7 +240,7 @@ bool SConnection::processSecurityMsg()
|
||
|
}
|
||
|
|
||
|
state_ = RFBSTATE_QUERYING;
|
||
|
- setAccessRights(ssecurity->getAccessRights());
|
||
|
+ setAccessRights(accessRights & ssecurity->getAccessRights());
|
||
|
queryConnection(ssecurity->getUserName());
|
||
|
|
||
|
// If the connection got approved right away then we can continue
|
||
|
diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h
|
||
|
index 38969c2..e8d9695 100644
|
||
|
--- a/common/rfb/SConnection.h
|
||
|
+++ b/common/rfb/SConnection.h
|
||
|
@@ -27,6 +27,7 @@
|
||
|
#include <rdr/InStream.h>
|
||
|
#include <rdr/OutStream.h>
|
||
|
|
||
|
+#include <rfb/AccessRights.h>
|
||
|
#include <rfb/SMsgHandler.h>
|
||
|
#include <rfb/SecurityServer.h>
|
||
|
#include <rfb/Timer.h>
|
||
|
@@ -40,7 +41,7 @@ namespace rfb {
|
||
|
class SConnection : public SMsgHandler {
|
||
|
public:
|
||
|
|
||
|
- SConnection();
|
||
|
+ SConnection(AccessRights accessRights);
|
||
|
virtual ~SConnection();
|
||
|
|
||
|
// Methods to initialise the connection
|
||
|
@@ -173,20 +174,12 @@ namespace rfb {
|
||
|
// clipboard via handleClipboardRequest().
|
||
|
virtual void sendClipboardData(const char* data);
|
||
|
|
||
|
+ // getAccessRights() returns the access rights of a SConnection to the server.
|
||
|
+ AccessRights getAccessRights() { return accessRights; }
|
||
|
+
|
||
|
// setAccessRights() allows a security package to limit the access rights
|
||
|
// of a SConnection to the server. How the access rights are treated
|
||
|
// is up to the derived class.
|
||
|
-
|
||
|
- typedef rdr::U16 AccessRights;
|
||
|
- static const AccessRights AccessView; // View display contents
|
||
|
- static const AccessRights AccessKeyEvents; // Send key events
|
||
|
- static const AccessRights AccessPtrEvents; // Send pointer events
|
||
|
- static const AccessRights AccessCutText; // Send/receive clipboard events
|
||
|
- static const AccessRights AccessSetDesktopSize; // Change desktop size
|
||
|
- static const AccessRights AccessNonShared; // Exclusive access to the server
|
||
|
- static const AccessRights AccessDefault; // The default rights, INCLUDING FUTURE ONES
|
||
|
- static const AccessRights AccessNoQuery; // Connect without local user accepting
|
||
|
- static const AccessRights AccessFull; // All of the available AND FUTURE rights
|
||
|
virtual void setAccessRights(AccessRights ar);
|
||
|
virtual bool accessCheck(AccessRights ar) const;
|
||
|
|
||
|
diff --git a/common/rfb/SSecurity.h b/common/rfb/SSecurity.h
|
||
|
index cef2027..6ebdbdf 100644
|
||
|
--- a/common/rfb/SSecurity.h
|
||
|
+++ b/common/rfb/SSecurity.h
|
||
|
@@ -63,7 +63,7 @@ namespace rfb {
|
||
|
// for this security type.
|
||
|
virtual const char* getUserName() const = 0;
|
||
|
|
||
|
- virtual SConnection::AccessRights getAccessRights() const { return SConnection::AccessDefault; }
|
||
|
+ virtual AccessRights getAccessRights() const { return AccessDefault; }
|
||
|
|
||
|
protected:
|
||
|
SConnection* sc;
|
||
|
diff --git a/common/rfb/SSecurityRSAAES.cxx b/common/rfb/SSecurityRSAAES.cxx
|
||
|
index 15d2e97..9d6da87 100644
|
||
|
--- a/common/rfb/SSecurityRSAAES.cxx
|
||
|
+++ b/common/rfb/SSecurityRSAAES.cxx
|
||
|
@@ -74,7 +74,7 @@ SSecurityRSAAES::SSecurityRSAAES(SConnection* sc, rdr::U32 _secType,
|
||
|
keySize(_keySize), isAllEncrypted(_isAllEncrypted), secType(_secType),
|
||
|
serverKey(), clientKey(),
|
||
|
serverKeyN(NULL), serverKeyE(NULL), clientKeyN(NULL), clientKeyE(NULL),
|
||
|
- accessRights(SConnection::AccessDefault),
|
||
|
+ accessRights(AccessDefault),
|
||
|
rais(NULL), raos(NULL), rawis(NULL), rawos(NULL)
|
||
|
{
|
||
|
assert(keySize == 128 || keySize == 256);
|
||
|
@@ -580,12 +580,12 @@ void SSecurityRSAAES::verifyPass()
|
||
|
throw AuthFailureException("No password configured for VNC Auth");
|
||
|
|
||
|
if (strcmp(password.buf, passwd.buf) == 0) {
|
||
|
- accessRights = SConnection::AccessDefault;
|
||
|
+ accessRights = AccessDefault;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (passwdReadOnly.buf && strcmp(password.buf, passwdReadOnly.buf) == 0) {
|
||
|
- accessRights = SConnection::AccessView;
|
||
|
+ accessRights = AccessView;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
diff --git a/common/rfb/SSecurityRSAAES.h b/common/rfb/SSecurityRSAAES.h
|
||
|
index 17e0d40..17e1405 100644
|
||
|
--- a/common/rfb/SSecurityRSAAES.h
|
||
|
+++ b/common/rfb/SSecurityRSAAES.h
|
||
|
@@ -39,7 +39,7 @@ namespace rfb {
|
||
|
virtual bool processMsg();
|
||
|
virtual const char* getUserName() const;
|
||
|
virtual int getType() const { return secType; }
|
||
|
- virtual SConnection::AccessRights getAccessRights() const
|
||
|
+ virtual AccessRights getAccessRights() const
|
||
|
{
|
||
|
return accessRights;
|
||
|
}
|
||
|
@@ -82,7 +82,7 @@ namespace rfb {
|
||
|
|
||
|
CharArray username;
|
||
|
CharArray password;
|
||
|
- SConnection::AccessRights accessRights;
|
||
|
+ AccessRights accessRights;
|
||
|
|
||
|
rdr::InStream* rais;
|
||
|
rdr::OutStream* raos;
|
||
|
diff --git a/common/rfb/SSecurityStack.cxx b/common/rfb/SSecurityStack.cxx
|
||
|
index 8b1c2a4..9c0321d 100644
|
||
|
--- a/common/rfb/SSecurityStack.cxx
|
||
|
+++ b/common/rfb/SSecurityStack.cxx
|
||
|
@@ -71,14 +71,14 @@ const char* SSecurityStack::getUserName() const
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
-SConnection::AccessRights SSecurityStack::getAccessRights() const
|
||
|
+AccessRights SSecurityStack::getAccessRights() const
|
||
|
{
|
||
|
- SConnection::AccessRights accessRights;
|
||
|
+ AccessRights accessRights;
|
||
|
|
||
|
if (!state0 && !state1)
|
||
|
return SSecurity::getAccessRights();
|
||
|
|
||
|
- accessRights = SConnection::AccessFull;
|
||
|
+ accessRights = AccessFull;
|
||
|
|
||
|
if (state0)
|
||
|
accessRights &= state0->getAccessRights();
|
||
|
diff --git a/common/rfb/SSecurityStack.h b/common/rfb/SSecurityStack.h
|
||
|
index 8b412bd..cf7b10d 100644
|
||
|
--- a/common/rfb/SSecurityStack.h
|
||
|
+++ b/common/rfb/SSecurityStack.h
|
||
|
@@ -32,7 +32,7 @@ namespace rfb {
|
||
|
virtual bool processMsg();
|
||
|
virtual int getType() const { return type; };
|
||
|
virtual const char* getUserName() const;
|
||
|
- virtual SConnection::AccessRights getAccessRights() const;
|
||
|
+ virtual AccessRights getAccessRights() const;
|
||
|
protected:
|
||
|
short state;
|
||
|
SSecurity* state0;
|
||
|
diff --git a/common/rfb/SSecurityVeNCrypt.cxx b/common/rfb/SSecurityVeNCrypt.cxx
|
||
|
index 70d50d2..45d63b4 100644
|
||
|
--- a/common/rfb/SSecurityVeNCrypt.cxx
|
||
|
+++ b/common/rfb/SSecurityVeNCrypt.cxx
|
||
|
@@ -180,7 +180,7 @@ const char* SSecurityVeNCrypt::getUserName() const
|
||
|
return ssecurity->getUserName();
|
||
|
}
|
||
|
|
||
|
-SConnection::AccessRights SSecurityVeNCrypt::getAccessRights() const
|
||
|
+AccessRights SSecurityVeNCrypt::getAccessRights() const
|
||
|
{
|
||
|
if (ssecurity == NULL)
|
||
|
return SSecurity::getAccessRights();
|
||
|
diff --git a/common/rfb/SSecurityVeNCrypt.h b/common/rfb/SSecurityVeNCrypt.h
|
||
|
index afbf724..d1fa831 100644
|
||
|
--- a/common/rfb/SSecurityVeNCrypt.h
|
||
|
+++ b/common/rfb/SSecurityVeNCrypt.h
|
||
|
@@ -37,7 +37,7 @@ namespace rfb {
|
||
|
virtual bool processMsg();
|
||
|
virtual int getType() const { return chosenType; }
|
||
|
virtual const char* getUserName() const;
|
||
|
- virtual SConnection::AccessRights getAccessRights() const;
|
||
|
+ virtual AccessRights getAccessRights() const;
|
||
|
|
||
|
protected:
|
||
|
SSecurity *ssecurity;
|
||
|
diff --git a/common/rfb/SSecurityVncAuth.cxx b/common/rfb/SSecurityVncAuth.cxx
|
||
|
index a19404d..fcce4b2 100644
|
||
|
--- a/common/rfb/SSecurityVncAuth.cxx
|
||
|
+++ b/common/rfb/SSecurityVncAuth.cxx
|
||
|
@@ -54,7 +54,7 @@ VncAuthPasswdParameter SSecurityVncAuth::vncAuthPasswd
|
||
|
|
||
|
SSecurityVncAuth::SSecurityVncAuth(SConnection* sc)
|
||
|
: SSecurity(sc), sentChallenge(false),
|
||
|
- pg(&vncAuthPasswd), accessRights(0)
|
||
|
+ pg(&vncAuthPasswd), accessRights(AccessNone)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
@@ -103,12 +103,12 @@ bool SSecurityVncAuth::processMsg()
|
||
|
throw AuthFailureException("No password configured for VNC Auth");
|
||
|
|
||
|
if (verifyResponse(passwd)) {
|
||
|
- accessRights = SConnection::AccessDefault;
|
||
|
+ accessRights = AccessDefault;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (passwdReadOnly.buf && verifyResponse(passwdReadOnly)) {
|
||
|
- accessRights = SConnection::AccessView;
|
||
|
+ accessRights = AccessView;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
diff --git a/common/rfb/SSecurityVncAuth.h b/common/rfb/SSecurityVncAuth.h
|
||
|
index 94d5aaf..b7448f4 100644
|
||
|
--- a/common/rfb/SSecurityVncAuth.h
|
||
|
+++ b/common/rfb/SSecurityVncAuth.h
|
||
|
@@ -55,7 +55,7 @@ namespace rfb {
|
||
|
virtual bool processMsg();
|
||
|
virtual int getType() const {return secTypeVncAuth;}
|
||
|
virtual const char* getUserName() const {return 0;}
|
||
|
- virtual SConnection::AccessRights getAccessRights() const { return accessRights; }
|
||
|
+ virtual AccessRights getAccessRights() const { return accessRights; }
|
||
|
static StringParameter vncAuthPasswdFile;
|
||
|
static VncAuthPasswdParameter vncAuthPasswd;
|
||
|
private:
|
||
|
@@ -65,7 +65,7 @@ namespace rfb {
|
||
|
rdr::U8 response[vncAuthChallengeSize];
|
||
|
bool sentChallenge;
|
||
|
VncAuthPasswdGetter* pg;
|
||
|
- SConnection::AccessRights accessRights;
|
||
|
+ AccessRights accessRights;
|
||
|
};
|
||
|
}
|
||
|
#endif
|
||
|
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
|
||
|
index 23024c5..441ad3b 100644
|
||
|
--- a/common/rfb/VNCSConnectionST.cxx
|
||
|
+++ b/common/rfb/VNCSConnectionST.cxx
|
||
|
@@ -48,8 +48,9 @@ static LogWriter vlog("VNCSConnST");
|
||
|
static Cursor emptyCursor(0, 0, Point(0, 0), NULL);
|
||
|
|
||
|
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
||
|
- bool reverse)
|
||
|
- : sock(s), reverseConnection(reverse),
|
||
|
+ bool reverse, AccessRights ar)
|
||
|
+ : SConnection(ar),
|
||
|
+ sock(s), reverseConnection(reverse),
|
||
|
inProcessMessages(false),
|
||
|
pendingSyncFence(false), syncFence(false), fenceFlags(0),
|
||
|
fenceDataLen(0), fenceData(NULL), congestionTimer(this),
|
||
|
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
|
||
|
index 72b0c52..66567a6 100644
|
||
|
--- a/common/rfb/VNCSConnectionST.h
|
||
|
+++ b/common/rfb/VNCSConnectionST.h
|
||
|
@@ -40,7 +40,8 @@ namespace rfb {
|
||
|
class VNCSConnectionST : private SConnection,
|
||
|
public Timer::Callback {
|
||
|
public:
|
||
|
- VNCSConnectionST(VNCServerST* server_, network::Socket* s, bool reverse);
|
||
|
+ VNCSConnectionST(VNCServerST* server_, network::Socket* s, bool reverse,
|
||
|
+ AccessRights ar);
|
||
|
virtual ~VNCSConnectionST();
|
||
|
|
||
|
// SConnection methods
|
||
|
diff --git a/common/rfb/VNCServer.h b/common/rfb/VNCServer.h
|
||
|
index 4535b56..a081f63 100644
|
||
|
--- a/common/rfb/VNCServer.h
|
||
|
+++ b/common/rfb/VNCServer.h
|
||
|
@@ -23,17 +23,48 @@
|
||
|
#ifndef __RFB_VNCSERVER_H__
|
||
|
#define __RFB_VNCSERVER_H__
|
||
|
|
||
|
-#include <network/Socket.h>
|
||
|
-
|
||
|
#include <rfb/UpdateTracker.h>
|
||
|
#include <rfb/SSecurity.h>
|
||
|
#include <rfb/ScreenSet.h>
|
||
|
|
||
|
+namespace network { class Socket; }
|
||
|
+
|
||
|
namespace rfb {
|
||
|
|
||
|
- class VNCServer : public UpdateTracker,
|
||
|
- public network::SocketServer {
|
||
|
+ class VNCServer : public UpdateTracker {
|
||
|
public:
|
||
|
+ // addSocket() tells the server to serve the Socket. The caller
|
||
|
+ // retains ownership of the Socket - the only way for the server
|
||
|
+ // to discard a Socket is by calling shutdown() on it.
|
||
|
+ // outgoing is set to true if the socket was created by connecting out
|
||
|
+ // to another host, or false if the socket was created by accept()ing
|
||
|
+ // an incoming connection.
|
||
|
+ // accessRights allows to set the access rights to the server.
|
||
|
+ virtual void addSocket(network::Socket* sock, bool outgoing=false,
|
||
|
+ AccessRights accessRights = AccessDefault) = 0;
|
||
|
+
|
||
|
+ // removeSocket() tells the server to stop serving the Socket. The
|
||
|
+ // caller retains ownership of the Socket - the server must NOT
|
||
|
+ // delete the Socket! This call is used mainly to cause per-Socket
|
||
|
+ // resources to be freed.
|
||
|
+ virtual void removeSocket(network::Socket* sock) = 0;
|
||
|
+
|
||
|
+ // getSockets() gets a list of sockets. This can be used to generate an
|
||
|
+ // fd_set for calling select().
|
||
|
+ virtual void getSockets(std::list<network::Socket*>* sockets) = 0;
|
||
|
+
|
||
|
+ // processSocketReadEvent() tells the server there is a Socket read event.
|
||
|
+ // The implementation can indicate that the Socket is no longer active
|
||
|
+ // by calling shutdown() on it. The caller will then call removeSocket()
|
||
|
+ // soon after processSocketEvent returns, to allow any pre-Socket
|
||
|
+ // resources to be tidied up.
|
||
|
+ virtual void processSocketReadEvent(network::Socket* sock) = 0;
|
||
|
+
|
||
|
+ // processSocketReadEvent() tells the server there is a Socket write event.
|
||
|
+ // This is only necessary if the Socket has been put in non-blocking
|
||
|
+ // mode and needs this callback to flush the buffer.
|
||
|
+ virtual void processSocketWriteEvent(network::Socket* sock) = 0;
|
||
|
+
|
||
|
// blockUpdates()/unblockUpdates() tells the server that the pixel buffer
|
||
|
// is currently in flux and may not be accessed. The attributes of the
|
||
|
// pixel buffer may still be accessed, but not the frame buffer itself.
|
||
|
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
|
||
|
index 411cfd5..6f7c039 100644
|
||
|
--- a/common/rfb/VNCServerST.cxx
|
||
|
+++ b/common/rfb/VNCServerST.cxx
|
||
|
@@ -55,6 +55,8 @@
|
||
|
#include <assert.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
+#include <network/Socket.h>
|
||
|
+
|
||
|
#include <rfb/ComparingUpdateTracker.h>
|
||
|
#include <rfb/KeyRemapper.h>
|
||
|
#include <rfb/LogWriter.h>
|
||
|
@@ -126,9 +128,9 @@ VNCServerST::~VNCServerST()
|
||
|
}
|
||
|
|
||
|
|
||
|
-// SocketServer methods
|
||
|
+// VNCServer methods
|
||
|
|
||
|
-void VNCServerST::addSocket(network::Socket* sock, bool outgoing)
|
||
|
+void VNCServerST::addSocket(network::Socket* sock, bool outgoing, AccessRights accessRights)
|
||
|
{
|
||
|
// - Check the connection isn't black-marked
|
||
|
// *** do this in getSecurity instead?
|
||
|
@@ -161,7 +163,7 @@ void VNCServerST::addSocket(network::Socket* sock, bool outgoing)
|
||
|
connectTimer.start(secsToMillis(rfb::Server::maxConnectionTime));
|
||
|
disconnectTimer.stop();
|
||
|
|
||
|
- VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing);
|
||
|
+ VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing, accessRights);
|
||
|
clients.push_front(client);
|
||
|
client->init();
|
||
|
}
|
||
|
@@ -233,8 +235,6 @@ void VNCServerST::processSocketWriteEvent(network::Socket* sock)
|
||
|
throw rdr::Exception("invalid Socket in VNCServerST");
|
||
|
}
|
||
|
|
||
|
-// VNCServer methods
|
||
|
-
|
||
|
void VNCServerST::blockUpdates()
|
||
|
{
|
||
|
blockCounter++;
|
||
|
@@ -677,7 +677,7 @@ void VNCServerST::queryConnection(VNCSConnectionST* client,
|
||
|
}
|
||
|
|
||
|
// - Does the client have the right to bypass the query?
|
||
|
- if (client->accessCheck(SConnection::AccessNoQuery))
|
||
|
+ if (client->accessCheck(AccessNoQuery))
|
||
|
{
|
||
|
approveConnection(client->getSock(), true, NULL);
|
||
|
return;
|
||
|
@@ -690,7 +690,7 @@ void VNCServerST::clientReady(VNCSConnectionST* client, bool shared)
|
||
|
{
|
||
|
if (!shared) {
|
||
|
if (rfb::Server::disconnectClients &&
|
||
|
- client->accessCheck(SConnection::AccessNonShared)) {
|
||
|
+ client->accessCheck(AccessNonShared)) {
|
||
|
// - Close all the other connected clients
|
||
|
slog.debug("non-shared connection - closing clients");
|
||
|
closeClients("Non-shared connection requested", client->getSock());
|
||
|
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
|
||
|
index 159e3a4..3610062 100644
|
||
|
--- a/common/rfb/VNCServerST.h
|
||
|
+++ b/common/rfb/VNCServerST.h
|
||
|
@@ -51,12 +51,13 @@ namespace rfb {
|
||
|
virtual ~VNCServerST();
|
||
|
|
||
|
|
||
|
- // Methods overridden from SocketServer
|
||
|
+ // Methods overridden from VNCServer
|
||
|
|
||
|
// addSocket
|
||
|
// Causes the server to allocate an RFB-protocol management
|
||
|
// structure for the socket & initialise it.
|
||
|
- virtual void addSocket(network::Socket* sock, bool outgoing=false);
|
||
|
+ virtual void addSocket(network::Socket* sock, bool outgoing=false,
|
||
|
+ AccessRights ar=AccessDefault);
|
||
|
|
||
|
// removeSocket
|
||
|
// Clean up any resources associated with the Socket
|
||
|
@@ -76,9 +77,6 @@ namespace rfb {
|
||
|
// Flush pending data from the Socket on to the network.
|
||
|
virtual void processSocketWriteEvent(network::Socket* sock);
|
||
|
|
||
|
-
|
||
|
- // Methods overridden from VNCServer
|
||
|
-
|
||
|
virtual void blockUpdates();
|
||
|
virtual void unblockUpdates();
|
||
|
virtual void setPixelBuffer(PixelBuffer* pb, const ScreenSet& layout);
|
||
|
diff --git a/tests/perf/encperf.cxx b/tests/perf/encperf.cxx
|
||
|
index 8fb9553..fa87b16 100644
|
||
|
--- a/tests/perf/encperf.cxx
|
||
|
+++ b/tests/perf/encperf.cxx
|
||
|
@@ -41,6 +41,8 @@
|
||
|
#include <rdr/OutStream.h>
|
||
|
#include <rdr/FileInStream.h>
|
||
|
|
||
|
+#include <rfb/AccessRights.h>
|
||
|
+
|
||
|
#include <rfb/PixelFormat.h>
|
||
|
|
||
|
#include <rfb/CConnection.h>
|
||
|
@@ -134,7 +136,7 @@ public:
|
||
|
|
||
|
void getStats(double&, unsigned long long&, unsigned long long&);
|
||
|
|
||
|
- virtual void setAccessRights(AccessRights ar);
|
||
|
+ virtual void setAccessRights(rfb::AccessRights ar);
|
||
|
|
||
|
virtual void setDesktopSize(int fb_width, int fb_height,
|
||
|
const rfb::ScreenSet& layout);
|
||
|
@@ -303,6 +305,7 @@ void Manager::getStats(double& ratio, unsigned long long& encodedBytes,
|
||
|
}
|
||
|
|
||
|
SConn::SConn()
|
||
|
+: SConnection(rfb::AccessDefault)
|
||
|
{
|
||
|
out = new DummyOutStream;
|
||
|
setStreams(NULL, out);
|
||
|
@@ -329,7 +332,7 @@ void SConn::getStats(double& ratio, unsigned long long& bytes,
|
||
|
manager->getStats(ratio, bytes, rawEquivalent);
|
||
|
}
|
||
|
|
||
|
-void SConn::setAccessRights(AccessRights ar)
|
||
|
+void SConn::setAccessRights(rfb::AccessRights)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
diff --git a/unix/vncconfig/vncExt.c b/unix/vncconfig/vncExt.c
|
||
|
index f19123b..4ec671b 100644
|
||
|
--- a/unix/vncconfig/vncExt.c
|
||
|
+++ b/unix/vncconfig/vncExt.c
|
||
|
@@ -228,7 +228,7 @@ Bool XVncExtSelectInput(Display* dpy, Window w, int mask)
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
-Bool XVncExtConnect(Display* dpy, const char* hostAndPort)
|
||
|
+Bool XVncExtConnect(Display* dpy, const char* hostAndPort, Bool viewOnly)
|
||
|
{
|
||
|
xVncExtConnectReq* req;
|
||
|
xVncExtConnectReply rep;
|
||
|
@@ -243,6 +243,7 @@ Bool XVncExtConnect(Display* dpy, const char* hostAndPort)
|
||
|
req->vncExtReqType = X_VncExtConnect;
|
||
|
req->length += (strLen + 3) >> 2;
|
||
|
req->strLen = strLen;
|
||
|
+ req->viewOnly = (CARD8)viewOnly;
|
||
|
Data(dpy, hostAndPort, strLen);
|
||
|
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
|
||
|
UnlockDisplay(dpy);
|
||
|
diff --git a/unix/vncconfig/vncExt.h b/unix/vncconfig/vncExt.h
|
||
|
index 2b24469..4383248 100644
|
||
|
--- a/unix/vncconfig/vncExt.h
|
||
|
+++ b/unix/vncconfig/vncExt.h
|
||
|
@@ -46,7 +46,7 @@ char* XVncExtGetParamDesc(Display* dpy, const char* param);
|
||
|
char** XVncExtListParams(Display* dpy, int* nParams);
|
||
|
void XVncExtFreeParamList(char** list);
|
||
|
Bool XVncExtSelectInput(Display* dpy, Window w, int mask);
|
||
|
-Bool XVncExtConnect(Display* dpy, const char* hostAndPort);
|
||
|
+Bool XVncExtConnect(Display* dpy, const char* hostAndPort, Bool viewOnly);
|
||
|
Bool XVncExtGetQueryConnect(Display* dpy, char** addr,
|
||
|
char** user, int* timeout, void** opaqueId);
|
||
|
Bool XVncExtApproveConnect(Display* dpy, void* opaqueId, int approve);
|
||
|
@@ -181,7 +181,7 @@ typedef struct {
|
||
|
CARD8 vncExtReqType; /* always VncExtConnect */
|
||
|
CARD16 length B16;
|
||
|
CARD8 strLen;
|
||
|
- CARD8 pad0;
|
||
|
+ CARD8 viewOnly;
|
||
|
CARD16 pad1 B16;
|
||
|
} xVncExtConnectReq;
|
||
|
#define sz_xVncExtConnectReq 8
|
||
|
diff --git a/unix/vncconfig/vncconfig.cxx b/unix/vncconfig/vncconfig.cxx
|
||
|
index 276d0e6..0d644ed 100644
|
||
|
--- a/unix/vncconfig/vncconfig.cxx
|
||
|
+++ b/unix/vncconfig/vncconfig.cxx
|
||
|
@@ -177,8 +177,8 @@ static void usage()
|
||
|
{
|
||
|
fprintf(stderr,"usage: %s [parameters]\n",
|
||
|
programName);
|
||
|
- fprintf(stderr," %s [parameters] -connect <host>[:<port>]\n",
|
||
|
- programName);
|
||
|
+ fprintf(stderr," %s [parameters] -connect "
|
||
|
+ "[-view-only] <host>[:<port>]\n", programName);
|
||
|
fprintf(stderr," %s [parameters] -disconnect\n", programName);
|
||
|
fprintf(stderr," %s [parameters] [-set] <Xvnc-param>=<value> ...\n",
|
||
|
programName);
|
||
|
@@ -241,13 +241,18 @@ int main(int argc, char** argv)
|
||
|
if (i < argc) {
|
||
|
for (; i < argc; i++) {
|
||
|
if (strcmp(argv[i], "-connect") == 0) {
|
||
|
+ Bool viewOnly = False;
|
||
|
i++;
|
||
|
+ if (strcmp(argv[i], "-view-only") == 0) {
|
||
|
+ viewOnly = True;
|
||
|
+ i++;
|
||
|
+ }
|
||
|
if (i >= argc) usage();
|
||
|
- if (!XVncExtConnect(dpy, argv[i])) {
|
||
|
+ if (!XVncExtConnect(dpy, argv[i], viewOnly)) {
|
||
|
fprintf(stderr,"connecting to %s failed\n",argv[i]);
|
||
|
}
|
||
|
} else if (strcmp(argv[i], "-disconnect") == 0) {
|
||
|
- if (!XVncExtConnect(dpy, "")) {
|
||
|
+ if (!XVncExtConnect(dpy, "", False)) {
|
||
|
fprintf(stderr,"disconnecting all clients failed\n");
|
||
|
}
|
||
|
} else if (strcmp(argv[i], "-get") == 0) {
|
||
|
diff --git a/unix/vncconfig/vncconfig.man b/unix/vncconfig/vncconfig.man
|
||
|
index ed9ddda..b07c02f 100644
|
||
|
--- a/unix/vncconfig/vncconfig.man
|
||
|
+++ b/unix/vncconfig/vncconfig.man
|
||
|
@@ -7,7 +7,7 @@ vncconfig \- configure and control a VNC server
|
||
|
.br
|
||
|
.B vncconfig
|
||
|
.RI [ parameters ]
|
||
|
-.B \-connect
|
||
|
+.B \-connect \fP[\fB-view-only\fP]
|
||
|
.IR host [: port ]
|
||
|
.br
|
||
|
.B vncconfig
|
||
|
@@ -55,12 +55,13 @@ is no VNC extension.
|
||
|
|
||
|
.SH OPTIONS
|
||
|
.TP
|
||
|
-.B \-connect \fIhost\fP[:\fIport\fP]
|
||
|
+.B \-connect \fP[\fB-view-only\fP] \fIhost\fP[:\fIport\fP]
|
||
|
Tells an Xvnc server to make a "reverse" connection to a listening VNC viewer
|
||
|
(normally connections are made the other way round - the viewer connects to the
|
||
|
server). \fIhost\fP is the host where the listening viewer is running. If it's
|
||
|
not listening on the default port of 5500, you can specify \fIhost:port\fP
|
||
|
-instead.
|
||
|
+instead. The \fB-view-only\fP option specifies that the server must ignore all
|
||
|
+keyboard or mouse events sent by the client.
|
||
|
.
|
||
|
.TP
|
||
|
.B \-disconnect
|
||
|
diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx
|
||
|
index f9c8109..6719c43 100644
|
||
|
--- a/unix/x0vncserver/XDesktop.cxx
|
||
|
+++ b/unix/x0vncserver/XDesktop.cxx
|
||
|
@@ -26,6 +26,8 @@
|
||
|
#include <signal.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
+#include <network/Socket.h>
|
||
|
+
|
||
|
#include <rfb/LogWriter.h>
|
||
|
|
||
|
#include <x0vncserver/XDesktop.h>
|
||
|
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
|
||
|
index 603e1e5..5f08f10 100644
|
||
|
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
|
||
|
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
|
||
|
@@ -311,7 +311,7 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write)
|
||
|
|
||
|
bool XserverDesktop::handleListenerEvent(int fd,
|
||
|
std::list<SocketListener*>* sockets,
|
||
|
- SocketServer* sockserv)
|
||
|
+ VNCServer* sockserv)
|
||
|
{
|
||
|
std::list<SocketListener*>::iterator i;
|
||
|
|
||
|
@@ -332,7 +332,7 @@ bool XserverDesktop::handleListenerEvent(int fd,
|
||
|
}
|
||
|
|
||
|
bool XserverDesktop::handleSocketEvent(int fd,
|
||
|
- SocketServer* sockserv,
|
||
|
+ VNCServer* sockserv,
|
||
|
bool read, bool write)
|
||
|
{
|
||
|
std::list<Socket*> sockets;
|
||
|
@@ -402,10 +402,10 @@ void XserverDesktop::blockHandler(int* timeout)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-void XserverDesktop::addClient(Socket* sock, bool reverse)
|
||
|
+void XserverDesktop::addClient(Socket* sock, bool reverse, bool viewOnly)
|
||
|
{
|
||
|
vlog.debug("new client, sock %d reverse %d",sock->getFd(),reverse);
|
||
|
- server->addSocket(sock, reverse);
|
||
|
+ server->addSocket(sock, reverse, viewOnly ? AccessView : AccessDefault);
|
||
|
vncSetNotifyFd(sock->getFd(), screenIndex, true, false);
|
||
|
}
|
||
|
|
||
|
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
|
||
|
index 57ee808..1382677 100644
|
||
|
--- a/unix/xserver/hw/vnc/XserverDesktop.h
|
||
|
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
|
||
|
@@ -42,7 +42,7 @@ namespace rfb {
|
||
|
class VNCServerST;
|
||
|
}
|
||
|
|
||
|
-namespace network { class SocketListener; class Socket; class SocketServer; }
|
||
|
+namespace network { class SocketListener; class Socket; }
|
||
|
|
||
|
class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
|
||
|
public rfb::Timer::Callback {
|
||
|
@@ -72,7 +72,7 @@ public:
|
||
|
void add_copied(const rfb::Region &dest, const rfb::Point &delta);
|
||
|
void handleSocketEvent(int fd, bool read, bool write);
|
||
|
void blockHandler(int* timeout);
|
||
|
- void addClient(network::Socket* sock, bool reverse);
|
||
|
+ void addClient(network::Socket* sock, bool reverse, bool viewOnly);
|
||
|
void disconnectClients();
|
||
|
|
||
|
// QueryConnect methods called from X server code
|
||
|
@@ -107,9 +107,9 @@ public:
|
||
|
protected:
|
||
|
bool handleListenerEvent(int fd,
|
||
|
std::list<network::SocketListener*>* sockets,
|
||
|
- network::SocketServer* sockserv);
|
||
|
+ rfb::VNCServer* sockserv);
|
||
|
bool handleSocketEvent(int fd,
|
||
|
- network::SocketServer* sockserv,
|
||
|
+ rfb::VNCServer* sockserv,
|
||
|
bool read, bool write);
|
||
|
|
||
|
virtual bool handleTimeout(rfb::Timer* t);
|
||
|
diff --git a/unix/xserver/hw/vnc/vncExt.c b/unix/xserver/hw/vnc/vncExt.c
|
||
|
index 89c1055..e98275c 100644
|
||
|
--- a/unix/xserver/hw/vnc/vncExt.c
|
||
|
+++ b/unix/xserver/hw/vnc/vncExt.c
|
||
|
@@ -348,7 +348,7 @@ static int ProcVncExtConnect(ClientPtr client)
|
||
|
address[stuff->strLen] = 0;
|
||
|
|
||
|
rep.success = 0;
|
||
|
- if (vncConnectClient(address) == 0)
|
||
|
+ if (vncConnectClient(address, (int)stuff->viewOnly) == 0)
|
||
|
rep.success = 1;
|
||
|
|
||
|
rep.type = X_Reply;
|
||
|
diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc
|
||
|
index 8dbc048..2e0dc9e 100644
|
||
|
--- a/unix/xserver/hw/vnc/vncExtInit.cc
|
||
|
+++ b/unix/xserver/hw/vnc/vncExtInit.cc
|
||
|
@@ -262,7 +262,7 @@ void vncExtensionInit(void)
|
||
|
|
||
|
if (scr == 0 && vncInetdSock != -1 && listeners.empty()) {
|
||
|
network::Socket* sock = new network::TcpSocket(vncInetdSock);
|
||
|
- desktop[scr]->addClient(sock, false);
|
||
|
+ desktop[scr]->addClient(sock, false, false);
|
||
|
vlog.info("added inetd sock");
|
||
|
}
|
||
|
}
|
||
|
@@ -338,7 +338,7 @@ void vncSendClipboardData(const char* data)
|
||
|
desktop[scr]->sendClipboardData(data);
|
||
|
}
|
||
|
|
||
|
-int vncConnectClient(const char *addr)
|
||
|
+int vncConnectClient(const char *addr, int viewOnly)
|
||
|
{
|
||
|
if (strlen(addr) == 0) {
|
||
|
try {
|
||
|
@@ -357,8 +357,10 @@ int vncConnectClient(const char *addr)
|
||
|
|
||
|
try {
|
||
|
network::Socket* sock = new network::TcpSocket(host, port);
|
||
|
+ vlog.info("Reverse connection: %s:%d%s", host, port,
|
||
|
+ viewOnly ? " (view only)" : "");
|
||
|
delete [] host;
|
||
|
- desktop[0]->addClient(sock, true);
|
||
|
+ desktop[0]->addClient(sock, true, (bool)viewOnly);
|
||
|
} catch (rdr::Exception& e) {
|
||
|
vlog.error("Reverse connection: %s",e.str());
|
||
|
return -1;
|
||
|
diff --git a/unix/xserver/hw/vnc/vncExtInit.h b/unix/xserver/hw/vnc/vncExtInit.h
|
||
|
index c317d8a..333e32a 100644
|
||
|
--- a/unix/xserver/hw/vnc/vncExtInit.h
|
||
|
+++ b/unix/xserver/hw/vnc/vncExtInit.h
|
||
|
@@ -57,7 +57,7 @@ void vncRequestClipboard(void);
|
||
|
void vncAnnounceClipboard(int available);
|
||
|
void vncSendClipboardData(const char* data);
|
||
|
|
||
|
-int vncConnectClient(const char *addr);
|
||
|
+int vncConnectClient(const char *addr, int viewOnly);
|
||
|
|
||
|
void vncGetQueryConnect(uint32_t *opaqueId, const char**username,
|
||
|
const char **address, int *timeout);
|
||
|
diff --git a/win/rfb_win32/SocketManager.cxx b/win/rfb_win32/SocketManager.cxx
|
||
|
index 5463b24..9c9a736 100644
|
||
|
--- a/win/rfb_win32/SocketManager.cxx
|
||
|
+++ b/win/rfb_win32/SocketManager.cxx
|
||
|
@@ -24,8 +24,12 @@
|
||
|
|
||
|
#include <winsock2.h>
|
||
|
#include <list>
|
||
|
+
|
||
|
+#include <network/Socket.h>
|
||
|
+
|
||
|
#include <rfb/LogWriter.h>
|
||
|
#include <rfb/Timer.h>
|
||
|
+#include <rfb/VNCServer.h>
|
||
|
#include <rfb_win32/SocketManager.h>
|
||
|
|
||
|
using namespace rfb;
|
||
|
@@ -54,7 +58,7 @@ static void requestAddressChangeEvents(network::SocketListener* sock_) {
|
||
|
|
||
|
|
||
|
void SocketManager::addListener(network::SocketListener* sock_,
|
||
|
- network::SocketServer* srvr,
|
||
|
+ VNCServer* srvr,
|
||
|
AddressChangeNotifier* acn) {
|
||
|
WSAEVENT event = WSACreateEvent();
|
||
|
long flags = FD_ACCEPT | FD_CLOSE;
|
||
|
@@ -102,7 +106,7 @@ void SocketManager::remListener(network::SocketListener* sock) {
|
||
|
}
|
||
|
|
||
|
|
||
|
-void SocketManager::addSocket(network::Socket* sock_, network::SocketServer* srvr, bool outgoing) {
|
||
|
+void SocketManager::addSocket(network::Socket* sock_, VNCServer* srvr, bool outgoing) {
|
||
|
WSAEVENT event = WSACreateEvent();
|
||
|
if (!event || !addEvent(event, this) ||
|
||
|
(WSAEventSelect(sock_->getFd(), event, FD_READ | FD_CLOSE) == SOCKET_ERROR)) {
|
||
|
@@ -134,7 +138,7 @@ void SocketManager::remSocket(network::Socket* sock_) {
|
||
|
throw rdr::Exception("Socket not registered");
|
||
|
}
|
||
|
|
||
|
-bool SocketManager::getDisable(network::SocketServer* srvr)
|
||
|
+bool SocketManager::getDisable(VNCServer* srvr)
|
||
|
{
|
||
|
std::map<HANDLE,ListenInfo>::iterator i;
|
||
|
for (i=listeners.begin(); i!=listeners.end(); i++) {
|
||
|
@@ -145,7 +149,7 @@ bool SocketManager::getDisable(network::SocketServer* srvr)
|
||
|
throw rdr::Exception("Listener not registered");
|
||
|
}
|
||
|
|
||
|
-void SocketManager::setDisable(network::SocketServer* srvr, bool disable)
|
||
|
+void SocketManager::setDisable(VNCServer* srvr, bool disable)
|
||
|
{
|
||
|
bool found = false;
|
||
|
std::map<HANDLE,ListenInfo>::iterator i;
|
||
|
diff --git a/win/rfb_win32/SocketManager.h b/win/rfb_win32/SocketManager.h
|
||
|
index e5ca02e..809c470 100644
|
||
|
--- a/win/rfb_win32/SocketManager.h
|
||
|
+++ b/win/rfb_win32/SocketManager.h
|
||
|
@@ -19,22 +19,28 @@
|
||
|
// -=- SocketManager.h
|
||
|
|
||
|
// Socket manager class for Win32.
|
||
|
-// Passed a network::SocketListener and a network::SocketServer when
|
||
|
+// Passed a network::SocketListener and a rfb::VNCServer when
|
||
|
// constructed. Uses WSAAsyncSelect to get notifications of network
|
||
|
// connection attempts. When an incoming connection is received,
|
||
|
-// the manager will call network::SocketServer::addClient(). If
|
||
|
+// the manager will call rfb::VNCServer::addClient(). If
|
||
|
// addClient returns true then the manager registers interest in
|
||
|
// network events on that socket, and calls
|
||
|
-// network::SocketServer::processSocketEvent().
|
||
|
+// rfb::VNCServer::processSocketEvent().
|
||
|
|
||
|
#ifndef __RFB_WIN32_SOCKET_MGR_H__
|
||
|
#define __RFB_WIN32_SOCKET_MGR_H__
|
||
|
|
||
|
#include <map>
|
||
|
-#include <network/Socket.h>
|
||
|
#include <rfb_win32/EventManager.h>
|
||
|
|
||
|
+namespace network {
|
||
|
+ class SocketListener;
|
||
|
+ class Socket;
|
||
|
+}
|
||
|
+
|
||
|
namespace rfb {
|
||
|
+ class VNCServer;
|
||
|
+
|
||
|
namespace win32 {
|
||
|
|
||
|
class SocketManager : public EventManager, EventHandler {
|
||
|
@@ -52,21 +58,21 @@ namespace rfb {
|
||
|
};
|
||
|
|
||
|
// Add a listening socket. Incoming connections will be added to the supplied
|
||
|
- // SocketServer.
|
||
|
+ // VNCServer.
|
||
|
void addListener(network::SocketListener* sock_,
|
||
|
- network::SocketServer* srvr,
|
||
|
+ VNCServer* srvr,
|
||
|
AddressChangeNotifier* acn = 0);
|
||
|
|
||
|
// Remove and delete a listening socket.
|
||
|
void remListener(network::SocketListener* sock);
|
||
|
|
||
|
// Add an already-connected socket. Socket events will cause the supplied
|
||
|
- // SocketServer to be called. The socket must ALREADY BE REGISTERED with
|
||
|
- // the SocketServer.
|
||
|
- void addSocket(network::Socket* sock_, network::SocketServer* srvr, bool outgoing=true);
|
||
|
+ // VNCServer to be called. The socket must ALREADY BE REGISTERED with
|
||
|
+ // the VNCServer.
|
||
|
+ void addSocket(network::Socket* sock_, VNCServer* srvr, bool outgoing=true);
|
||
|
|
||
|
- bool getDisable(network::SocketServer* srvr);
|
||
|
- void setDisable(network::SocketServer* srvr, bool disable);
|
||
|
+ bool getDisable(VNCServer* srvr);
|
||
|
+ void setDisable(VNCServer* srvr, bool disable);
|
||
|
|
||
|
protected:
|
||
|
virtual int checkTimeouts();
|
||
|
@@ -75,11 +81,11 @@ namespace rfb {
|
||
|
|
||
|
struct ConnInfo {
|
||
|
network::Socket* sock;
|
||
|
- network::SocketServer* server;
|
||
|
+ VNCServer* server;
|
||
|
};
|
||
|
struct ListenInfo {
|
||
|
network::SocketListener* sock;
|
||
|
- network::SocketServer* server;
|
||
|
+ VNCServer* server;
|
||
|
AddressChangeNotifier* notifier;
|
||
|
bool disable;
|
||
|
};
|
||
|
diff --git a/win/winvnc/ManagedListener.cxx b/win/winvnc/ManagedListener.cxx
|
||
|
index a93ca29..1a27867 100644
|
||
|
--- a/win/winvnc/ManagedListener.cxx
|
||
|
+++ b/win/winvnc/ManagedListener.cxx
|
||
|
@@ -45,7 +45,7 @@ ManagedListener::~ManagedListener() {
|
||
|
}
|
||
|
|
||
|
|
||
|
-void ManagedListener::setServer(network::SocketServer* svr) {
|
||
|
+void ManagedListener::setServer(rfb::VNCServer* svr) {
|
||
|
if (svr == server)
|
||
|
return;
|
||
|
vlog.info("set server to %p", svr);
|
||
|
diff --git a/win/winvnc/ManagedListener.h b/win/winvnc/ManagedListener.h
|
||
|
index 39223c7..20503c3 100644
|
||
|
--- a/win/winvnc/ManagedListener.h
|
||
|
+++ b/win/winvnc/ManagedListener.h
|
||
|
@@ -27,7 +27,7 @@ namespace winvnc {
|
||
|
|
||
|
// -=- ManagedListener
|
||
|
// Wrapper class which simplifies the management of a listening socket
|
||
|
- // on a specified port, attached to a SocketManager and SocketServer.
|
||
|
+ // on a specified port, attached to a SocketManager and VNCServer.
|
||
|
// Reopens sockets & reconfigures filters & callbacks as appropriate.
|
||
|
// Handles addition/removal of Listeners from SocketManager internally.
|
||
|
|
||
|
@@ -36,7 +36,7 @@ namespace winvnc {
|
||
|
ManagedListener(rfb::win32::SocketManager* mgr);
|
||
|
~ManagedListener();
|
||
|
|
||
|
- void setServer(network::SocketServer* svr);
|
||
|
+ void setServer(rfb::VNCServer* svr);
|
||
|
void setPort(int port, bool localOnly=false);
|
||
|
void setFilter(const char* filter);
|
||
|
void setAddressChangeNotifier(rfb::win32::SocketManager::AddressChangeNotifier* acn);
|
||
|
@@ -49,7 +49,7 @@ namespace winvnc {
|
||
|
network::TcpFilter* filter;
|
||
|
rfb::win32::SocketManager* manager;
|
||
|
rfb::win32::SocketManager::AddressChangeNotifier* addrChangeNotifier;
|
||
|
- network::SocketServer* server;
|
||
|
+ rfb::VNCServer* server;
|
||
|
int port;
|
||
|
bool localOnly;
|
||
|
};
|
||
|
diff --git a/win/winvnc/VNCServerWin32.cxx b/win/winvnc/VNCServerWin32.cxx
|
||
|
index 79769e9..b884352 100644
|
||
|
--- a/win/winvnc/VNCServerWin32.cxx
|
||
|
+++ b/win/winvnc/VNCServerWin32.cxx
|
||
|
@@ -366,11 +366,11 @@ void VNCServerWin32::getConnInfo(ListConnInfo * listConn)
|
||
|
|
||
|
if (!conn->authenticated())
|
||
|
status = 3;
|
||
|
- else if (conn->accessCheck(rfb::SConnection::AccessPtrEvents |
|
||
|
- rfb::SConnection::AccessKeyEvents |
|
||
|
- rfb::SConnection::AccessView))
|
||
|
+ else if (conn->accessCheck(rfb::AccessPtrEvents |
|
||
|
+ rfb::AccessKeyEvents |
|
||
|
+ rfb::AccessView))
|
||
|
status = 0;
|
||
|
- else if (conn->accessCheck(rfb::SConnection::AccessView))
|
||
|
+ else if (conn->accessCheck(rfb::AccessView))
|
||
|
status = 1;
|
||
|
else
|
||
|
status = 2;
|
||
|
@@ -401,25 +401,25 @@ void VNCServerWin32::setConnStatus(ListConnInfo* listConn)
|
||
|
if (status == 3) {
|
||
|
conn->close(0);
|
||
|
} else {
|
||
|
- rfb::SConnection::AccessRights ar;
|
||
|
+ rfb::AccessRights ar;
|
||
|
|
||
|
- ar = rfb::SConnection::AccessDefault;
|
||
|
+ ar = rfb::AccessDefault;
|
||
|
|
||
|
switch (status) {
|
||
|
case 0:
|
||
|
- ar |= rfb::SConnection::AccessPtrEvents |
|
||
|
- rfb::SConnection::AccessKeyEvents |
|
||
|
- rfb::SConnection::AccessView;
|
||
|
+ ar |= rfb::AccessPtrEvents |
|
||
|
+ rfb::AccessKeyEvents |
|
||
|
+ rfb::AccessView;
|
||
|
break;
|
||
|
case 1:
|
||
|
- ar |= rfb::SConnection::AccessView;
|
||
|
- ar &= ~(rfb::SConnection::AccessPtrEvents |
|
||
|
- rfb::SConnection::AccessKeyEvents);
|
||
|
+ ar |= rfb::AccessView;
|
||
|
+ ar &= ~(rfb::AccessPtrEvents |
|
||
|
+ rfb::AccessKeyEvents);
|
||
|
break;
|
||
|
case 2:
|
||
|
- ar &= ~(rfb::SConnection::AccessPtrEvents |
|
||
|
- rfb::SConnection::AccessKeyEvents |
|
||
|
- rfb::SConnection::AccessView);
|
||
|
+ ar &= ~(rfb::AccessPtrEvents |
|
||
|
+ rfb::AccessKeyEvents |
|
||
|
+ rfb::AccessView);
|
||
|
break;
|
||
|
}
|
||
|
conn->setAccessRights(ar);
|