[X2go-Commits] x2goclient2.git - master (branch) updated: ac2eeb5461e7f27cef3aaff705f690bf839bd8ce

X2Go dev team git-admin at x2go.org
Sun Nov 11 15:52:03 CET 2012


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 at 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 at 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 at 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 at 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 at 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)).




More information about the x2go-commits mailing list