diff options
author | Pierre Ossman <ossman@cendio.se> | 2018-11-09 17:21:35 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2018-11-09 17:21:35 +0100 |
commit | f9de17665a3549e7e1eb44584ce73d6cafbd4c99 (patch) | |
tree | 9b8db530dac34858f202cd9c3bc1479faa221725 /win | |
parent | 42d0f5dd74fa0fe3bf3f26a92ecc5846db17895b (diff) | |
parent | 7e1093e976dbadfebcce893b943f6b52e1d4f8d5 (diff) | |
download | tigervnc-f9de17665a3549e7e1eb44584ce73d6cafbd4c99.tar.gz tigervnc-f9de17665a3549e7e1eb44584ce73d6cafbd4c99.zip |
Merge branch 'vncserver' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'win')
-rw-r--r-- | win/rfb_win32/SDisplay.cxx | 18 | ||||
-rw-r--r-- | win/rfb_win32/SDisplay.h | 18 | ||||
-rw-r--r-- | win/rfb_win32/SocketManager.cxx | 29 | ||||
-rw-r--r-- | win/rfb_win32/SocketManager.h | 4 | ||||
-rw-r--r-- | win/winvnc/ControlPanel.cxx | 13 | ||||
-rw-r--r-- | win/winvnc/ControlPanel.h | 12 | ||||
-rw-r--r-- | win/winvnc/ListConnInfo.h | 119 | ||||
-rw-r--r-- | win/winvnc/STrayIcon.cxx | 4 | ||||
-rw-r--r-- | win/winvnc/VNCServerService.cxx | 1 | ||||
-rw-r--r-- | win/winvnc/VNCServerWin32.cxx | 108 | ||||
-rw-r--r-- | win/winvnc/VNCServerWin32.h | 17 |
11 files changed, 304 insertions, 39 deletions
diff --git a/win/rfb_win32/SDisplay.cxx b/win/rfb_win32/SDisplay.cxx index 9b2cbb02..afb72ad7 100644 --- a/win/rfb_win32/SDisplay.cxx +++ b/win/rfb_win32/SDisplay.cxx @@ -20,6 +20,8 @@ // // The SDisplay class encapsulates a particular system display. +#include <assert.h> + #include <rfb_win32/SDisplay.h> #include <rfb_win32/Service.h> #include <rfb_win32/TsSessions.h> @@ -66,7 +68,7 @@ SDisplay::SDisplay() : server(0), pb(0), device(0), core(0), ptr(0), kbd(0), clipboard(0), inputs(0), monitor(0), cleanDesktop(0), cursor(0), - statusLocation(0), ledState(0) + statusLocation(0), queryConnectionHandler(0), ledState(0) { updateEvent.h = CreateEvent(0, TRUE, FALSE, 0); } @@ -139,6 +141,20 @@ void SDisplay::stop() } +void SDisplay::queryConnection(network::Socket* sock, + const char* userName) +{ + assert(server != NULL); + + if (queryConnectionHandler) { + queryConnectionHandler->queryConnection(sock, userName); + return; + } + + server->approveConnection(sock, true); +} + + void SDisplay::startCore() { // Currently, we just check whether we're in the console session, and diff --git a/win/rfb_win32/SDisplay.h b/win/rfb_win32/SDisplay.h index c1d5c1e2..76ddf50b 100644 --- a/win/rfb_win32/SDisplay.h +++ b/win/rfb_win32/SDisplay.h @@ -52,6 +52,13 @@ namespace rfb { virtual const char* methodName() const = 0; }; + class QueryConnectionHandler { + public: + virtual ~QueryConnectionHandler() {} + virtual void queryConnection(network::Socket* sock, + const char* userName) = 0; + }; + class SDisplay : public SDesktop, WMMonitor::Notifier, Clipboard::Notifier, @@ -65,6 +72,8 @@ namespace rfb { virtual void start(VNCServer* vs); virtual void stop(); + virtual void queryConnection(network::Socket* sock, + const char* userName); virtual void pointerEvent(const Point& pos, int buttonmask); virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); virtual void clientCutText(const char* str, int len); @@ -86,6 +95,12 @@ namespace rfb { void setStatusLocation(bool* status) {statusLocation = status;} + // -=- Set handler for incoming connections + + void setQueryConnectionHandler(QueryConnectionHandler* qch) { + queryConnectionHandler = qch; + } + static IntParameter updateMethod; static BoolParameter disableLocalInputs; static StringParameter disconnectAction; @@ -150,6 +165,9 @@ namespace rfb { // -=- Where to write the active/inactive indicator to bool* statusLocation; + // -=- Whom to query incoming connections + QueryConnectionHandler* queryConnectionHandler; + unsigned ledState; }; diff --git a/win/rfb_win32/SocketManager.cxx b/win/rfb_win32/SocketManager.cxx index 5b211a0d..aa469e53 100644 --- a/win/rfb_win32/SocketManager.cxx +++ b/win/rfb_win32/SocketManager.cxx @@ -78,6 +78,7 @@ void SocketManager::addListener(network::SocketListener* sock_, li.sock = sock_; li.server = srvr; li.notifier = acn; + li.disable = false; listeners[event] = li; } @@ -128,6 +129,32 @@ void SocketManager::remSocket(network::Socket* sock_) { throw rdr::Exception("Socket not registered"); } +bool SocketManager::getDisable(network::SocketServer* srvr) +{ + std::map<HANDLE,ListenInfo>::iterator i; + for (i=listeners.begin(); i!=listeners.end(); i++) { + if (i->second.server == srvr) { + return i->second.disable; + } + } + throw rdr::Exception("Listener not registered"); +} + +void SocketManager::setDisable(network::SocketServer* srvr, bool disable) +{ + bool found = false; + std::map<HANDLE,ListenInfo>::iterator i; + for (i=listeners.begin(); i!=listeners.end(); i++) { + if (i->second.server == srvr) { + i->second.disable = disable; + // There might be multiple sockets for the same server, so + // continue iterating + found = true; + } + } + if (!found) + throw rdr::Exception("Listener not registered"); +} int SocketManager::checkTimeouts() { int timeout = EventManager::checkTimeouts(); @@ -164,7 +191,7 @@ void SocketManager::processEvent(HANDLE event) { WSAEnumNetworkEvents(li.sock->getFd(), event, &network_events); if (network_events.lNetworkEvents & FD_ACCEPT) { network::Socket* new_sock = li.sock->accept(); - if (new_sock && li.server->getDisable()) { + if (new_sock && li.disable) { delete new_sock; new_sock = 0; } diff --git a/win/rfb_win32/SocketManager.h b/win/rfb_win32/SocketManager.h index c3c8fafd..e5ca02e6 100644 --- a/win/rfb_win32/SocketManager.h +++ b/win/rfb_win32/SocketManager.h @@ -65,6 +65,9 @@ namespace rfb { // the SocketServer. void addSocket(network::Socket* sock_, network::SocketServer* srvr, bool outgoing=true); + bool getDisable(network::SocketServer* srvr); + void setDisable(network::SocketServer* srvr, bool disable); + protected: virtual int checkTimeouts(); virtual void processEvent(HANDLE event); @@ -78,6 +81,7 @@ namespace rfb { network::SocketListener* sock; network::SocketServer* server; AddressChangeNotifier* notifier; + bool disable; }; std::map<HANDLE, ListenInfo> listeners; std::map<HANDLE, ConnInfo> connections; diff --git a/win/winvnc/ControlPanel.cxx b/win/winvnc/ControlPanel.cxx index ba6cab2c..72831e55 100644 --- a/win/winvnc/ControlPanel.cxx +++ b/win/winvnc/ControlPanel.cxx @@ -19,10 +19,9 @@ void ControlPanel::initDialog() { TCHAR *ColumnsStrings[] = { (TCHAR *) "IP address", - (TCHAR *) "Time connected", (TCHAR *) "Status" }; - InitLVColumns(IDC_LIST_CONNECTIONS, handle, 120, 3, ColumnsStrings, + InitLVColumns(IDC_LIST_CONNECTIONS, handle, 120, 2, ColumnsStrings, LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM, LVS_EX_FULLROWSELECT, LVCFMT_LEFT); SendCommand(4, -1); @@ -74,7 +73,7 @@ bool ControlPanel::onCommand(int cmd) } -void ControlPanel::UpdateListView(rfb::ListConnInfo* LCInfo) +void ControlPanel::UpdateListView(ListConnInfo* LCInfo) { getSelConnInfo(); DeleteAllLVItem(IDC_LIST_CONNECTIONS, handle); @@ -85,12 +84,12 @@ void ControlPanel::UpdateListView(rfb::ListConnInfo* LCInfo) ListConn.Copy(LCInfo); - char* ItemString[3]; + char* ItemString[2]; int i = 0; for (ListConn.iBegin(); !ListConn.iEnd(); ListConn.iNext()) { ListConn.iGetCharInfo(ItemString); - InsertLVItem(IDC_LIST_CONNECTIONS, handle, i, (TCHAR **) ItemString, 3); + InsertLVItem(IDC_LIST_CONNECTIONS, handle, i, (TCHAR **) ItemString, 2); for (ListSelConn.iBegin(); !ListSelConn.iEnd(); ListSelConn.iNext()) { if (ListSelConn.iGetConn() == ListConn.iGetConn()) SelectLVItem(IDC_LIST_CONNECTIONS, handle, i); @@ -141,6 +140,8 @@ void ControlPanel::SendCommand(DWORD command, int data) { COPYDATASTRUCT copyData; copyData.dwData = command; + copyData.cbData = 0; + copyData.lpData = 0; getSelConnInfo(); if (data != -1) { ListConnStatus.Copy(&ListSelConn); @@ -149,8 +150,6 @@ void ControlPanel::SendCommand(DWORD command, int data) } else { ListConnStatus.Clear(); } - copyData.cbData = 0; - copyData.lpData = &ListConnStatus; SendMessage(m_hSTIcon, WM_COPYDATA, 0, (LPARAM)©Data); } diff --git a/win/winvnc/ControlPanel.h b/win/winvnc/ControlPanel.h index 73b859f8..f64a6081 100644 --- a/win/winvnc/ControlPanel.h +++ b/win/winvnc/ControlPanel.h @@ -11,10 +11,10 @@ #include <list> #include <winvnc/resource.h> +#include <winvnc/ListConnInfo.h> #include <rfb_win32/Dialog.h> #include <rfb_win32/ListViewControl.h> #include <rfb_win32/Win32Util.h> -#include <rfb/ListConnInfo.h> namespace winvnc { @@ -27,19 +27,19 @@ namespace winvnc { virtual bool showDialog(); virtual void initDialog(); virtual bool onCommand(int cmd); - void UpdateListView(rfb::ListConnInfo* LCInfo); + void UpdateListView(ListConnInfo* LCInfo); HWND GetHandle() {return handle;}; void SendCommand(DWORD command, int data); ~ControlPanel(); - rfb::ListConnInfo ListConnStatus; + ListConnInfo ListConnStatus; protected: virtual BOOL dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void getSelConnInfo(); HWND m_hSTIcon; - rfb::ListConnInfo ListConn; - rfb::ListConnInfo ListSelConn; + ListConnInfo ListConn; + ListConnInfo ListSelConn; bool stop_updating; }; }; -#endif
\ No newline at end of file +#endif diff --git a/win/winvnc/ListConnInfo.h b/win/winvnc/ListConnInfo.h new file mode 100644 index 00000000..6ca5b7c7 --- /dev/null +++ b/win/winvnc/ListConnInfo.h @@ -0,0 +1,119 @@ +/* Copyright (C) 2002-2003 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_LISTCONNINFO_INCLUDED__ +#define __RFB_LISTCONNINFO_INCLUDED__ + +#include <list> + +#include <rfb/util.h> + +namespace winvnc { + + struct ListConnInfo { + ListConnInfo() : disableClients(false) {} + + void Clear() { + conn.clear(); + IP_address.clear(); + status.clear(); + } + + bool Empty() { return conn.empty();} + + void iBegin() { + ci = conn.begin(); + Ii = IP_address.begin(); + si = status.begin(); + } + + bool iEnd() { return ci == conn.end();} + + void iNext() { + ci++; + Ii++; + si++; + } + + void addInfo(void* Conn, char* IP, int Status) { + conn.push_back(Conn); + IP_address.push_back(rfb::strDup(IP)); + status.push_back(Status); + } + + void iGetCharInfo(char* buf[2]) { + buf[0] = *Ii; + switch (*si) { + case 0: + buf[1] = rfb::strDup("Full control"); + break; + case 1: + buf[1] = rfb::strDup("View only"); + break; + case 2: + buf[1] = rfb::strDup("Stop updating"); + break; + default: + buf[1] = rfb::strDup("Unknown"); + } + } + + void* iGetConn() { return *ci;} + + int iGetStatus() { return *si;} + + void iSetStatus(int istatus) { *si = istatus;} + + void Copy(ListConnInfo* InputList) { + Clear(); + if (InputList->Empty()) return; + for (InputList->iBegin(); !InputList->iEnd(); InputList->iNext()) { + iAdd(InputList); + } + setDisable(InputList->getDisable()); + } + + void iAdd (ListConnInfo* InputList) { + char* buf[2]; + InputList->iGetCharInfo(buf); + addInfo(InputList->iGetConn(), buf[0], InputList->iGetStatus()); + } + + void setDisable(bool disable) {disableClients = disable;} + + bool getDisable() {return disableClients;} + + void setAllStatus(int stat) { + std::list<int>::iterator st; + for (st = status.begin(); st != status.end(); st++) + *st = stat; + } + + private: + std::list<void*> conn; + std::list<char*> IP_address; + std::list<int> status; + std::list<void*>::iterator ci; + std::list<char*>::iterator Ii; + std::list<int>::iterator si; + bool disableClients; + }; +}; +#endif + diff --git a/win/winvnc/STrayIcon.cxx b/win/winvnc/STrayIcon.cxx index 05a38d6e..a90819d0 100644 --- a/win/winvnc/STrayIcon.cxx +++ b/win/winvnc/STrayIcon.cxx @@ -184,7 +184,7 @@ public: case 2: return thread.server.disconnectClients("IPC disconnect") ? 1 : 0; case 3: - thread.server.setClientsStatus((rfb::ListConnInfo *)command->lpData); + thread.server.setClientsStatus(&CPanel->ListConnStatus); case 4: thread.server.getClientsInfo(&LCInfo); CPanel->UpdateListView(&LCInfo); @@ -230,7 +230,7 @@ protected: LaunchProcess vncConnect; STrayIconThread& thread; ControlPanel * CPanel; - rfb::ListConnInfo LCInfo; + ListConnInfo LCInfo; }; 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> diff --git a/win/winvnc/VNCServerWin32.cxx b/win/winvnc/VNCServerWin32.cxx index 9f6a954d..03b1bca7 100644 --- a/win/winvnc/VNCServerWin32.cxx +++ b/win/winvnc/VNCServerWin32.cxx @@ -20,6 +20,7 @@ #include <winvnc/VNCServerWin32.h> #include <winvnc/resource.h> +#include <winvnc/ListConnInfo.h> #include <winvnc/STrayIcon.h> #include <os/Mutex.h> @@ -71,9 +72,7 @@ VNCServerWin32::VNCServerWin32() // Initialise the desktop desktop.setStatusLocation(&isDesktopStarted); - - // Initialise the VNC server - vncServer.setQueryConnectionHandler(this); + desktop.setQueryConnectionHandler(this); // Register the desktop's event to be handled sockMgr.addEvent(desktop.getUpdateEvent(), &desktop); @@ -241,27 +240,27 @@ bool VNCServerWin32::addNewClient(const char* client) { return false; } -bool VNCServerWin32::getClientsInfo(rfb::ListConnInfo* LCInfo) { +bool VNCServerWin32::getClientsInfo(ListConnInfo* LCInfo) { return queueCommand(GetClientsInfo, LCInfo, 0); } -bool VNCServerWin32::setClientsStatus(rfb::ListConnInfo* LCInfo) { +bool VNCServerWin32::setClientsStatus(ListConnInfo* LCInfo) { return queueCommand(SetClientsStatus, LCInfo, 0); } -VNCServerST::queryResult VNCServerWin32::queryConnection(network::Socket* sock, - const char* userName, - char** reason) +void VNCServerWin32::queryConnection(network::Socket* sock, + const char* userName) { - if (queryOnlyIfLoggedOn && CurrentUserToken().noUserLoggedOn()) - return VNCServerST::ACCEPT; + if (queryOnlyIfLoggedOn && CurrentUserToken().noUserLoggedOn()) { + vncServer.approveConnection(sock, true, NULL); + return; + } if (queryConnectDialog) { - *reason = rfb::strDup("Another connection is currently being queried."); - return VNCServerST::REJECT; + vncServer.approveConnection(sock, false, "Another connection is currently being queried."); + return; } queryConnectDialog = new QueryConnectDialog(sock, userName, this); queryConnectDialog->startDialog(); - return VNCServerST::PENDING; } void VNCServerWin32::queryConnectionComplete() { @@ -309,10 +308,10 @@ void VNCServerWin32::processEvent(HANDLE event_) { sockMgr.addSocket((network::Socket*)commandData, &vncServer); break; case GetClientsInfo: - vncServer.getConnInfo((ListConnInfo*)commandData); + getConnInfo((ListConnInfo*)commandData); break; case SetClientsStatus: - vncServer.setConnStatus((ListConnInfo*)commandData); + setConnStatus((ListConnInfo*)commandData); break; case QueryConnectionComplete: @@ -341,3 +340,82 @@ void VNCServerWin32::processEvent(HANDLE event_) { } } +void VNCServerWin32::getConnInfo(ListConnInfo * listConn) +{ + std::list<network::Socket*> sockets; + std::list<network::Socket*>::iterator i; + + listConn->Clear(); + listConn->setDisable(sockMgr.getDisable(&vncServer)); + + vncServer.getSockets(&sockets); + + for (i = sockets.begin(); i != sockets.end(); i++) { + rfb::SConnection* conn; + int status; + + conn = vncServer.getConnection(*i); + if (!conn) + continue; + + if (conn->accessCheck(rfb::SConnection::AccessPtrEvents | + rfb::SConnection::AccessKeyEvents | + rfb::SConnection::AccessView)) + status = 0; + else if (conn->accessCheck(rfb::SConnection::AccessView)) + status = 1; + else + status = 2; + + listConn->addInfo((void*)(*i), (*i)->getPeerAddress(), status); + } +} + +void VNCServerWin32::setConnStatus(ListConnInfo* listConn) +{ + sockMgr.setDisable(&vncServer, listConn->getDisable()); + + if (listConn->Empty()) + return; + + for (listConn->iBegin(); !listConn->iEnd(); listConn->iNext()) { + network::Socket* sock; + rfb::SConnection* conn; + int status; + + sock = (network::Socket*)listConn->iGetConn(); + + conn = vncServer.getConnection(sock); + if (!conn) + continue; + + status = listConn->iGetStatus(); + if (status == 3) { + conn->close(0); + } else { + rfb::SConnection::AccessRights ar; + + ar = rfb::SConnection::AccessDefault; + + switch (status) { + case 0: + ar |= rfb::SConnection::AccessPtrEvents | + rfb::SConnection::AccessKeyEvents | + rfb::SConnection::AccessView; + break; + case 1: + ar |= rfb::SConnection::AccessView; + ar &= ~(rfb::SConnection::AccessPtrEvents | + rfb::SConnection::AccessKeyEvents); + break; + case 2: + ar &= ~(rfb::SConnection::AccessPtrEvents | + rfb::SConnection::AccessKeyEvents | + rfb::SConnection::AccessView); + break; + } + conn->setAccessRights(ar); + conn->framebufferUpdateRequest(vncServer.getPixelBuffer()->getRect(), false); + } + } +} diff --git a/win/winvnc/VNCServerWin32.h b/win/winvnc/VNCServerWin32.h index 271cb76a..1a737823 100644 --- a/win/winvnc/VNCServerWin32.h +++ b/win/winvnc/VNCServerWin32.h @@ -37,9 +37,10 @@ namespace os { namespace winvnc { + class ListConnInfo; class STrayIconThread; - class VNCServerWin32 : rfb::VNCServerST::QueryConnectionHandler, + class VNCServerWin32 : rfb::win32::QueryConnectionHandler, rfb::win32::SocketManager::AddressChangeNotifier, rfb::win32::RegConfig::Callback, rfb::win32::EventHandler { @@ -73,17 +74,16 @@ namespace winvnc { // Where to read the configuration settings from static const TCHAR* RegConfigPath; - bool getClientsInfo(rfb::ListConnInfo* LCInfo); + bool getClientsInfo(ListConnInfo* LCInfo); - bool setClientsStatus(rfb::ListConnInfo* LCInfo); + bool setClientsStatus(ListConnInfo* LCInfo); protected: - // VNCServerST::QueryConnectionHandler interface + // QueryConnectionHandler interface // Callback used to prompt user to accept or reject a connection. // CALLBACK IN VNCServerST "HOST" THREAD - virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock, - const char* userName, - char** reason); + virtual void queryConnection(network::Socket* sock, + const char* userName); // SocketManager::AddressChangeNotifier interface // Used to keep tray icon up to date @@ -97,6 +97,9 @@ namespace winvnc { // Used to perform queued commands virtual void processEvent(HANDLE event); + void getConnInfo(ListConnInfo * listConn); + void setConnStatus(ListConnInfo* listConn); + protected: // Perform a particular internal function in the server thread typedef enum {NoCommand, DisconnectClients, AddClient, QueryConnectionComplete, SetClientsStatus, GetClientsInfo} Command; |