This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2goclient. commit 539e0a4268df3d78f88f6908506c18222743d84f Author: Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> Date: Tue Aug 21 15:42:52 2018 +0200 Add new brocker feature. Broker can send to client some configuration in the section START_CLIENT_CONFIG - END_CLIENT_CONFIG. For the moment is supported option events=bool. If true, client sending to broker events: CONNECTING, CONNECTED, SUSPENDING, TERMINATING, FINISHED. It's not a real session state, but rather the state of X2Go Client. --- debian/changelog | 5 +++ src/httpbrokerclient.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ src/httpbrokerclient.h | 5 +++ src/onmainwindow.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++----- src/onmainwindow.h | 15 ++++++++- 5 files changed, 187 insertions(+), 10 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5e22cd3..b0c0449 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,11 @@ x2goclient (4.1.2.2-0x2go1) UNRELEASED; urgency=medium [ Oleksandr Shneyder ] * New upstream version (4.1.2.2): - Add SSH instruction to list of errors if keyboard-interactive auth has failed. + - Add new brocker feature. Broker can send to client some configuration in + the section START_CLIENT_CONFIG - END_CLIENT_CONFIG. For the moment is supported + option events=bool. If true, client sending to broker events: CONNECTING, + CONNECTED, SUSPENDING, TERMINATING, FINISHED. It's not a real session state, + but rather the state of X2Go Client. [ Mihai Moldovan ] * New upstream version (4.1.2.2): diff --git a/src/httpbrokerclient.cpp b/src/httpbrokerclient.cpp index f7fbaf1..ea5158e 100644 --- a/src/httpbrokerclient.cpp +++ b/src/httpbrokerclient.cpp @@ -270,6 +270,7 @@ void HttpBrokerClient::slotSshUserAuthError(QString error) return; } + void HttpBrokerClient::getUserSessions() { QString brokerUser=config->brokerUser; @@ -347,6 +348,66 @@ void HttpBrokerClient::selectUserSession(const QString& session) } +void HttpBrokerClient::sendEvent(const QString& ev, const QString& id, const QString& server, const QString& client, const QString& login, const QString& cmd, const QString& display, const QString& start) +{ + x2goDebug<<"Called sendEvent."; + QString brokerUser=config->brokerUser; + if(mainWindow->getUsePGPCard()) + brokerUser=mainWindow->getCardLogin(); + + if(!sshBroker) + { + QString req; + QTextStream ( &req ) << + "task=clientevent&"<< + "user="<<QUrl::toPercentEncoding(brokerUser)<<"&"<< + "sid="<<id<<"&"<< + "event="<<ev<<"&"<< + "server="<<QUrl::toPercentEncoding(server)<<"&"<< + "client="<<QUrl::toPercentEncoding(client)<<"&"<< + "login="<<QUrl::toPercentEncoding(login)<<"&"<< + "cmd="<<QUrl::toPercentEncoding(cmd)<<"&"<< + "display="<<QUrl::toPercentEncoding(display)<<"&"<< + "start="<<QUrl::toPercentEncoding(start)<<"&"<< + "authid="<<nextAuthId; + x2goDebug << "Sending request: "<< req.toUtf8(); + QNetworkRequest request(QUrl(config->brokerurl)); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + eventRequest=http->post (request, req.toUtf8() ); + + } + else + { + if (nextAuthId.length() > 0) { + sshConnection->executeCommand ( config->sshBrokerBin+" --user "+ brokerUser +" --authid "+nextAuthId+ + " --task clientevent --sid \""+id+"\" --event "+ev+" --server \""+server+"\" --client \""+client+"\" --login "+"\""+ + login+"\" --cmd \""+cmd+"\" --display \""+display+"\" --start \""+start+"\"", + this,SLOT ( slotEventSent(bool,QString,int))); + } else { + sshConnection->executeCommand ( config->sshBrokerBin+" --user "+ brokerUser + + " --task clientevent --sid \""+id+"\" --event "+ev+" --server \""+server+"\" --client \""+client+"\" --login "+"\""+ + login+"\" --cmd \""+cmd+"\" --display\" "+display+" \" --start \""+start+"\"", + this,SLOT ( slotEventSent(bool,QString,int))); + } + } +} + + +void HttpBrokerClient::slotEventSent(bool success, QString answer, int) +{ + if(!success) + { + x2goDebug<<answer; + QMessageBox::critical(0,tr("Error"),answer); + emit fatalHttpError(); + return; + } + if(!checkAccess(answer)) + return; + x2goDebug<<"event sent:"<<answer; +} + + void HttpBrokerClient::changePassword(QString newPass) { newBrokerPass=newPass; @@ -405,6 +466,16 @@ void HttpBrokerClient::testConnection() } } +void HttpBrokerClient::processClientConfig(const QString& raw_content) +{ + X2goSettings st(raw_content, QSettings::IniFormat); + mainWindow->config.brokerEvents=st.setting()->value("events",false).toBool(); + if(mainWindow->config.brokerEvents) + { + x2goDebug<<"sending client events to broker"; + } +} + void HttpBrokerClient::createIniFile(const QString& raw_content) { @@ -420,6 +491,17 @@ void HttpBrokerClient::createIniFile(const QString& raw_content) cont=cont.split("END_USER_SESSIONS\n")[0]; } mainWindow->config.iniFile=cont; + lines=content.split("START_CLIENT_CONFIG\n"); + if (lines.count()>1) + { + cont=lines[1]; + cont=cont.split("END_CLIENT_CONFIG\n")[0]; + processClientConfig(cont); + } + else + { + x2goDebug<<"no client config from broker"; + } } @@ -540,6 +622,10 @@ void HttpBrokerClient::slotRequestFinished ( QNetworkReply* reply ) { slotPassChanged(true,answer,0); } + if (reply == eventRequest) + { + slotEventSent(true,answer,0); + } // We receive ownership of the reply object // and therefore need to handle deletion. diff --git a/src/httpbrokerclient.h b/src/httpbrokerclient.h index 0a307e1..4e0098e 100644 --- a/src/httpbrokerclient.h +++ b/src/httpbrokerclient.h @@ -45,6 +45,8 @@ public: void changePassword(QString newPass); void testConnection(); void closeSSHInteractionDialog(); + void sendEvent(const QString& ev, const QString& id, const QString& server, const QString& client, + const QString& login, const QString& cmd, const QString& display, const QString& start); private: QNetworkAccessManager* http; QNetworkRequest* netRequest; @@ -53,6 +55,7 @@ private: QNetworkReply* selSessRequest; QNetworkReply* chPassRequest; QNetworkReply* testConRequest; + QNetworkReply* eventRequest; QString nextAuthId; QString newBrokerPass; ConfigFile* config; @@ -62,6 +65,7 @@ private: SshMasterConnection* sshConnection; private: void createIniFile(const QString& raw_content); + void processClientConfig(const QString& raw_content); void parseSession(QString sInfo); void createSshConnection(); bool checkAccess(QString answer); @@ -78,6 +82,7 @@ private slots: void slotListSessions ( bool success, QString answer, int pid); void slotSelectSession ( bool success, QString answer, int pid); void slotPassChanged ( bool success, QString answer, int pid); + void slotEventSent ( bool success, QString answer, int pid); void slotConnectionTest( bool success, QString answer, int pid); void slotSshIoErr(SshProcess* caller, QString error, QString lastSessionError); diff --git a/src/onmainwindow.cpp b/src/onmainwindow.cpp index 405b124..d547248 100644 --- a/src/onmainwindow.cpp +++ b/src/onmainwindow.cpp @@ -3548,6 +3548,12 @@ void ONMainWindow::startDirectRDP() resumingSession.sessionId=sessionExplorer->getLastSession()->name(); resumingSession.crTime=QDateTime::currentDateTime().toString("dd.MM.yy HH:mm:ss"); showSessionStatus(); + if(brokerMode) + { + sendEventToBroker(CONNECTING,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } + // QTimer::singleShot ( 30000,this,SLOT ( slotRestartProxy() ) ); proxyRunning=true; delete st; @@ -3991,6 +3997,31 @@ x2goSession ONMainWindow::getSessionFromString ( const QString& string ) } +void ONMainWindow::sendEventToBroker(ONMainWindow::client_events ev, const QString& id, const QString& server, const QString& client, const QString& login, const QString& cmd, const QString& display, const QString& start) +{ + if(!config.brokerEvents) + { + return; + } + if(ev <= lastBrokerEvent && id == lastBrokerEventSession ) + { + return; + } + lastBrokerEvent=ev; + lastBrokerEventSession=id; + QString event; + switch(ev) + { + case CONNECTING: event="CONNECTING";break; + case CONNECTED: event="CONNECTED";break; + case SUSPENDING: event="SUSPENDING";break; + case TERMINATING: event="TERMINATING";break; + case FINISHED: event="FINISHED";break; + } + broker->sendEvent(event, id, server, client, login, cmd, display, start); +} + + void ONMainWindow::startNewSession() { newSession=true; @@ -5025,6 +5056,11 @@ void ONMainWindow::slotSuspendSess() void ONMainWindow::slotSuspendSessFromSt() { + if(brokerMode) + { + sendEventToBroker(SUSPENDING,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } #ifdef Q_OS_LINUX if (directRDP) { @@ -5053,6 +5089,11 @@ void ONMainWindow::slotTermSessFromSt() if (directRDP) { + if(brokerMode) + { + sendEventToBroker(TERMINATING,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } x2goDebug<<"Terminating direct RDP session."; nxproxy->terminate(); @@ -5061,20 +5102,30 @@ void ONMainWindow::slotTermSessFromSt() } #endif - x2goDebug<<"Disconnect export."; - - /* - disconnect ( sbExp,SIGNAL ( clicked() ),this, - SLOT ( slot_exportDirectory() ) );*/ - sbExp->setEnabled ( false ); if ( !shadowSession ) { if ( termSession ( resumingSession.sessionId ) ) + { + sbExp->setEnabled ( false ); + if(brokerMode) + { + sendEventToBroker(TERMINATING,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } setStatStatus ( tr ( "terminating" ) ); + } } else + { + sbExp->setEnabled ( false ); + if(brokerMode) + { + sendEventToBroker(TERMINATING,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } termSession ( resumingSession.sessionId,false ); + } } @@ -5812,6 +5863,12 @@ void ONMainWindow::slotTunnelOk(int) nxproxy->start ( proxyCmd ); proxyRunning=true; + if(brokerMode) + { + sendEventToBroker(CONNECTING,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } + // always search for proxy window on linux. On Windows only in window mode #ifdef Q_OS_WIN if (xorgMode==WIN) { @@ -6087,7 +6144,11 @@ void ONMainWindow::slotProxyError ( QProcess::ProcessError err ) void ONMainWindow::slotProxyFinished ( int,QProcess::ExitStatus ) { - + if(brokerMode) + { + sendEventToBroker(FINISHED,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } #ifdef Q_OS_DARWIN if (modMapTimer) { disconnect (modMapTimer, SIGNAL (timeout ()), this, SLOT (slotSetModMap ())); @@ -6288,9 +6349,11 @@ void ONMainWindow::slotProxyStderr() stInfo->insertPlainText ( reserr ); stInfo->ensureCursorVisible(); if ( stInfo->toPlainText().indexOf ( - "Connecting to remote host 'localhost:"+ - /*resumingSession.grPort*/ localGraphicPort ) !=-1 ) + "Connecting to remote host 'localhost:"+ + /*resumingSession.grPort*/ localGraphicPort ) !=-1 ) + { setStatStatus ( tr ( "connecting" ) ); + } if ( stInfo->toPlainText().indexOf ( "Connection to remote proxy 'localhost:"+ @@ -6310,6 +6373,11 @@ void ONMainWindow::slotProxyStderr() if ( stInfo->toPlainText().indexOf ( "Established X server connection" ) !=-1 ) { + if(brokerMode) + { + sendEventToBroker(CONNECTED,resumingSession.sessionId,resumingSession.server, resumingSession.clientIp, getCurrentUname(), + resumingSession.command, resumingSession.display, resumingSession.crTime); + } setStatStatus ( tr ( "running" ) ); if (trayEnabled) { diff --git a/src/onmainwindow.h b/src/onmainwindow.h index 47eaa5e..a1fab35 100644 --- a/src/onmainwindow.h +++ b/src/onmainwindow.h @@ -169,6 +169,7 @@ struct ConfigFile bool brokerAutologin; bool brokerAutologoff; bool brokerKrbLogin; + bool brokerEvents; //Send events to broker and get control commands QString brokerSshKey; QString brokerCaCertFile; QString iniFile; @@ -300,6 +301,14 @@ public: UNKNOWN_KEY_TYPE }; + enum client_events { + CONNECTING, + CONNECTED, + SUSPENDING, + TERMINATING, + FINISHED + }; + static bool debugging; static bool portable; @@ -859,6 +868,8 @@ private: int lastUid; bool cardReady; HttpBrokerClient* broker; + client_events lastBrokerEvent; + QString lastBrokerEventSession; #if defined ( Q_OS_WIN) //&& defined (CFGCLIENT ) @@ -899,7 +910,9 @@ private: bool trayMinCon; bool trayMaxDiscon; bool trayAutoHidden; - + void sendEventToBroker(client_events ev, const QString& id, const QString& server, const QString& client, + const QString& login, const QString& cmd, + const QString& display, const QString& start); QString findSshKeyForServer(QString user, QString server, QString port); void loadSettings(); void showPass ( UserButton* user ); -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2goclient.git