diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 2aab195a..8b7d5b69 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -81,7 +81,8 @@ Client::Client( m_sendFileThread(NULL), m_writeToDropDirThread(NULL), m_enableDragDrop(enableDragDrop), - m_socket(NULL) + m_socket(NULL), + m_useSecureNetwork(false) { assert(m_socketFactory != NULL); assert(m_screen != NULL); @@ -155,13 +156,13 @@ Client::connect() } // create the socket - bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity); - IDataSocket* socket = m_socketFactory->create(useSecureSocket); + m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity); + IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork); m_socket = dynamic_cast(socket); // filter socket messages, including a packetizing filter m_stream = socket; - bool adopt = !useSecureSocket; + bool adopt = !m_useSecureNetwork; m_stream = new PacketStreamFilter(m_events, m_stream, adopt); if (m_crypto.m_mode != kDisabled) { @@ -570,10 +571,14 @@ Client::cleanupTimer() void Client::cleanupStream() { - bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity); - if (!useSecureSocket) { - delete m_stream; - m_stream = NULL; + delete m_stream; + m_stream = NULL; + + // PacketStreamFilter doen't adopt secure socket, because + // we need to tell the dynamic lib that allocated this object + // to do the deletion. + if (m_useSecureNetwork) { + ARCH->plugin().invoke(s_networkSecurity, "deleteSocket", NULL); } } diff --git a/src/lib/client/Client.h b/src/lib/client/Client.h index b0e23a79..be32999f 100644 --- a/src/lib/client/Client.h +++ b/src/lib/client/Client.h @@ -233,4 +233,5 @@ private: Thread* m_writeToDropDirThread; bool m_enableDragDrop; TCPSocket* m_socket; + bool m_useSecureNetwork; }; diff --git a/src/lib/io/StreamFilter.h b/src/lib/io/StreamFilter.h index 84a4cf54..f9986801 100644 --- a/src/lib/io/StreamFilter.h +++ b/src/lib/io/StreamFilter.h @@ -49,13 +49,13 @@ public: virtual bool isReady() const; virtual UInt32 getSize() const; -protected: //! Get the stream /*! Returns the stream passed to the c'tor. */ synergy::IStream* getStream() const; +protected: //! Handle events from source stream /*! Does the event filtering. The default simply dispatches an event diff --git a/src/lib/net/IListenSocket.h b/src/lib/net/IListenSocket.h index ab4fdeff..e6c98833 100644 --- a/src/lib/net/IListenSocket.h +++ b/src/lib/net/IListenSocket.h @@ -39,7 +39,15 @@ public: data stream. Returns NULL if no socket is waiting to be accepted. This is only valid after a call to \c bind(). */ - virtual IDataSocket* accept() = 0; + virtual IDataSocket* + accept() = 0; + + //! Delete connection socket + /*! + This is used when the socket was created but not adopted by a client + proxy. + */ + virtual void deleteSocket(void*) = 0; //@} diff --git a/src/lib/net/TCPListenSocket.h b/src/lib/net/TCPListenSocket.h index b81b38fb..ef2687db 100644 --- a/src/lib/net/TCPListenSocket.h +++ b/src/lib/net/TCPListenSocket.h @@ -43,8 +43,7 @@ public: // IListenSocket overrides virtual IDataSocket* accept(); - - ArchSocket& getSocket() { return m_socket; } + virtual void deleteSocket(void*) { } public: ISocketMultiplexerJob* diff --git a/src/lib/net/TCPSocketFactory.cpp b/src/lib/net/TCPSocketFactory.cpp index ea638cd3..b17eac5a 100644 --- a/src/lib/net/TCPSocketFactory.cpp +++ b/src/lib/net/TCPSocketFactory.cpp @@ -55,7 +55,7 @@ TCPSocketFactory::create(bool secure) const m_socketMultiplexer }; socket = static_cast( - ARCH->plugin().invoke(s_networkSecurity, "getSecureSocket", args)); + ARCH->plugin().invoke(s_networkSecurity, "getSocket", args)); } else { socket = new TCPSocket(m_events, m_socketMultiplexer); @@ -74,7 +74,7 @@ TCPSocketFactory::createListen(bool secure) const m_socketMultiplexer }; socket = static_cast( - ARCH->plugin().invoke(s_networkSecurity, "getSecureListenSocket", args)); + ARCH->plugin().invoke(s_networkSecurity, "getListenSocket", args)); } else { socket = new TCPListenSocket(m_events, m_socketMultiplexer); diff --git a/src/lib/plugin/ns/SecureListenSocket.cpp b/src/lib/plugin/ns/SecureListenSocket.cpp index 778a4c1e..b7c1f382 100644 --- a/src/lib/plugin/ns/SecureListenSocket.cpp +++ b/src/lib/plugin/ns/SecureListenSocket.cpp @@ -36,6 +36,11 @@ SecureListenSocket::SecureListenSocket( SecureListenSocket::~SecureListenSocket() { + SecureSocketSet::iterator it; + for (it = m_secureSocketSet.begin(); it != m_secureSocketSet.end(); it++) { + delete *it; + } + m_secureSocketSet.clear(); } IDataSocket* @@ -47,6 +52,9 @@ SecureListenSocket::accept() m_events, m_socketMultiplexer, ARCH->acceptSocket(m_socket, NULL)); + + m_secureSocketSet.insert(socket); + socket->initSsl(true); // TODO: customized certificate path socket->loadCertificates("C:\\Temp\\synergy.pem"); @@ -73,3 +81,14 @@ SecureListenSocket::accept() throw ex; } } + +void +SecureListenSocket::deleteSocket(void* socket) +{ + SecureSocketSet::iterator it; + it = m_secureSocketSet.find((IDataSocket*)socket); + if (it != m_secureSocketSet.end()) { + delete *it; + m_secureSocketSet.erase(it); + } +} diff --git a/src/lib/plugin/ns/SecureListenSocket.h b/src/lib/plugin/ns/SecureListenSocket.h index 4a4c1496..15166340 100644 --- a/src/lib/plugin/ns/SecureListenSocket.h +++ b/src/lib/plugin/ns/SecureListenSocket.h @@ -18,9 +18,11 @@ #pragma once #include "net/TCPListenSocket.h" +#include "common/stdset.h" class IEventQueue; class SocketMultiplexer; +class IDataSocket; class SecureListenSocket : public TCPListenSocket{ public: @@ -31,4 +33,10 @@ public: // IListenSocket overrides virtual IDataSocket* accept(); + void deleteSocket(void*); + +private: + typedef std::set SecureSocketSet; + + SecureSocketSet m_secureSocketSet; }; diff --git a/src/lib/plugin/ns/SecureSocket.cpp b/src/lib/plugin/ns/SecureSocket.cpp index 07c3a95f..14635511 100644 --- a/src/lib/plugin/ns/SecureSocket.cpp +++ b/src/lib/plugin/ns/SecureSocket.cpp @@ -68,21 +68,6 @@ SecureSocket::~SecureSocket() delete[] m_error; } -void -SecureSocket::close() -{ - if (m_ssl->m_ssl != NULL) { - SSL_free(m_ssl->m_ssl); - m_ssl->m_ssl = NULL; - } - - if (m_ssl->m_context != NULL) { - SSL_CTX_free(m_ssl->m_context); - m_ssl->m_context = NULL; - } - - TCPSocket::close(); -} void SecureSocket::secureConnect() diff --git a/src/lib/plugin/ns/SecureSocket.h b/src/lib/plugin/ns/SecureSocket.h index b46c6e52..42766265 100644 --- a/src/lib/plugin/ns/SecureSocket.h +++ b/src/lib/plugin/ns/SecureSocket.h @@ -42,9 +42,6 @@ public: ArchSocket socket); ~SecureSocket(); - // ISocket overrides - void close(); - void secureConnect(); void secureAccept(); bool isSecureReady(); diff --git a/src/lib/plugin/ns/ns.cpp b/src/lib/plugin/ns/ns.cpp index 4e492bb7..84e20b1e 100644 --- a/src/lib/plugin/ns/ns.cpp +++ b/src/lib/plugin/ns/ns.cpp @@ -59,7 +59,7 @@ invoke(const char* command, void** args) arg2 = reinterpret_cast(args[1]); } - if (strcmp(command, "getSecureSocket") == 0) { + if (strcmp(command, "getSocket") == 0) { if (g_secureSocket != NULL) { delete g_secureSocket; } @@ -67,16 +67,27 @@ invoke(const char* command, void** args) g_secureSocket->initSsl(false); return g_secureSocket; } - else if (strcmp(command, "getSecureListenSocket") == 0) { + else if (strcmp(command, "getListenSocket") == 0) { if (g_secureListenSocket != NULL) { delete g_secureListenSocket; } g_secureListenSocket = new SecureListenSocket(arg1, arg2); return g_secureListenSocket; } - else { - return NULL; + else if (strcmp(command, "deleteSocket") == 0) { + if (g_secureSocket != NULL) { + delete g_secureSocket; + g_secureSocket = NULL; + } } + else if (strcmp(command, "deleteListenSocket") == 0) { + if (g_secureListenSocket != NULL) { + delete g_secureListenSocket; + g_secureListenSocket = NULL; + } + } + + return NULL; } void diff --git a/src/lib/server/BaseClientProxy.h b/src/lib/server/BaseClientProxy.h index 55c9f1a5..1371d089 100644 --- a/src/lib/server/BaseClientProxy.h +++ b/src/lib/server/BaseClientProxy.h @@ -21,6 +21,8 @@ #include "synergy/IClient.h" #include "base/String.h" +namespace synergy { class IStream; } + //! Generic proxy for client or primary class BaseClientProxy : public IClient { public: @@ -82,6 +84,8 @@ public: size_t size) = 0; virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0; virtual String getName() const; + virtual synergy::IStream* + getStream() const = 0; private: String m_name; diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index 05171c97..601f3c32 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -54,8 +54,8 @@ ClientListener::ClientListener(const NetworkAddress& address, try { // create listen socket - m_useSecureSocket = ARCH->plugin().exists(s_networkSecurity); - m_listen = m_socketFactory->createListen(m_useSecureSocket); + m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity); + m_listen = m_socketFactory->createListen(m_useSecureNetwork); // bind listen address LOG((CLOG_DEBUG1 "binding listen socket")); @@ -115,6 +115,12 @@ ClientListener::setServer(Server* server) m_server = server; } +void +ClientListener::deleteSocket(void* socket) +{ + m_listen->deleteSocket(socket); +} + ClientProxy* ClientListener::getNextClient() { @@ -132,13 +138,16 @@ ClientListener::handleClientConnecting(const Event&, void*) { // accept client connection synergy::IStream* stream = m_listen->accept(); + if (stream == NULL) { return; } + LOG((CLOG_NOTE "accepted client connection")); // filter socket messages, including a packetizing filter - stream = new PacketStreamFilter(m_events, stream, true); + bool adopt = !m_useSecureNetwork; + stream = new PacketStreamFilter(m_events, stream, adopt); if (m_crypto.m_mode != kDisabled) { CryptoStream* cryptoStream = new CryptoStream( @@ -212,7 +221,13 @@ ClientListener::handleClientDisconnected(const Event&, void* vclient) void ClientListener::cleanupListenSocket() { - if (!m_useSecureSocket) { + if (!m_useSecureNetwork) { delete m_listen; } + else { + ARCH->plugin().invoke( + s_networkSecurity, + "deleteListenSocket", + NULL); + } } diff --git a/src/lib/server/ClientListener.h b/src/lib/server/ClientListener.h index afbb24aa..b92887aa 100644 --- a/src/lib/server/ClientListener.h +++ b/src/lib/server/ClientListener.h @@ -49,6 +49,8 @@ public: //@} + void deleteSocket(void* socket); + //! @name accessors //@{ @@ -84,5 +86,5 @@ private: Server* m_server; CryptoOptions m_crypto; IEventQueue* m_events; - bool m_useSecureSocket; + bool m_useSecureNetwork; }; diff --git a/src/lib/server/ClientProxy.h b/src/lib/server/ClientProxy.h index 1007ba58..1cadad25 100644 --- a/src/lib/server/ClientProxy.h +++ b/src/lib/server/ClientProxy.h @@ -52,7 +52,7 @@ public: Returns a crypto stream if the user has this enabled, otherwise returns the original stream passed to the c'tor. */ - synergy::IStream* getStream() const; + synergy::IStream* getStream() const; //@} diff --git a/src/lib/server/ClientProxyUnknown.h b/src/lib/server/ClientProxyUnknown.h index 060b0000..4d7b142d 100644 --- a/src/lib/server/ClientProxyUnknown.h +++ b/src/lib/server/ClientProxyUnknown.h @@ -63,6 +63,6 @@ private: EventQueueTimer* m_timer; ClientProxy* m_proxy; bool m_ready; - Server* m_server; + Server* m_server; IEventQueue* m_events; }; diff --git a/src/lib/server/PrimaryClient.h b/src/lib/server/PrimaryClient.h index f22f4464..b7c64a4f 100644 --- a/src/lib/server/PrimaryClient.h +++ b/src/lib/server/PrimaryClient.h @@ -146,6 +146,9 @@ public: virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size); virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize); + virtual synergy::IStream* + getStream() const { return NULL; } + private: synergy::Screen* m_screen; bool m_clipboardDirty[kClipboardEnd]; diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index c260583e..42367af4 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -21,6 +21,7 @@ #include "server/ClientProxy.h" #include "server/ClientProxyUnknown.h" #include "server/PrimaryClient.h" +#include "server/ClientListener.h" #include "synergy/IPlatformScreen.h" #include "synergy/DropHelper.h" #include "synergy/option_types.h" @@ -30,6 +31,8 @@ #include "synergy/FileChunker.h" #include "synergy/KeyState.h" #include "synergy/Screen.h" +#include "synergy/PacketStreamFilter.h" +#include "net/TCPSocket.h" #include "net/IDataSocket.h" #include "net/IListenSocket.h" #include "net/XSocket.h" @@ -1358,7 +1361,11 @@ Server::handleClientDisconnected(const Event&, void* vclient) BaseClientProxy* client = reinterpret_cast(vclient); removeActiveClient(client); removeOldClient(client); + + PacketStreamFilter* streamFileter = dynamic_cast(client->getStream()); + TCPSocket* socket = dynamic_cast(streamFileter->getStream()); delete client; + m_clientListener->deleteSocket(socket); } void diff --git a/src/lib/server/Server.h b/src/lib/server/Server.h index d1efccb6..f3302ae1 100644 --- a/src/lib/server/Server.h +++ b/src/lib/server/Server.h @@ -39,6 +39,7 @@ class InputFilter; namespace synergy { class Screen; } class IEventQueue; class Thread; +class ClientListener; //! Synergy server /*! @@ -154,6 +155,9 @@ public: //! Received dragging information from client void dragInfoReceived(UInt32 fileNum, String content); + + //! Store ClientListener pointer + void setListener(ClientListener* p) { m_clientListener = p; } //@} //! @name accessors @@ -412,7 +416,7 @@ private: SInt32 m_xDelta2, m_yDelta2; // current configuration - Config* m_config; + Config* m_config; // input filter (from m_config); InputFilter* m_inputFilter; @@ -458,7 +462,7 @@ private: bool m_lockedToScreen; // server screen - synergy::Screen* m_screen; + synergy::Screen* m_screen; IEventQueue* m_events; @@ -466,12 +470,14 @@ private: size_t m_expectedFileSize; String m_receivedFileData; DragFileList m_dragFileList; - Thread* m_sendFileThread; - Thread* m_writeToDropDirThread; + Thread* m_sendFileThread; + Thread* m_writeToDropDirThread; String m_dragFileExt; bool m_ignoreFileTransfer; bool m_enableDragDrop; - Thread* m_getDragInfoThread; + Thread* m_getDragInfoThread; bool m_waitDragInfoThread; + + ClientListener* m_clientListener; }; diff --git a/src/lib/synergy/ServerApp.cpp b/src/lib/synergy/ServerApp.cpp index fbd1949e..df9686f3 100644 --- a/src/lib/synergy/ServerApp.cpp +++ b/src/lib/synergy/ServerApp.cpp @@ -543,6 +543,7 @@ ServerApp::startServer() listener = openClientListener(args().m_config->getSynergyAddress()); m_server = openServer(*args().m_config, m_primaryClient); listener->setServer(m_server); + m_server->setListener(listener); m_listener = listener; updateStatus(); LOG((CLOG_NOTE "started server, waiting for clients"));