diff options
-rw-r--r-- | common/rfb/VNCSConnectionST.cxx | 55 | ||||
-rw-r--r-- | common/rfb/VNCServerST.cxx | 78 | ||||
-rw-r--r-- | common/rfb/VNCServerST.h | 32 | ||||
-rw-r--r-- | unix/x0vncserver/XDesktop.cxx | 2 | ||||
-rw-r--r-- | win/winvnc/VNCServerService.cxx | 1 |
5 files changed, 98 insertions, 70 deletions
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index d9e276a9..50e6d88b 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -56,22 +56,18 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, { setStreams(&sock->inStream(), &sock->outStream()); peerEndpoint.buf = sock->getPeerEndpoint(); - VNCServerST::connectionsLog.write(1,"accepted: %s", peerEndpoint.buf); // Configure the socket setSocketTimeouts(); lastEventTime = time(0); - - server->clients.push_front(this); } VNCSConnectionST::~VNCSConnectionST() { // If we reach here then VNCServerST is deleting us! - VNCServerST::connectionsLog.write(1,"closed: %s (%s)", - peerEndpoint.buf, - (closeReason.buf) ? closeReason.buf : ""); + if (closeReason.buf) + vlog.info("closing %s: %s", peerEndpoint.buf, closeReason.buf); // Release any keys the client still had pressed while (!pressedKeys.empty()) { @@ -86,9 +82,6 @@ VNCSConnectionST::~VNCSConnectionST() server->keyEvent(keysym, keycode, false); } - // Remove this client from the server - server->clients.remove(this); - delete [] fenceData; } @@ -113,10 +106,6 @@ void VNCSConnectionST::close(const char* reason) else vlog.debug("second close: %s (%s)", peerEndpoint.buf, reason); - if (authenticated()) { - server->lastDisconnectTime = time(0); - } - // Just shutdown the socket and mark our state as closing. Eventually the // calling code will call VNCServerST's removeSocket() method causing us to // be deleted. @@ -445,30 +434,7 @@ void VNCSConnectionST::authSuccess() void VNCSConnectionST::queryConnection(const char* userName) { - // - Authentication succeeded - clear from blacklist - CharArray name; name.buf = sock->getPeerAddress(); - server->blHosts->clearBlackmark(name.buf); - - // - Prepare the desktop that we might be making calls - server->startDesktop(); - - // - Special case to provide a more useful error message - if (rfb::Server::neverShared && !rfb::Server::disconnectClients && - server->authClientCount() > 0) { - approveConnection(false, "The server is already in use"); - return; - } - - // - Does the client have the right to bypass the query? - if (!(rfb::Server::queryConnect || sock->requiresQuery()) || - accessCheck(AccessNoQuery)) - { - approveConnection(true); - return; - } - - // - Get the server to display an Accept/Reject dialog, if required - server->queryConnection(sock, userName); + server->queryConnection(this, userName); } void VNCSConnectionST::clientInit(bool shared) @@ -477,21 +443,8 @@ void VNCSConnectionST::clientInit(bool shared) if (rfb::Server::alwaysShared || reverseConnection) shared = true; if (!accessCheck(AccessNonShared)) shared = true; if (rfb::Server::neverShared) shared = false; - if (!shared) { - 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()); - } else { - // - Refuse this connection if there are existing clients, in addition to - // this one - if (server->authClientCount() > 1) { - close("Server is already in use"); - return; - } - } - } SConnection::clientInit(shared); + server->clientReady(this, shared); } void VNCSConnectionST::setPixelFormat(const PixelFormat& pf) diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 5e166119..e09e085f 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -54,6 +54,7 @@ #include <rfb/ComparingUpdateTracker.h> #include <rfb/KeyRemapper.h> #include <rfb/ListConnInfo.h> +#include <rfb/LogWriter.h> #include <rfb/Security.h> #include <rfb/ServerCore.h> #include <rfb/VNCServerST.h> @@ -66,7 +67,7 @@ using namespace rfb; static LogWriter slog("VNCServerST"); -LogWriter VNCServerST::connectionsLog("Connections"); +static LogWriter connectionsLog("Connections"); // // -=- VNCServerST Implementation @@ -99,9 +100,11 @@ VNCServerST::~VNCServerST() stopFrameClock(); // Delete all the clients, and their sockets, and any closing sockets - // NB: Deleting a client implicitly removes it from the clients list while (!clients.empty()) { - delete clients.front(); + VNCSConnectionST* client; + client = clients.front(); + clients.pop_front(); + delete client; } // Stop the desktop object if active, *only* after deleting all clients! @@ -134,11 +137,16 @@ void VNCServerST::addSocket(network::Socket* sock, bool outgoing) return; } + CharArray name; + name.buf = sock->getPeerEndpoint(); + connectionsLog.status("accepted: %s", name.buf); + if (clients.empty()) { lastConnectionTime = time(0); } VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing); + clients.push_front(client); client->init(); } @@ -147,13 +155,22 @@ void VNCServerST::removeSocket(network::Socket* sock) { std::list<VNCSConnectionST*>::iterator ci; for (ci = clients.begin(); ci != clients.end(); ci++) { if ((*ci)->getSock() == sock) { + clients.remove(*ci); + // - Release the cursor if this client owns it if (pointerClient == *ci) pointerClient = NULL; + if ((*ci)->authenticated()) + lastDisconnectTime = time(0); + // - Delete the per-Socket resources delete *ci; + CharArray name; + name.buf = sock->getPeerEndpoint(); + connectionsLog.status("closed: %s", name.buf); + // - Check that the desktop object is still required if (authClientCount() == 0) stopDesktop(); @@ -613,10 +630,61 @@ bool VNCServerST::handleTimeout(Timer* t) return false; } -void VNCServerST::queryConnection(network::Socket* sock, +void VNCServerST::queryConnection(VNCSConnectionST* client, const char* userName) { - desktop->queryConnection(sock, userName); + // - Authentication succeeded - clear from blacklist + CharArray name; + name.buf = client->getSock()->getPeerAddress(); + blHosts->clearBlackmark(name.buf); + + // - Prepare the desktop for that the client will start requiring + // resources after this + startDesktop(); + + // - Special case to provide a more useful error message + if (rfb::Server::neverShared && + !rfb::Server::disconnectClients && + authClientCount() > 0) { + approveConnection(client->getSock(), false, + "The server is already in use"); + return; + } + + // - Are we configured to do queries? + if (!rfb::Server::queryConnect && + !client->getSock()->requiresQuery()) { + approveConnection(client->getSock(), true, NULL); + return; + } + + // - Does the client have the right to bypass the query? + if (client->accessCheck(SConnection::AccessNoQuery)) + { + approveConnection(client->getSock(), true, NULL); + return; + } + + desktop->queryConnection(client->getSock(), userName); +} + +void VNCServerST::clientReady(VNCSConnectionST* client, bool shared) +{ + if (!shared) { + if (rfb::Server::disconnectClients && + client->accessCheck(SConnection::AccessNonShared)) { + // - Close all the other connected clients + slog.debug("non-shared connection - closing clients"); + closeClients("Non-shared connection requested", client->getSock()); + } else { + // - Refuse this connection if there are existing clients, in addition to + // this one + if (authClientCount() > 1) { + client->close("Server is already in use"); + return; + } + } + } } // -=- Internal methods diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 0fa2c875..52b22893 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -28,7 +28,6 @@ #include <rfb/SDesktop.h> #include <rfb/VNCServer.h> -#include <rfb/LogWriter.h> #include <rfb/Blacklist.h> #include <rfb/Cursor.h> #include <rfb/Timer.h> @@ -134,13 +133,9 @@ namespace rfb { // any), and logs the specified reason for closure. void closeClients(const char* reason, 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. - // approveConnection() must be called some time later to accept or reject - // the connection. - virtual void queryConnection(network::Socket* sock, - const char* userName); + // queryConnection() does some basic checks and then passes on the + // request to the desktop. + void queryConnection(VNCSConnectionST* client, const char* userName); // setBlacklist() is called to replace the VNCServerST's internal // Blacklist instance with another instance. This allows a single @@ -157,9 +152,22 @@ namespace rfb { bool getDisable() { return disableclients;}; void setDisable(bool disable) { disableclients = disable;}; - protected: + // clientReady() is called by a VNCSConnectionST instance when the + // client has completed the handshake and is ready for normal + // communication. + void clientReady(VNCSConnectionST* client, bool shared); + + // Estimated time until the next time new updates will be pushed + // to clients + int msToNextUpdate(); - friend class VNCSConnectionST; + // Part of the framebuffer that has been modified but is not yet + // ready to be sent to clients + Region getPendingRegion(); + + const RenderedCursor* getRenderedCursor(); + + protected: // Timer callbacks virtual bool handleTimeout(Timer* t); @@ -169,7 +177,6 @@ namespace rfb { void startDesktop(); void stopDesktop(); - static LogWriter connectionsLog; Blacklist blacklist; Blacklist* blHosts; @@ -199,10 +206,7 @@ namespace rfb { bool needRenderedCursor(); void startFrameClock(); void stopFrameClock(); - int msToNextUpdate(); void writeUpdate(); - Region getPendingRegion(); - const RenderedCursor* getRenderedCursor(); bool getComparerState(); diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx index c7f8ef8d..62a18a09 100644 --- a/unix/x0vncserver/XDesktop.cxx +++ b/unix/x0vncserver/XDesktop.cxx @@ -20,6 +20,8 @@ #include <assert.h> +#include <rfb/LogWriter.h> + #include <x0vncserver/XDesktop.h> #include <X11/XKBlib.h> diff --git a/win/winvnc/VNCServerService.cxx b/win/winvnc/VNCServerService.cxx index 5656de04..f5a4dba2 100644 --- a/win/winvnc/VNCServerService.cxx +++ b/win/winvnc/VNCServerService.cxx @@ -19,6 +19,7 @@ // -=- WinVNC Version 4.0 Service-Mode implementation #include <winvnc/VNCServerService.h> +#include <rfb/LogWriter.h> #include <rfb_win32/TsSessions.h> #include <rfb_win32/ModuleFileName.h> #include <windows.h> |