LCOV - code coverage report
Current view: top level - sd/source/ui/remotecontrol - Server.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 147 0.0 %
Date: 2014-04-14 Functions: 0 16 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : #include <stdlib.h>
      10             : #include <algorithm>
      11             : #include <vector>
      12             : 
      13             : #include <officecfg/Office/Common.hxx>
      14             : #include <officecfg/Office/Impress.hxx>
      15             : 
      16             : #include <com/sun/star/container/XNameAccess.hpp>
      17             : #include <com/sun/star/container/XNameContainer.hpp>
      18             : #include <com/sun/star/uno/Sequence.hxx>
      19             : 
      20             : #include <comphelper/processfactory.hxx>
      21             : #include <comphelper/configuration.hxx>
      22             : #include <sal/log.hxx>
      23             : 
      24             : #include "sddll.hxx"
      25             : 
      26             : #include "DiscoveryService.hxx"
      27             : #include "Listener.hxx"
      28             : #include "Receiver.hxx"
      29             : #include "RemoteServer.hxx"
      30             : #include "BluetoothServer.hxx"
      31             : #include "Communicator.hxx"
      32             : #include "BufferedStreamSocket.hxx"
      33             : 
      34             : using namespace std;
      35             : using namespace sd;
      36             : using namespace ::com::sun::star;
      37             : using namespace ::com::sun::star::uno;
      38             : using namespace ::com::sun::star::beans;
      39             : using namespace ::com::sun::star::container;
      40             : using namespace ::com::sun::star::lang;
      41             : using namespace ::osl;
      42             : using namespace ::comphelper;
      43             : 
      44             : namespace sd {
      45             :     /**
      46             :      * Used to keep track of clients that have attempted to connect, but haven't
      47             :      * yet been approved.
      48             :      */
      49             :     struct ClientInfoInternal:
      50             :         ClientInfo
      51             :     {
      52             :         BufferedStreamSocket *mpStreamSocket;
      53             :         OUString mPin;
      54             : 
      55           0 :         ClientInfoInternal( const OUString& rName,
      56             :                             const OUString& rAddress,
      57             :                             BufferedStreamSocket *pSocket,
      58             :                             const OUString& rPin ):
      59             :                 ClientInfo( rName, rAddress ),
      60             :                 mpStreamSocket( pSocket ),
      61           0 :                 mPin( rPin ) {}
      62             :     };
      63             : }
      64             : 
      65           0 : RemoteServer::RemoteServer() :
      66             :     Thread( "RemoteServerThread" ),
      67             :     mSocket(),
      68           0 :     mAvailableClients()
      69             : {
      70             :     SAL_INFO( "sdremote", "Instantiated RemoteServer" );
      71           0 : }
      72             : 
      73           0 : RemoteServer::~RemoteServer()
      74             : {
      75           0 : }
      76             : 
      77           0 : void RemoteServer::execute()
      78             : {
      79             :     SAL_INFO( "sdremote", "RemoteServer::execute called" );
      80           0 :     uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
      81           0 :     if (!xContext.is()/* || !officecfg::Office::Common::Misc::ExperimentalMode::get(xContext)*/)
      82             :     {
      83             :         // SAL_INFO("sdremote", "not in experimental mode, disabling TCP server");
      84           0 :         spServer = NULL;
      85           0 :         return;
      86             :     }
      87           0 :     osl::SocketAddr aAddr( "0", PORT );
      88           0 :     if ( !mSocket.bind( aAddr ) )
      89             :     {
      90             :         SAL_WARN( "sdremote", "bind failed" << mSocket.getErrorAsString() );
      91           0 :         spServer = NULL;
      92           0 :         return;
      93             :     }
      94             : 
      95           0 :     if ( !mSocket.listen(3) )
      96             :     {
      97             :         SAL_WARN( "sdremote", "listen failed" << mSocket.getErrorAsString() );
      98           0 :         spServer = NULL;
      99           0 :         return;
     100             :     }
     101             :     while ( true )
     102             :     {
     103           0 :         StreamSocket aSocket;
     104             :         SAL_INFO( "sdremote", "waiting on accept" );
     105           0 :         if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error )
     106             :         {
     107             :             SAL_WARN( "sdremote", "accept failed" << mSocket.getErrorAsString() );
     108           0 :             spServer = NULL;
     109           0 :             return; // Closed, or other issue.
     110             :         }
     111           0 :         BufferedStreamSocket *pSocket = new BufferedStreamSocket( aSocket);
     112           0 :         OString aLine;
     113           0 :         if ( pSocket->readLine( aLine)
     114           0 :             && aLine.equals( "LO_SERVER_CLIENT_PAIR" ) &&
     115           0 :             pSocket->readLine( aLine ) )
     116             :         {
     117           0 :             OString aName( aLine );
     118             : 
     119           0 :             if ( ! pSocket->readLine( aLine ) ) delete pSocket;
     120           0 :             OString aPin( aLine );
     121             : 
     122           0 :             SocketAddr aClientAddr;
     123           0 :             pSocket->getPeerAddr( aClientAddr );
     124           0 :             OUString aAddress = aClientAddr.getHostname();
     125             : 
     126           0 :             MutexGuard aGuard( sDataMutex );
     127             :             ClientInfoInternal* pClient = new ClientInfoInternal(
     128             :                     OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ),
     129             :                     aAddress, pSocket, OStringToOUString( aPin,
     130           0 :                     RTL_TEXTENCODING_UTF8 ) );
     131           0 :             mAvailableClients.push_back( pClient );
     132             : 
     133             :             // Read off any additional non-empty lines
     134             :             // We know that we at least have the empty termination line to read.
     135           0 :             do
     136             :             {
     137           0 :                 pSocket->readLine( aLine );
     138             :             }
     139           0 :             while ( aLine.getLength() > 0 );
     140             : 
     141             :             // Check if we already have this server.
     142           0 :             Reference< XNameAccess > const xConfig = officecfg::Office::Impress::Misc::AuthorisedRemotes::get();
     143           0 :             Sequence< OUString > aNames = xConfig->getElementNames();
     144           0 :             bool aFound = false;
     145           0 :             for ( int i = 0; i < aNames.getLength(); i++ )
     146             :             {
     147           0 :                 if ( aNames[i].equals( pClient->mName ) )
     148             :                 {
     149           0 :                     Reference<XNameAccess> xSetItem( xConfig->getByName(aNames[i]), UNO_QUERY );
     150           0 :                     Any axPin(xSetItem->getByName("PIN"));
     151           0 :                     OUString sPin;
     152           0 :                     axPin >>= sPin;
     153             : 
     154           0 :                     if ( sPin.equals( pClient->mPin ) ) {
     155             :                         SAL_INFO( "sdremote", "client found on validated list -- connecting" );
     156           0 :                         connectClient( pClient, sPin );
     157           0 :                         aFound = true;
     158           0 :                         break;
     159           0 :                     }
     160             :                 }
     161             : 
     162             :             }
     163             :             // Pin not found so inform the client.
     164           0 :             if ( !aFound )
     165             :             {
     166             :                 SAL_INFO( "sdremote", "client not found on validated list" );
     167             :                 pSocket->write( "LO_SERVER_VALIDATING_PIN\n\n",
     168           0 :                             strlen( "LO_SERVER_VALIDATING_PIN\n\n" ) );
     169           0 :             }
     170             :         } else {
     171             :             SAL_INFO( "sdremote", "client failed to send LO_SERVER_CLIENT_PAIR, ignoring" );
     172           0 :             delete pSocket;
     173             :         }
     174           0 :     }
     175             :     SAL_INFO( "sdremote", "shutting down RemoteServer" );
     176           0 :     spServer = NULL; // Object is destroyed when Thread::execute() ends.
     177             : }
     178             : 
     179             : RemoteServer *sd::RemoteServer::spServer = NULL;
     180           0 : ::osl::Mutex sd::RemoteServer::sDataMutex;
     181           0 : ::std::vector<Communicator*> sd::RemoteServer::sCommunicators;
     182             : 
     183           0 : void RemoteServer::setup()
     184             : {
     185           0 :     if (spServer)
     186           0 :         return;
     187             : 
     188           0 :     spServer = new RemoteServer();
     189           0 :     spServer->launch();
     190             : 
     191             : #ifdef ENABLE_SDREMOTE_BLUETOOTH
     192           0 :     sd::BluetoothServer::setup( &sCommunicators );
     193             : #endif
     194             : }
     195             : 
     196             : 
     197           0 : void RemoteServer::presentationStarted( const css::uno::Reference<
     198             :                 css::presentation::XSlideShowController > &rController )
     199             : {
     200           0 :     if ( !spServer )
     201           0 :         return;
     202           0 :     MutexGuard aGuard( sDataMutex );
     203           0 :     for ( vector<Communicator*>::const_iterator aIt = sCommunicators.begin();
     204           0 :          aIt != sCommunicators.end(); ++aIt )
     205             :     {
     206           0 :         (*aIt)->presentationStarted( rController );
     207           0 :     }
     208             : }
     209           0 : void RemoteServer::presentationStopped()
     210             : {
     211           0 :     if ( !spServer )
     212           0 :         return;
     213           0 :     MutexGuard aGuard( sDataMutex );
     214           0 :     for ( vector<Communicator*>::const_iterator aIt = sCommunicators.begin();
     215           0 :          aIt != sCommunicators.end(); ++aIt )
     216             :     {
     217           0 :         (*aIt)->disposeListener();
     218           0 :     }
     219             : }
     220             : 
     221           0 : void RemoteServer::removeCommunicator( Communicator* mCommunicator )
     222             : {
     223           0 :     if ( !spServer )
     224           0 :         return;
     225           0 :     MutexGuard aGuard( sDataMutex );
     226           0 :     for ( vector<Communicator*>::iterator aIt = sCommunicators.begin();
     227           0 :          aIt != sCommunicators.end(); ++aIt )
     228             :     {
     229           0 :         if ( mCommunicator == *aIt )
     230             :         {
     231           0 :             sCommunicators.erase( aIt );
     232           0 :             break;
     233             :         }
     234           0 :     }
     235             : }
     236             : 
     237           0 : std::vector<ClientInfo*> RemoteServer::getClients()
     238             : {
     239             :     SAL_INFO( "sdremote", "RemoteServer::getClients() called" );
     240           0 :     std::vector<ClientInfo*> aClients;
     241           0 :     if ( !spServer )
     242             :     {
     243             :         SAL_INFO( "sdremote", "No remote server instance => no clients" );
     244           0 :         return aClients;
     245             :     }
     246             : 
     247           0 :     MutexGuard aGuard( sDataMutex );
     248             :     aClients.assign( spServer->mAvailableClients.begin(),
     249           0 :                      spServer->mAvailableClients.end() );
     250           0 :     return aClients;
     251             : }
     252             : 
     253           0 : sal_Bool RemoteServer::connectClient( ClientInfo* pClient, const OUString& aPin )
     254             : {
     255             :     SAL_INFO( "sdremote", "RemoteServer::connectClient called" );
     256           0 :     if ( !spServer )
     257           0 :         return false;
     258             : 
     259           0 :     ClientInfoInternal *apClient = (ClientInfoInternal*) pClient;
     260           0 :     if ( apClient->mPin.equals( aPin ) )
     261             :     {
     262             :         // Save in settings first
     263           0 :         boost::shared_ptr< ConfigurationChanges > aChanges = ConfigurationChanges::create();
     264           0 :         Reference< XNameContainer > const xConfig = officecfg::Office::Impress::Misc::AuthorisedRemotes::get( aChanges );
     265             : 
     266             :         Reference<XSingleServiceFactory> xChildFactory (
     267           0 :             xConfig, UNO_QUERY);
     268           0 :         Reference<XNameReplace> xChild( xChildFactory->createInstance(), UNO_QUERY);
     269           0 :                 Any aValue;
     270           0 :         if (xChild.is())
     271             :         {
     272             :             // Check whether the client is already saved
     273           0 :             bool aSaved = false;
     274           0 :             Sequence< OUString > aNames = xConfig->getElementNames();
     275           0 :             for ( int i = 0; i < aNames.getLength(); i++ )
     276             :             {
     277           0 :                 if ( aNames[i].equals( apClient->mName ) )
     278             :                 {
     279           0 :                     xConfig->replaceByName( apClient->mName, makeAny( xChild ) );
     280           0 :                     aSaved = true;
     281           0 :                     break;
     282             :                 }
     283             :             }
     284           0 :             if ( !aSaved )
     285           0 :                 xConfig->insertByName( apClient->mName, makeAny( xChild ) );
     286           0 :             aValue <<= OUString( apClient->mPin );
     287           0 :             xChild->replaceByName("PIN", aValue);
     288           0 :             aChanges->commit();
     289             :         }
     290             : 
     291           0 :         Communicator* pCommunicator = new Communicator( apClient->mpStreamSocket );
     292           0 :         MutexGuard aGuard( sDataMutex );
     293             : 
     294           0 :         sCommunicators.push_back( pCommunicator );
     295             : 
     296           0 :         for ( vector<ClientInfoInternal*>::iterator aIt = spServer->mAvailableClients.begin();
     297           0 :             aIt != spServer->mAvailableClients.end(); ++aIt )
     298             :         {
     299           0 :             if ( pClient == *aIt )
     300             :             {
     301           0 :                 spServer->mAvailableClients.erase( aIt );
     302           0 :             break;
     303             :             }
     304             :         }
     305           0 :         pCommunicator->launch();
     306           0 :         return true;
     307             :     }
     308             :     else
     309             :     {
     310           0 :         return false;
     311             :     }
     312             : }
     313             : 
     314           0 : void SdDLL::RegisterRemotes()
     315             : {
     316             :     SAL_INFO( "sdremote", "SdDLL::RegisterRemotes called" );
     317           0 :     uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
     318           0 :     if ( xContext.is()  && !officecfg::Office::Impress::Misc::Start::EnableSdremote::get( xContext ) )
     319           0 :         return;
     320             : 
     321           0 :     sd::RemoteServer::setup();
     322           0 :     sd::DiscoveryService::setup();
     323             : }
     324             : 
     325           0 : void RemoteServer::ensureDiscoverable()
     326             : {
     327             :     // FIXME: we could also enable listening on our WiFi
     328             :     // socket here to significantly reduce the attack surface.
     329             : #ifdef ENABLE_SDREMOTE_BLUETOOTH
     330           0 :     BluetoothServer::ensureDiscoverable();
     331             : #endif
     332           0 : }
     333             : 
     334           0 : void RemoteServer::restoreDiscoverable()
     335             : {
     336             : #ifdef ENABLE_SDREMOTE_BLUETOOTH
     337           0 :     BluetoothServer::restoreDiscoverable();
     338             : #endif
     339           0 : }
     340             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10