]> source.dussan.org Git - tigervnc.git/commitdiff
Move access rights and closing to SConnection object
authorPierre Ossman <ossman@cendio.se>
Mon, 8 Oct 2018 13:59:02 +0000 (15:59 +0200)
committerPierre Ossman <ossman@cendio.se>
Wed, 10 Oct 2018 11:15:30 +0000 (13:15 +0200)
This makes it generally useful and other code doesn't have to
know of the specific sub-class.

common/rfb/SConnection.cxx
common/rfb/SConnection.h
common/rfb/VNCSConnectionST.cxx
common/rfb/VNCSConnectionST.h
common/rfb/VNCServer.h
common/rfb/VNCServerST.cxx
common/rfb/VNCServerST.h

index efc26acfe1e00828c0e08027f084ba4d0a3c07f0..6b4a5c4fd7fade29a156994ffc47b2de7ee42e1d 100644 (file)
@@ -269,6 +269,16 @@ void SConnection::writeConnFailedFromScratch(const char* msg,
   os->flush();
 }
 
+void SConnection::setAccessRights(AccessRights ar)
+{
+  accessRights = ar;
+}
+
+bool SConnection::accessCheck(AccessRights ar) const
+{
+  return (accessRights & ar) == ar;
+}
+
 void SConnection::setEncodings(int nEncodings, const rdr::S32* encodings)
 {
   int i;
@@ -342,6 +352,11 @@ void SConnection::clientInit(bool shared)
   state_ = RFBSTATE_NORMAL;
 }
 
+void SConnection::close(const char* reason)
+{
+  state_ = RFBSTATE_CLOSING;
+}
+
 void SConnection::setPixelFormat(const PixelFormat& pf)
 {
   SMsgHandler::setPixelFormat(pf);
index 47092e356aa72fd5010f23064fd742e6458790bb..7148294b0d912930b8b7480c7a51a5aff684d194 100644 (file)
@@ -69,6 +69,13 @@ namespace rfb {
     void approveConnection(bool accept, const char* reason=0);
 
 
+    // Methods to terminate the connection
+
+    // close() shuts down the connection to the client and awaits
+    // cleanup of the SConnection object by the server
+    virtual void close(const char* reason);
+
+
     // Overridden from SMsgHandler
 
     virtual void setEncodings(int nEncodings, const rdr::S32* encodings);
@@ -118,8 +125,10 @@ namespace rfb {
     virtual void enableContinuousUpdates(bool enable,
                                          int x, int y, int w, int h);
 
+    // Other methods
+
     // setAccessRights() allows a security package to limit the access rights
-    // of a VNCSConnectionST to the server.  How the access rights are treated
+    // of a SConnection to the server.  How the access rights are treated
     // is up to the derived class.
 
     typedef rdr::U16 AccessRights;
@@ -132,9 +141,8 @@ namespace rfb {
     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) = 0;
-
-    // Other methods
+    virtual void setAccessRights(AccessRights ar);
+    virtual bool accessCheck(AccessRights ar) const;
 
     // authenticated() returns true if the client has authenticated
     // successfully.
@@ -201,6 +209,7 @@ namespace rfb {
     SSecurity* ssecurity;
     stateEnum state_;
     rdr::S32 preferredEncoding;
+    AccessRights accessRights;
   };
 }
 #endif
index b5f81c615e55d128e2294e95ccf75e69f74388ee..d9e276a919c7c8b59cbac09f34e7224c0f0488f4 100644 (file)
@@ -52,8 +52,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
     losslessTimer(this), server(server_), updates(false),
     updateRenderedCursor(false), removeRenderedCursor(false),
     continuousUpdates(false), encodeManager(this), pointerEventTime(0),
-    clientHasCursor(false),
-    accessRights(AccessDefault), startTime(time(0))
+    clientHasCursor(false), startTime(time(0))
 {
   setStreams(&sock->inStream(), &sock->outStream());
   peerEndpoint.buf = sock->getPeerEndpoint();
@@ -94,17 +93,16 @@ VNCSConnectionST::~VNCSConnectionST()
 }
 
 
-// Methods called from VNCServerST
+// SConnection methods
 
-bool VNCSConnectionST::init()
+bool VNCSConnectionST::accessCheck(AccessRights ar) const
 {
-  try {
-    initialiseProtocol();
-  } catch (rdr::Exception& e) {
-    close(e.str());
-    return false;
-  }
-  return true;
+  // Reverse connections are user initiated, so they are implicitly
+  // allowed to bypass the query
+  if (reverseConnection)
+    ar &= ~AccessNoQuery;
+
+  return SConnection::accessCheck(ar);
 }
 
 void VNCSConnectionST::close(const char* reason)
@@ -123,7 +121,22 @@ void VNCSConnectionST::close(const char* reason)
   // calling code will call VNCServerST's removeSocket() method causing us to
   // be deleted.
   sock->shutdown();
-  setState(RFBSTATE_CLOSING);
+
+  SConnection::close(reason);
+}
+
+
+// Methods called from VNCServerST
+
+bool VNCSConnectionST::init()
+{
+  try {
+    initialiseProtocol();
+  } catch (rdr::Exception& e) {
+    close(e.str());
+    return false;
+  }
+  return true;
 }
 
 
@@ -267,7 +280,7 @@ void VNCSConnectionST::bellOrClose()
 void VNCSConnectionST::serverCutTextOrClose(const char *str, int len)
 {
   try {
-    if (!(accessRights & AccessCutText)) return;
+    if (!accessCheck(AccessCutText)) return;
     if (!rfb::Server::sendCutText) return;
     if (state() == RFBSTATE_NORMAL)
       writer()->writeServerCutText(str, len);
@@ -447,9 +460,8 @@ void VNCSConnectionST::queryConnection(const char* userName)
   }
 
   // - Does the client have the right to bypass the query?
-  if (reverseConnection ||
-      !(rfb::Server::queryConnect || sock->requiresQuery()) ||
-      (accessRights & AccessNoQuery))
+  if (!(rfb::Server::queryConnect || sock->requiresQuery()) ||
+      accessCheck(AccessNoQuery))
   {
     approveConnection(true);
     return;
@@ -463,10 +475,10 @@ void VNCSConnectionST::clientInit(bool shared)
 {
   lastEventTime = time(0);
   if (rfb::Server::alwaysShared || reverseConnection) shared = true;
-  if (!(accessRights & AccessNonShared)) shared = true;
+  if (!accessCheck(AccessNonShared)) shared = true;
   if (rfb::Server::neverShared) shared = false;
   if (!shared) {
-    if (rfb::Server::disconnectClients && (accessRights & AccessNonShared)) {
+    if (rfb::Server::disconnectClients && accessCheck(AccessNonShared)) {
       // - Close all the other connected clients
       vlog.debug("non-shared connection - closing clients");
       server->closeClients("Non-shared connection requested", getSock());
@@ -494,7 +506,7 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf)
 void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask)
 {
   pointerEventTime = lastEventTime = time(0);
-  if (!(accessRights & AccessPtrEvents)) return;
+  if (!accessCheck(AccessPtrEvents)) return;
   if (!rfb::Server::acceptPointerEvents) return;
   pointerEventPos = pos;
   server->pointerEvent(this, pointerEventPos, buttonMask);
@@ -526,7 +538,7 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
   rdr::U32 lookup;
 
   lastEventTime = time(0);
-  if (!(accessRights & AccessKeyEvents)) return;
+  if (!accessCheck(AccessKeyEvents)) return;
   if (!rfb::Server::acceptKeyEvents) return;
 
   if (down)
@@ -636,7 +648,7 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
 
 void VNCSConnectionST::clientCutText(const char* str, int len)
 {
-  if (!(accessRights & AccessCutText)) return;
+  if (!accessCheck(AccessCutText)) return;
   if (!rfb::Server::acceptCutText) return;
   server->clientCutText(str, len);
 }
@@ -645,7 +657,7 @@ void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental)
 {
   Rect safeRect;
 
-  if (!(accessRights & AccessView)) return;
+  if (!accessCheck(AccessView)) return;
 
   SConnection::framebufferUpdateRequest(r, incremental);
 
@@ -684,7 +696,7 @@ void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
 {
   unsigned int result;
 
-  if (!(accessRights & AccessSetDesktopSize)) return;
+  if (!accessCheck(AccessSetDesktopSize)) return;
   if (!rfb::Server::acceptSetDesktopSize) return;
 
   result = server->setDesktopSize(this, fb_width, fb_height, layout);
@@ -1158,27 +1170,34 @@ char* VNCSConnectionST::getStartTime()
 
 void VNCSConnectionST::setStatus(int status)
 {
+  AccessRights ar;
+
+  ar = AccessDefault;
+
   switch (status) {
   case 0:
-    accessRights = accessRights | AccessPtrEvents | AccessKeyEvents | AccessView;
+    ar |= AccessPtrEvents | AccessKeyEvents | AccessView;
     break;
   case 1:
-    accessRights = (accessRights & ~(AccessPtrEvents | AccessKeyEvents)) | AccessView;
+    ar |= rfb::SConnection::AccessView;
+    ar &= ~(AccessPtrEvents | AccessKeyEvents);
     break;
   case 2:
-    accessRights = accessRights & ~(AccessPtrEvents | AccessKeyEvents | AccessView);
+    ar &= ~(AccessPtrEvents | AccessKeyEvents | AccessView);
     break;
   }
+
+  setAccessRights(ar);
+
   framebufferUpdateRequest(server->getPixelBuffer()->getRect(), false);
 }
 int VNCSConnectionST::getStatus()
 {
-  if ((accessRights & (AccessPtrEvents | AccessKeyEvents | AccessView)) == 0x0007)
+  if (accessCheck(AccessPtrEvents | AccessKeyEvents | AccessView))
     return 0;
-  if ((accessRights & (AccessPtrEvents | AccessKeyEvents | AccessView)) == 0x0001)
+  else if (accessCheck(AccessView))
     return 1;
-  if ((accessRights & (AccessPtrEvents | AccessKeyEvents | AccessView)) == 0x0000)
+  else
     return 2;
-  return 4;
 }
 
index faa0479317daf78cbcee7ba73b286424934d7014..121ebcc1f88f5432a42318624b68c32962330e16 100644 (file)
@@ -43,6 +43,11 @@ namespace rfb {
     VNCSConnectionST(VNCServerST* server_, network::Socket* s, bool reverse);
     virtual ~VNCSConnectionST();
 
+    // SConnection methods
+
+    virtual bool accessCheck(AccessRights ar) const;
+    virtual void close(const char* reason);
+
     // Methods called from VNCServerST.  None of these methods ever knowingly
     // throw an exception.
 
@@ -54,10 +59,6 @@ namespace rfb {
     // returns false, and close() will have been called.
     bool init();
 
-    // close() shuts down the socket to the client and deletes the
-    // SConnectionST object.
-    void close(const char* reason);
-
     // processMessages() processes incoming messages from the client, invoking
     // various callbacks as a result.  It continues to process messages until
     // reading might block.  shutdown() will be called on the connection's
@@ -141,12 +142,6 @@ namespace rfb {
     virtual void supportsContinuousUpdates();
     virtual void supportsLEDState();
 
-    // setAccessRights() allows a security package to limit the access rights
-    // of a VNCSConnectioST to the server.  These access rights are applied
-    // such that the actual rights granted are the minimum of the server's
-    // default access settings and the connection's access settings.
-    virtual void setAccessRights(AccessRights ar) {accessRights=ar;}
-
     // Timer callbacks
     virtual bool handleTimeout(Timer* t);
 
@@ -202,8 +197,6 @@ namespace rfb {
     Point pointerEventPos;
     bool clientHasCursor;
 
-    AccessRights accessRights;
-
     CharArray closeReason;
     time_t startTime;
   };
index 2987ec0e7e4ef3849d0db443b9f3492181f23a94..5bb7c0bf6711ade27d19ff8fe30a5c18a4a56e23 100644 (file)
@@ -73,6 +73,10 @@ namespace rfb {
     //   their close() method with the supplied reason.
     virtual void closeClients(const char* reason) = 0;
 
+    // getConnection() gets the SConnection for a particular Socket.  If
+    // the Socket is not recognised then null is returned.
+    virtual SConnection* getConnection(network::Socket* sock) = 0;
+
     // setCursor() tells the server that the cursor has changed.  The
     // cursorData argument contains width*height rgba quadruplets with
     // non-premultiplied alpha.
index 31ac5d1c2dba49abc9ab5234f3c1e652f00a24a2..5e166119d15010189b7f7ad0fcf6a3c580636195 100644 (file)
@@ -583,7 +583,7 @@ void VNCServerST::getSockets(std::list<network::Socket*>* sockets)
   }
 }
 
-SConnection* VNCServerST::getSConnection(network::Socket* sock) {
+SConnection* VNCServerST::getConnection(network::Socket* sock) {
   std::list<VNCSConnectionST*>::iterator ci;
   for (ci = clients.begin(); ci != clients.end(); ci++) {
     if ((*ci)->getSock() == sock)
index 54443e1f2cf7f72a01f8fb6731458bb2fed7c387..0fa2c87500dd989fe41c36a85beb3010323d0316 100644 (file)
@@ -99,6 +99,7 @@ namespace rfb {
     virtual void approveConnection(network::Socket* sock, bool accept,
                                    const char* reason);
     virtual void closeClients(const char* reason) {closeClients(reason, 0);}
+    virtual SConnection* getConnection(network::Socket* sock);
 
     virtual void add_changed(const Region &region);
     virtual void add_copied(const Region &dest, const Point &delta);
@@ -133,11 +134,6 @@ namespace rfb {
     // any), and logs the specified reason for closure.
     void closeClients(const char* reason, network::Socket* sock);
 
-    // getSConnection() gets the SConnection for a particular Socket.  If
-    // the Socket is not recognised then null is returned.
-
-    SConnection* getSConnection(network::Socket* sock);
-
     // queryConnection() is called when a connection has been
     // successfully authenticated.  The sock and userName arguments identify
     // the socket and the name of the authenticated user, if any.