The branch, master has been updated
via ac2eeb5461e7f27cef3aaff705f690bf839bd8ce (commit)
from af679ed1fd34a7a062902d8b3960efe0dcfd62f8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ac2eeb5461e7f27cef3aaff705f690bf839bd8ce
Author: Oleksandr Shneyder <o.shneyder(a)phoca-gmbh.de>
Date: Sun Nov 11 15:51:36 2012 +0100
add classes for SSH Connection
-----------------------------------------------------------------------
Summary of changes:
sshconnection.cpp | 477 +++++++++++++++++++++++++++++++++++++++
sshconnection.h | 132 +++++++++++
sshconnectionguiinteraction.cpp | 170 ++++++++++++++
sshconnectionguiinteraction.h | 75 ++++++
workarea.cpp | 1 +
x2goapplication.cpp | 2 +
x2gobroker.cpp | 14 +-
x2goclient2.pro | 4 +
8 files changed, 871 insertions(+), 4 deletions(-)
create mode 100644 sshconnection.cpp
create mode 100644 sshconnection.h
create mode 100644 sshconnectionguiinteraction.cpp
create mode 100644 sshconnectionguiinteraction.h
The diff of changes is:
diff --git a/sshconnection.cpp b/sshconnection.cpp
new file mode 100644
index 0000000..878c66c
--- /dev/null
+++ b/sshconnection.cpp
@@ -0,0 +1,477 @@
+/**************************************************************************
+* Copyright (C) 2005-2012 by Oleksandr Shneyder *
+* o.shneyder(a)phoca-gmbh.de *
+* *
+* This program 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 program 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 program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+
+#include "sshconnection.h"
+#include "sshconnectionguiinteraction.h"
+
+#define PROXYTUNNELPORT 44444
+
+#undef DEBUG
+// #define DEBUG
+
+#undef SSH_DEBUG
+// #define SSH_DEBUG
+
+#include <QDebug>
+#include <QDir>
+#include <QTemporaryFile>
+
+
+#ifndef Q_OS_WIN
+#include <arpa/inet.h>
+#endif
+#include <math.h>
+
+#ifndef Q_OS_WIN
+#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
+#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
+#include <arpa/inet.h>
+#include <netinet/tcp.h>
+#include <qt4/QtNetwork/qabstractsocket.h>
+#endif
+
+
+bool SshConnection::isLibSshInited=false;
+SshConnectionGuiInteraction* SshConnection::guiInteractor=0;
+
+SshConnection::SshConnection(QObject* parent, QString host, int port, bool acceptUnknownServers,
+ QString user, QString pass, QString key, bool autoLogin, bool krbLogin,
+ bool useProxy, SshConnection::ProxyType proxyType, QString proxyServer,
+ quint16 proxyPort, QString proxyLogin, QString proxyPassword, QString proxyKey,
+ bool proxyAutoLogin): QThread(parent)
+{
+#if defined ( Q_OS_DARWIN )
+ // Mac OS X provides only 512KB stack space for secondary threads.
+ // As we put a 512KB buffer on the stack later on, we need a bigger stack space.
+ setStackSize (sizeof (char) * 1024 * 1024 * 2);
+#endif
+ tcpProxySocket = NULL;
+ tcpNetworkProxy = NULL;
+ sshProxy= NULL;
+ sshProxyReady=false;
+ nextPid=0;
+ my_ssh_session=0;
+
+ breakLoop=false;
+ this->host=host;
+ this->port=port;
+ this->user=user;
+ this->pass=pass;
+ this->key=key;
+ this->autoLogin=autoLogin;
+ this->acceptUnknownServers=acceptUnknownServers;
+ this->useProxy=useProxy;
+ this->proxyType=proxyType;
+ this->proxyAutoLogin=proxyAutoLogin;
+ this->proxyKey=proxyKey;
+ this->proxyServer=proxyServer;
+ this->proxyPort=proxyPort;
+ this->proxyLogin=proxyLogin;
+ this->proxyPassword=proxyPassword;
+ reverseTunnel=false;
+ kerberos=krbLogin;
+ kerberos=false;
+ if(!guiInteractor)
+ {
+ guiInteractor=new SshConnectionGuiInteraction(parent);
+ }
+}
+
+SshConnection::~SshConnection()
+{
+ if(my_ssh_session)
+ {
+ ssh_free(my_ssh_session);
+ }
+ qDebug()<<"ssh connection destructor";
+}
+
+void SshConnection::run()
+{
+ disconnectSessionFlag=false;
+ if ( !isLibSshInited )
+ {
+ if ( ssh_init() !=0 )
+ {
+ QString err=tr ( "Can not initialize libssh" );
+ qDebug()<<err<<endl;
+ guiInteractor->critical(err, MessageBox::OK);
+ emit signalError ( CONNECTION, err );
+ return;
+ }
+ isLibSshInited=true;
+ }
+
+#ifdef SSH_DEBUG
+ int verbosity=SSH_LOG_PACKET;
+#else
+ int verbosity=SSH_LOG_NOLOG;
+#endif
+
+ long timeout = 60;
+
+ my_ssh_session = ssh_new();
+ if ( my_ssh_session == NULL )
+ {
+ QString err=tr ( "Can not create ssh session" );
+ qDebug()<<err<<endl;
+ guiInteractor->critical(err, MessageBox::OK);
+ emit signalError ( CONNECTION, err);
+ if ( reverseTunnel )
+ emit signalIoError ( reverseTunnelCreator, err, "" );
+ return;
+ }
+
+#ifdef Q_OS_WIN
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_SSH_DIR, (mainWnd->getHomeDirectory()+"/ssh").toAscii());
+#endif
+ ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+
+ ssh_options_set(my_ssh_session, SSH_OPTIONS_TIMEOUT, &timeout);
+
+ if (useProxy && (proxyType == PROXYHTTP))
+ {
+ socket_t proxysocket = SSH_INVALID_SOCKET;
+
+ tcpNetworkProxy = new QNetworkProxy( QNetworkProxy::HttpProxy,
+ proxyServer, proxyPort, proxyLogin, proxyPassword);
+ tcpProxySocket = new QTcpSocket();
+ tcpProxySocket->setProxy( *tcpNetworkProxy );
+ tcpProxySocket->connectToHost(host, port);
+ proxysocket = tcpProxySocket->socketDescriptor();
+ if (!tcpProxySocket->waitForConnected(30000))
+ {
+ QString message=tr ( "Can not connect to proxy server" );
+ qDebug()<<message<<endl;
+ guiInteractor->critical(message, MessageBox::OK);
+ emit signalError ( CONNECTION, message );
+ ssh_free ( my_ssh_session );
+ return;
+ }
+ ssh_options_set( my_ssh_session, SSH_OPTIONS_FD, &proxysocket);
+ ssh_set_fd_toread( my_ssh_session);
+ }
+
+ if ( !sshConnect() )
+ {
+ QString err=ssh_get_error ( my_ssh_session );
+ QString message=tr ( "Can not connect to " ) +host+":"+QString::number ( port );
+ message+=" - "+err;
+ qDebug()<<message;
+ guiInteractor->critical(message, MessageBox::OK);
+ emit signalError (CONNECTION, message);
+ if ( reverseTunnel )
+ emit signalIoError ( reverseTunnelCreator, message, err);
+ ssh_free ( my_ssh_session );
+ return;
+ }
+ QString errMsg;
+ int state=serverAuth ( errMsg );
+ if ( state != SSH_SERVER_KNOWN_OK )
+ {
+ guiInteractor->critical(errMsg, MessageBox::OK);
+ emit signalError (SERVERAUTH, errMsg);
+ ssh_disconnect ( my_ssh_session );
+ ssh_free ( my_ssh_session );
+ return;
+ }
+
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_USER, user.toAscii() );
+#ifdef Q_OS_WIN
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_SSH_DIR, (QDir::homePath()+"/ssh").toAscii());
+#endif
+ if ( userAuth() )
+ {
+ qDebug()<<"SSH session connected";
+ emit signalConnectionOk(host);
+ }
+ else
+ {
+ QString err;
+ if (!kerberos)
+ err=ssh_get_error ( my_ssh_session );
+ QString message=tr ( "Authentication failed" );
+ guiInteractor->critical(message, MessageBox::OK);
+ message+=" - "+err+"\n"+authErrors.join ( "\n" );
+ qDebug()<<message;
+ emit signalError (USERAUTH, message );
+ if ( reverseTunnel )
+ emit signalIoError ( reverseTunnelCreator,message,err );
+ ssh_disconnect ( my_ssh_session );
+ ssh_free ( my_ssh_session );
+ return;
+ }
+
+
+#ifndef Q_OS_WIN
+ const int y=1;
+#else
+ const char y=1;
+#endif
+ socket_t session_sock=ssh_get_fd(my_ssh_session);
+ setsockopt(session_sock, IPPROTO_TCP, TCP_NODELAY,&y, sizeof(int));
+
+
+ if ( reverseTunnel )
+ {
+ if ( channel_forward_listen ( my_ssh_session, NULL, reverseTunnelRemotePort, NULL ) !=SSH_OK )
+ {
+ QString err=ssh_get_error ( my_ssh_session );
+ QString message=tr ( "channel_forward_listen failed" );
+ message+=" - "+err;
+ qDebug()<<message;
+ guiInteractor->critical(message, MessageBox::OK);
+ emit signalIoError ( reverseTunnelCreator, message, err );
+ ssh_disconnect ( my_ssh_session );
+ ssh_free ( my_ssh_session );
+ return;
+ }
+ emit signalReverseListenOk ( reverseTunnelCreator );
+ }
+ channelLoop();
+}
+
+void SshConnection::finalizeLibSsh()
+{
+ if ( !isLibSshInited )
+ return;
+ ssh_finalize();
+}
+
+
+bool SshConnection::sshConnect()
+{
+ int rc;
+ QByteArray tmpBA = host.toLocal8Bit();
+ if(useProxy && proxyType==PROXYSSH)
+ {
+#ifdef Q_OS_WIN
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_HOST, "127.0.0.1" );
+#else
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_HOST, "localhost" );
+#endif
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_PORT, &localProxyPort );
+ }
+ else
+ {
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_HOST, tmpBA.data() );
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_PORT, &port );
+ }
+ rc = ssh_connect ( my_ssh_session );
+ if ( rc != SSH_OK )
+ {
+ return false;
+ }
+//set values for remote host for proper server authentication
+ if(useProxy && proxyType==PROXYSSH)
+ {
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_HOST, tmpBA.data() );
+ ssh_options_set ( my_ssh_session, SSH_OPTIONS_PORT, &port );
+
+ }
+ return true;
+}
+
+int SshConnection::serverAuth(QString& errorMsg)
+{
+ int state, hlen;
+ unsigned char *hash = NULL;
+ char *hexa;
+
+ state = ssh_is_server_known ( my_ssh_session );
+ hlen = ssh_get_pubkey_hash ( my_ssh_session, &hash );
+
+
+ if ( hlen < 0 )
+ return SSH_SERVER_ERROR;
+
+#ifdef DEBUG
+ x2goDebug<<"state: "<<state<<endl;
+#endif
+
+ switch ( state )
+ {
+ case SSH_SERVER_KNOWN_OK:
+ break; /* ok */
+
+ case SSH_SERVER_KNOWN_CHANGED:
+ hexa = ssh_get_hexa ( hash, hlen );
+ errorMsg=tr ( "Host key for server ")+host+":"+QString::number(port)+tr(" changed.\nIt is now: " ) +hexa+"\n"+
+ tr ( "For security reasons, connection will be stopped" );
+ free ( hexa );
+ break;
+ case SSH_SERVER_FOUND_OTHER:
+ errorMsg=tr ( "The host key for server ")+ host+":"+QString::number(port) +tr(" was not found but an other"
+ "type of key exists.An attacker might change the default server key to"
+ "confuse your client into thinking the key does not exist" );
+
+ break;
+ case SSH_SERVER_FILE_NOT_FOUND:
+ case SSH_SERVER_NOT_KNOWN:
+ if ( !acceptUnknownServers )
+ {
+ hexa = ssh_get_hexa ( hash, hlen );
+ errorMsg= tr ( "The server is unknown: ")+ host+":"+QString::number(port)+"\n"+
+ tr("Do you trust the host key?\nPublic key hash: " )+ " - "+hexa;
+ free ( hexa );
+ if(guiInteractor->warning(errorMsg, MessageBox::YES| MessageBox::NO) != MessageBox::YES)
+ {
+ errorMsg=tr ( "Host key verification failed" );
+ break;
+ }
+ }
+ ssh_write_knownhost ( my_ssh_session );
+ state=SSH_SERVER_KNOWN_OK;
+ break;
+ case SSH_SERVER_ERROR:
+ errorMsg=host+":"+QString::number(port)+" - "+ssh_get_error ( my_ssh_session );
+ break;
+ }
+ free ( hash );
+ return state;
+}
+
+bool SshConnection::userAuth()
+{
+ if(user.length()<=0)
+ if (guiInteractor->input(tr("Enter user name"),tr("User:"),user,QLineEdit::Password)!=MessageBox::OK)
+ return false;
+ if ( autoLogin )
+ if ( userAuthAuto() )
+ return true;
+ if ( key!="" )
+ {
+ if ( userAuthWithKey() )
+ return true;
+ }
+ return userAuthWithPass();
+}
+
+bool SshConnection::userAuthAuto()
+{
+ int rc = ssh_userauth_autopubkey ( my_ssh_session, "" );
+ while(rc != SSH_AUTH_SUCCESS)
+ {
+ if(guiInteractor->input(tr("Enter passphrase to decrypt a key"),tr("Passphrase:"), keyPhrase,QLineEdit::Password)!=MessageBox::OK)
+ return false;
+ rc = ssh_userauth_autopubkey ( my_ssh_session, keyPhrase.toAscii() );
+ }
+ if ( rc != SSH_AUTH_SUCCESS )
+ {
+ QString err=ssh_get_error ( my_ssh_session );
+ authErrors<<err;
+ return false;
+ }
+ return true;
+}
+
+bool SshConnection::userAuthWithKey()
+{
+ QString keyName=key;
+ bool autoRemove=false;
+ if ( key.indexOf ( "PRIVATE KEY" ) !=-1 )
+ {
+ QDir dr;
+ QString keyPath=QDir::homePath() +"/.x2go/ssh/gen";
+ dr.mkpath ( keyPath );
+ QTemporaryFile fl ( keyPath+"/key" );
+ fl.open();
+ keyName=fl.fileName();
+ fl.setAutoRemove ( false );
+ QTextStream out ( &fl );
+ out<<key;
+ fl.close();
+ autoRemove=true;
+ }
+ ssh_private_key prkey=privatekey_from_file(my_ssh_session, keyName.toAscii(), 0,"");
+ while(!prkey)
+ {
+ if(guiInteractor->input(tr("Enter passphrase to decrypt a key"),tr("Passphrase:"), keyPhrase, QLineEdit::Password)!=MessageBox::OK)
+ break;
+ prkey=privatekey_from_file(my_ssh_session, keyName.toAscii(), 0,keyPhrase.toAscii());
+ }
+ if (!prkey)
+ {
+ if ( autoRemove )
+ QFile::remove ( keyName );
+ return false;
+ }
+ ssh_public_key pubkey=publickey_from_privatekey(prkey);
+ if (!prkey)
+ {
+ privatekey_free(prkey);
+ if ( autoRemove )
+ QFile::remove ( keyName );
+ return false;
+ }
+
+ ssh_string pubkeyStr=publickey_to_string(pubkey);
+ publickey_free(pubkey);
+
+ //not implemented before libssh 0.5
+ /* int rc = ssh_userauth_privatekey_file ( my_ssh_session,NULL,
+ keyName.toAscii(),
+ pass.toAscii() );*/
+
+ int rc=ssh_userauth_pubkey(my_ssh_session, NULL, pubkeyStr, prkey);
+ privatekey_free(prkey);
+ string_free(pubkeyStr);
+ if ( autoRemove )
+ QFile::remove ( keyName );
+ if ( rc != SSH_AUTH_SUCCESS )
+ {
+ QString err=ssh_get_error ( my_ssh_session );
+ authErrors<<err;
+ return false;
+ }
+ return true;
+}
+
+bool SshConnection::userAuthWithPass()
+{
+ if(pass.length()<=0)
+ if(guiInteractor->input(tr("Enter password"),tr("Password:"), pass, QLineEdit::Password)!=MessageBox::OK)
+ return false;
+
+ int rc = ssh_userauth_password ( my_ssh_session, NULL, pass.toAscii() );
+ while ( rc != SSH_AUTH_SUCCESS )
+ {
+ if(guiInteractor->input(tr("Enter password"),tr("Password:"), pass, QLineEdit::Password)!=MessageBox::OK)
+ {
+
+ QString err=ssh_get_error ( my_ssh_session );
+ authErrors<<err;
+ return false;
+ }
+ rc = ssh_userauth_password ( my_ssh_session, NULL, pass.toAscii() );
+ }
+ return true;
+
+}
+
+void SshConnection::channelLoop()
+{
+
+}
+
+void SshConnection::finalize(int arg1)
+{
+
+}
diff --git a/sshconnection.h b/sshconnection.h
new file mode 100644
index 0000000..abb08e7
--- /dev/null
+++ b/sshconnection.h
@@ -0,0 +1,132 @@
+/**************************************************************************
+* Copyright (C) 2005-2012 by Oleksandr Shneyder *
+* o.shneyder(a)phoca-gmbh.de *
+* *
+* This program 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 program 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 program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+
+#ifndef SSHCONNECTION_H
+#define SSHCONNECTION_H
+
+#include <libssh/libssh.h>
+#include <QString>
+#include <QList>
+#include <QMutex>
+#include <QThread>
+#include <QStringList>
+#include <QTcpSocket>
+#include <QNetworkProxy>
+
+#include "x2goapplication.h"
+
+class SshProcess;
+class SshConnectionGuiInteraction;
+
+struct ChannelConnection
+{
+ ssh_channel channel;
+ int sock;
+ SshProcess* creator;
+ int forwardPort;
+ int localPort;
+ QString forwardHost;
+ QString localHost;
+ QString command;
+ bool operator==(ChannelConnection& t)
+ {
+ return (channel==t.channel);
+ }
+};
+
+struct CopyRequest
+{
+ SshProcess* creator;
+ QString src;
+ QString dst;
+};
+
+class SshConnection: public QThread
+{
+ Q_OBJECT
+public:
+ enum ProxyType {PROXYSSH, PROXYHTTP};
+ enum Error {CONNECTION, SERVERAUTH, USERAUTH};
+ SshConnection(QObject* parent, QString host, int port, bool acceptUnknownServers, QString user,
+ QString pass, QString key, bool autoLogin, bool krbLogin=false,
+ bool useProxy=false, ProxyType proxyType=PROXYSSH, QString proxyServer=QString::null, quint16 proxyPort=0,
+ QString proxyLogin=QString::null, QString proxyPassword=QString::null, QString proxyKey=QString::null,
+ bool proxyAutoLogin=false);
+ ~SshConnection();
+ static void finalizeLibSsh();
+private:
+ ssh_session my_ssh_session;
+ QList<ChannelConnection> channelConnections;
+ QList<CopyRequest> copyRequests;
+ QList<SshConnection*> reverseTunnelConnections;
+ int nextPid;
+ QList<SshProcess*> processes;
+ QStringList authErrors;
+ QString keyPhrase;
+ QString host;
+ int port;
+ QString user;
+ QString pass;
+ QString key;
+ bool useProxy;
+ QString proxyServer;
+ quint16 proxyPort;
+ QString proxyLogin;
+ QString proxyPassword;
+ ProxyType proxyType;
+ bool proxyAutoLogin;
+ QString proxyKey;
+ bool autoLogin;
+ bool disconnectSessionFlag;
+ bool reverseTunnel;
+ int reverseTunnelRemotePort;
+ int localProxyPort;
+ int reverseTunnelLocalPort;
+ bool acceptUnknownServers;
+ QString reverseTunnelLocalHost;
+ SshProcess* reverseTunnelCreator;
+ bool kerberos;
+ QTcpSocket *tcpProxySocket;
+ QNetworkProxy *tcpNetworkProxy;
+ SshConnection* sshProxy;
+ bool sshProxyReady;
+ bool breakLoop;
+ static bool isLibSshInited;
+ static SshConnectionGuiInteraction* guiInteractor;
+private:
+ bool sshConnect();
+ bool userAuthWithPass();
+ bool userAuthAuto();
+ bool userAuthWithKey();
+ bool userAuth();
+ void channelLoop();
+ void finalize(int arg1);
+ int serverAuth(QString& errorMsg);
+protected:
+ void run();
+signals:
+ void signalError(Error, QString);
+ void signalIoError(SshProcess* caller, QString error, QString lastSessionError);
+
+ void signalConnectionOk( QString host);
+ void signalReverseListenOk(SshProcess* creator);
+};
+
+#endif // SSHCONNECTION_H
diff --git a/sshconnectionguiinteraction.cpp b/sshconnectionguiinteraction.cpp
new file mode 100644
index 0000000..d70d166
--- /dev/null
+++ b/sshconnectionguiinteraction.cpp
@@ -0,0 +1,170 @@
+/**************************************************************************
+* Copyright (C) 2005-2012 by Oleksandr Shneyder *
+* o.shneyder(a)phoca-gmbh.de *
+* *
+* This program 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 program 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 program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+
+#include "sshconnectionguiinteraction.h"
+#include <QTimer>
+#include <QThread>
+#include <QDebug>
+
+SshConnectionGuiInteraction::SshConnectionGuiInteraction(QObject* parent): QThread(parent)
+{
+ currentId=0;
+ QTimer::singleShot(100, this, SLOT(slotCheckRequests()));
+}
+
+SshConnectionGuiInteraction::~SshConnectionGuiInteraction()
+{
+
+}
+
+MessageBox::Buttons SshConnectionGuiInteraction::critical(QString text, int buttons)
+{
+ unsigned long int id=addRequest(CRITICAL, text, buttons);
+ QString input;
+ return result(id, input);
+}
+
+MessageBox::Buttons SshConnectionGuiInteraction::information(QString text, int buttons)
+{
+ unsigned long int id=addRequest(INFORMATION, text, buttons);
+ QString input;
+ return result(id, input);
+}
+
+MessageBox::Buttons SshConnectionGuiInteraction::warning(QString text, int buttons)
+{
+ unsigned long int id= addRequest(WARNING, text, buttons);
+ QString input;
+ return result(id, input);
+}
+
+
+MessageBox::Buttons SshConnectionGuiInteraction::input(QString text, QString inputLabel, QString& input,
+ QLineEdit::EchoMode echoMode, QString pixPath)
+{
+ unsigned long int id= addRequest(INPUT, text, MessageBox::OK| MessageBox::CANCEL, inputLabel, input, echoMode, pixPath);
+ return result(id, input);
+}
+
+long unsigned int SshConnectionGuiInteraction::addRequest(SshConnectionGuiInteraction::BoxType type,
+ QString text, int buttons, QString inputLabel,
+ QString input, QLineEdit::EchoMode echoMode,
+ QString pixPath)
+{
+ InteractionRequest req;
+ req.processed=false;
+ req.boxType=type;
+ req.text=text;
+ req.buttons=buttons;
+ req.inputLabel=inputLabel;
+ req.input=input;
+ req.echoMode=echoMode;
+ req.pixPath=pixPath;
+ req.id=currentId++;
+ mutex.lock();
+ requests<<req;
+ mutex.unlock();
+ return req.id;
+}
+
+MessageBox::Buttons SshConnectionGuiInteraction::result(long unsigned int id, QString& input)
+{
+ InteractionRequest req;
+ req.id=id;
+ bool ok=false;
+ MessageBox::Buttons button;
+ while(!ok)
+ {
+ mutex.lock();
+ int index=requests.indexOf(req);
+ if(index!=-1)
+ {
+ ok=requests[index].processed;
+ if(ok)
+ {
+ button=(MessageBox::Buttons)requests[index].buttons;
+ input=requests[index].input;
+ requests.removeAt(index);
+ }
+ }
+ mutex.unlock();
+ if(!ok)
+ QThread::msleep(100);
+ }
+ return button;
+}
+
+void SshConnectionGuiInteraction::slotCheckRequests()
+{
+ bool haveReq=false;
+ BoxType boxType;
+ int buttons;
+ QString text;
+ QString inputLabel;
+ QString input;
+ QLineEdit::EchoMode echoMode;
+ QString pixPath;
+ unsigned long int id;
+ mutex.lock();
+ foreach (InteractionRequest req, requests)
+ {
+ haveReq=true;
+ boxType=req.boxType;
+ buttons=req.buttons;
+ text=req.text;
+ inputLabel=req.inputLabel;
+ input=req.input;
+ echoMode=req.echoMode;
+ pixPath=req.pixPath;
+ id=req.id;
+ break;
+ }
+ mutex.unlock();
+ if(haveReq)
+ {
+ switch(boxType)
+ {
+ case INFORMATION:
+ buttons=MessageBox::information(text, buttons);
+ break;
+ case WARNING:
+ buttons=MessageBox::warning(text, buttons);
+ break;
+ case CRITICAL:
+ buttons=MessageBox::critical(text, buttons);
+ break;
+ case INPUT:
+ buttons=MessageBox::input(text, inputLabel, input, echoMode, pixPath);
+ break;
+ }
+ mutex.lock();
+ InteractionRequest req;
+ req.id=id;
+ int index=requests.indexOf(req);
+ if(index!=-1)
+ {
+ requests[index].buttons=buttons;
+ requests[index].input=input;
+ requests[index].processed=true;
+ }
+ mutex.unlock();
+ }
+ QTimer::singleShot(100, this, SLOT(slotCheckRequests()));
+}
diff --git a/sshconnectionguiinteraction.h b/sshconnectionguiinteraction.h
new file mode 100644
index 0000000..df462c9
--- /dev/null
+++ b/sshconnectionguiinteraction.h
@@ -0,0 +1,75 @@
+/**************************************************************************
+* Copyright (C) 2005-2012 by Oleksandr Shneyder *
+* o.shneyder(a)phoca-gmbh.de *
+* *
+* This program 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 program 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 program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+/*This class provide interaction with user for SshConnection objects, which running not in
+GUI thread and can not use GUI elements
+*/
+
+#ifndef SSHCONNECTIONGUIINTERACTION_H
+#define SSHCONNECTIONGUIINTERACTION_H
+#include <QObject>
+#include "messagebox.h"
+#include <QMutex>
+#include <QTimer>
+#include <QThread>
+
+class SshConnectionGuiInteraction: public QThread
+{
+ Q_OBJECT
+public:
+ explicit SshConnectionGuiInteraction(QObject* parent = 0);
+ virtual ~SshConnectionGuiInteraction();
+ MessageBox::Buttons critical(QString text, int buttons);
+ MessageBox::Buttons warning(QString text, int buttons);
+ MessageBox::Buttons information(QString text, int buttons);
+ MessageBox::Buttons input(QString text, QString inputLabel, QString& input,
+ QLineEdit::EchoMode echoMode=QLineEdit::Normal, QString pixPath=QString::null);
+private:
+ enum BoxType {WARNING, CRITICAL, INFORMATION, INPUT};
+ struct InteractionRequest
+ {
+ bool processed;
+ BoxType boxType;
+ int buttons;
+ QString text;
+ QString inputLabel;
+ QString input;
+ QLineEdit::EchoMode echoMode;
+ QString pixPath;
+ unsigned long int id;
+ bool operator==(InteractionRequest t)
+ {
+ return (id==t.id);
+ }
+ };
+ QList<InteractionRequest> requests;
+ unsigned long int currentId;
+ QMutex mutex;
+private:
+ unsigned long int addRequest(BoxType type, QString text, int buttons, QString inputLabel=QString::null,
+ QString input=QString::null,
+ QLineEdit::EchoMode echoMode=QLineEdit::Normal,
+ QString pixPath=QString::null);
+ MessageBox::Buttons result(unsigned long id, QString& input);
+
+private slots:
+ void slotCheckRequests();
+};
+
+#endif // SSHCONNECTIONGUIINTERACTION_H
diff --git a/workarea.cpp b/workarea.cpp
index eb23c8b..dc619b7 100644
--- a/workarea.cpp
+++ b/workarea.cpp
@@ -61,6 +61,7 @@ WorkArea::WorkArea(QWidget* parent, Qt::WindowFlags f): QWidget( parent, f)
QTimer::singleShot(100, this, SLOT(slotResizeChildForms()));
formToScroll=profileForm;
+ sessionForm->hide();
}
WorkArea::~WorkArea()
diff --git a/x2goapplication.cpp b/x2goapplication.cpp
index 1fd8881..817f571 100644
--- a/x2goapplication.cpp
+++ b/x2goapplication.cpp
@@ -34,6 +34,7 @@
#include "mainwindow.h"
#include "x2gobroker.h"
#include "profilesettingsform.h"
+#include "sshconnection.h"
X2GoApplication::X2GoApplication(int& argc, char** argv, int flags): QApplication(argc, argv, flags)
{
@@ -63,6 +64,7 @@ X2GoApplication::~X2GoApplication()
delete sessionSettings;
if(broker)
delete broker;
+ SshConnection::finalizeLibSsh();
qDebug()<<"X2Go Application exited";
}
diff --git a/x2gobroker.cpp b/x2gobroker.cpp
index 0cd2152..cca32a7 100644
--- a/x2gobroker.cpp
+++ b/x2gobroker.cpp
@@ -26,6 +26,7 @@
#include "x2goapplication.h"
#include "x2goclientconfig.h"
#include "messagebox.h"
+#include "sshconnection.h"
X2GoBroker::X2GoBroker(QObject* parent): QObject(parent)
{
@@ -38,9 +39,18 @@ X2GoBroker::X2GoBroker(QObject* parent): QObject(parent)
url = QUrl( urlString);
if(url.userName().length()>0)
user=url.userName();
+ if(!cfg->get_defaultNoBrockerAuth().get_value().toBool())
+ {
+ getLoginData();
+ }
if(urlString.indexOf("ssh://")==0)
{
brokerType=SSH;
+#warning search for default key hier
+ SshConnection* con=new SshConnection(this, url.host(), url.port(), cfg->get_autoAddToKnownHosts().get_value().toBool(),
+ user, pass, QString::null,
+ cfg->get_defaultAutoLogin().get_value().toBool());
+ con->start();
}
else
{
@@ -69,10 +79,6 @@ X2GoBroker::X2GoBroker(QObject* parent): QObject(parent)
QTextStream in(&file);
authId = in.readLine();
}
- if(!cfg->get_defaultNoBrockerAuth().get_value().toBool())
- {
- getLoginData();
- }
}
X2GoBroker::~X2GoBroker()
diff --git a/x2goclient2.pro b/x2goclient2.pro
index ea126d0..5f02ec9 100755
--- a/x2goclient2.pro
+++ b/x2goclient2.pro
@@ -56,6 +56,8 @@ SOURCES += main.cpp \
x2gosettings.cpp \
helpdialog.cpp \
x2gobroker.cpp \
+ sshconnection.cpp \
+ sshconnectionguiinteraction.cpp \
profile.cpp
HEADERS += mainwindow.h \
@@ -84,6 +86,8 @@ HEADERS += mainwindow.h \
x2gosettings.h \
helpdialog.h \
x2gobroker.h \
+ sshconnection.h \
+ sshconnectionguiinteraction.h \
profile.h
LIBS += -lssh
hooks/post-receive
--
x2goclient2.git (X2Go Client 2 (rewrite of x2goclient.git))
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "x2goclient2.git" (X2Go Client 2 (rewrite of x2goclient.git)).