[X2Go-Commits] [x2goclient] 17/17: src/sshmasterconnection.cpp: enable parsing of ~/.ssh/config. Fixes: #1121.

git-admin at x2go.org git-admin at x2go.org
Wed Feb 8 21:07:43 CET 2017


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch feature/libssh-api-upgrade
in repository x2goclient.

commit fbb7b42e94187fb16debf7a9f0726279aecf1ef3
Author: Mihai Moldovan <ionic at ionic.de>
Date:   Thu Feb 2 08:09:08 2017 +0100

    src/sshmasterconnection.cpp: enable parsing of ~/.ssh/config. Fixes: #1121.
    
    Shorthands as host names and other bells and whistles like inferred port
    or user name values are now supported.
---
 debian/changelog            |    3 +
 src/sessionwidget.cpp       |   19 ++++--
 src/sshmasterconnection.cpp |  148 +++++++++++++++++++++++++++++++++++++------
 3 files changed, 143 insertions(+), 27 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 75d4164..1e7ab6e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -612,6 +612,9 @@ x2goclient (4.1.0.0-0x2go1) UNRELEASED; urgency=medium
     - src/sshmasterconnection.cpp: fix up some debug strings.
     - src/sshmasterconnection.cpp: port more occurrences of "QString to C
       string" akin to 1b21d75f2c10609f3586f5b5e0b4ceb7fca83fdd.
+    - src/sshmasterconnection.cpp: enable parsing of ~/.ssh/config.
+      Fixes: #1121. Shorthands as host names and other bells and whistles like
+      inferred port or user name values are now supported.
 
   [ Bernard Cafarelli ]
   * New upstream version (4.1.0.0):
diff --git a/src/sessionwidget.cpp b/src/sessionwidget.cpp
index 9fd2781..e70aff6 100644
--- a/src/sessionwidget.cpp
+++ b/src/sessionwidget.cpp
@@ -84,17 +84,23 @@ SessionWidget::SessionWidget ( bool newSession, QString id, ONMainWindow * mw,
 #else
     QFrame* sgb=this;
 #endif
+    const QString ssh_port_tooltip_text = tr ("Values ranging from <b>0</b> to <b>65535</b> are allowed."
+                                              "<br />A value of <b>0</b> will either use the port specified in the "
+                                              "SSH configuration file belonging to a host or shortname, "
+                                              "or use the default of <b>22</b>.");
     server=new QLineEdit ( sgb );
     uname=new QLineEdit ( sgb );
     sshPort=new QSpinBox ( sgb );
     sshPort->setValue ( mainWindow->getDefaultSshPort().toInt() );
-    sshPort->setMinimum ( 1 );
-    sshPort->setMaximum ( 999999999 );
+    sshPort->setMinimum ( 0 );
+    sshPort->setMaximum ( 65535 );
+    sshPort->setToolTip (ssh_port_tooltip_text);
 #ifdef Q_OS_LINUX
     rdpPort=new QSpinBox ( sgb );
     rdpPort->setValue ( mainWindow->getDefaultSshPort().toInt() );
-    rdpPort->setMinimum ( 1 );
-    rdpPort->setMaximum ( 999999999 );
+    rdpPort->setMinimum ( 0 );
+    rdpPort->setMaximum ( 65535 );
+    rdpPort->setToolTip (ssh_port_tooltip_text);
 #endif
     key=new QLineEdit ( sgb );
 
@@ -156,8 +162,9 @@ SessionWidget::SessionWidget ( bool newSession, QString id, ONMainWindow * mw,
     proxyType->addButton(rbHttpProxy);
     proxyHost=new QLineEdit(proxyBox);
     proxyPort=new QSpinBox(proxyBox);
-    proxyPort->setMinimum ( 1 );
-    proxyPort->setMaximum ( 999999999 );
+    proxyPort->setMinimum ( 0 );
+    proxyPort->setMaximum ( 65535 );
+    proxyPort->setToolTip (ssh_port_tooltip_text);
 
     cbProxySameUser=new QCheckBox(tr("Same login as on X2Go Server"), proxyBox);
     proxyLogin=new QLineEdit(proxyBox);
diff --git a/src/sshmasterconnection.cpp b/src/sshmasterconnection.cpp
index b08acd0..acda638 100644
--- a/src/sshmasterconnection.cpp
+++ b/src/sshmasterconnection.cpp
@@ -195,14 +195,53 @@ SshMasterConnection::SshMasterConnection (QObject* parent, QString host, int por
     mainWnd=(ONMainWindow*) parent;
     kerberos=krblogin;
     challengeAuthVerificationCode=QString::null;
-    if(this->user==QString::null||this->user.length()<=0)
-    {
+
+    if (this->user.isEmpty ()) {
+        /* We might have a config file request pending, honor this. */
+        ssh_session tmp_session = ssh_new ();
+
+        if (!tmp_session) {
+            QString error_msg = tr ("Cannot create SSH session.");
+            error_msg += " " + tr ("Using environment-provided username.");
+#ifdef DEBUG
+            x2goDebug << error_msg;
+#endif
+        }
+        else {
+            QByteArray tmp_BA;
+
+            if ((useproxy) && (PROXYSSH == proxytype)) {
+                tmp_BA = this->proxyserver.toLocal8Bit ();
+            }
+            else {
+                tmp_BA = this->host.toLocal8Bit ();
+            }
+
+            ssh_options_set (tmp_session, SSH_OPTIONS_HOST, tmp_BA.data ());
+
+            if (ssh_options_parse_config (tmp_session, NULL) < 0) {
+                x2goDebug << "Warning: unable to parse the SSH config file.";
+            }
+
+            char *inferred_username = NULL;
+            ssh_options_get (tmp_session, SSH_OPTIONS_USER, &inferred_username);
+            x2goDebug << "Temporary session user name after config file parse: " << inferred_username;
+
+            this->user = QString::fromLocal8Bit (inferred_username);
+
+            ssh_string_free_char (inferred_username);
+            ssh_free (tmp_session);
+        }
+    }
+
+    if (this->user.isEmpty ()) {
 #ifdef Q_OS_WIN
-        this->user=getenv("USERNAME");
+        this->user = getenv ("USERNAME");
 #else
-        this->user=getenv("USER");
+        this->user = getenv ("USER");
 #endif
     }
+
 #ifdef DEBUG
     if (kerberos)
     {
@@ -773,14 +812,30 @@ bool SshMasterConnection::sshConnect()
     if(useproxy && proxytype==PROXYSSH)
     {
         ssh_options_set ( my_ssh_session, SSH_OPTIONS_HOST, "127.0.0.1" );
-        ssh_options_set ( my_ssh_session, SSH_OPTIONS_PORT, &localProxyPort );
-
+        if (localProxyPort) {
+            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 );
+        if (port) {
+            ssh_options_set ( my_ssh_session, SSH_OPTIONS_PORT, &port );
+        }
     }
+
+    unsigned int cur_port = 0;
+    ssh_options_get_port (my_ssh_session, &cur_port);
+    x2goDebug << "Session port before config file parse: " << cur_port;
+
+    /* Parse ~/.ssh/config. */
+    if (ssh_options_parse_config (my_ssh_session, NULL) < 0) {
+        x2goDebug << "Warning: unable to parse the SSH config file.";
+    }
+
+    ssh_options_get_port (my_ssh_session, &cur_port);
+    x2goDebug << "Session port after config file parse: " << cur_port;
+
     rc = ssh_connect ( my_ssh_session );
     if ( rc != SSH_OK )
     {
@@ -790,9 +845,22 @@ bool SshMasterConnection::sshConnect()
     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 );
+        if (port) {
+            ssh_options_set ( my_ssh_session, SSH_OPTIONS_PORT, &port );
+        }
+    }
+
+    ssh_options_get_port (my_ssh_session, &cur_port);
+    x2goDebug << "Session port before config file parse (part 2): " << cur_port;
 
+    /* Parse ~/.ssh/config. */
+    if (ssh_options_parse_config (my_ssh_session, NULL) < 0) {
+        x2goDebug << "Warning: unable to parse the SSH config file.";
     }
+
+    ssh_options_get_port (my_ssh_session, &cur_port);
+    x2goDebug << "Session port after config file parse (part 2): " << cur_port;
+
     return true;
 }
 
@@ -1583,23 +1651,61 @@ void SshMasterConnection::channelLoop()
 #ifdef DEBUG
                     x2goDebug<<"Forwarding new channel, local port: "<<channelConnections.at ( i ).localPort<<endl;
 #endif
-                    if ( ssh_channel_open_forward ( channel,
-                                                    channelConnections.at ( i ).forwardHost.toLatin1(),
-                                                    channelConnections.at ( i ).forwardPort,
-                                                    channelConnections.at ( i ).localHost.toLatin1(),
-                                                    channelConnections.at ( i ).localPort ) != SSH_OK )
-                    {
-                        QString err=ssh_get_error ( my_ssh_session );
-                        QString errorMsg=tr ( "%1 failed." ).arg ("ssh_channel_open_forward");
-                        emit ioErr ( channelConnections[i].creator, errorMsg, err );
+                    ssh_session tmp_session = ssh_new ();
+
+                    if (!tmp_session) {
+                        QString error_msg = tr ("Cannot create SSH session.");
 #ifdef DEBUG
-                        x2goDebug<<errorMsg.left (errorMsg.size () - 1)<<": "<<err<<endl;
+                        x2goDebug << error_msg;
 #endif
+                        emit ioErr (channelConnections[i].creator, error_msg, "");
                     }
-#ifdef DEBUG
-                    else
+                    else {
+                        QByteArray tmp_BA = channelConnections.at (i).forwardHost.toLocal8Bit ();
+                        ssh_options_set (tmp_session, SSH_OPTIONS_HOST, tmp_BA.data ());
+
+                        /* The host and port might be a shorthand and zero, so fetch the actual data. */
+                        if (ssh_options_parse_config (tmp_session, NULL) < 0) {
+                            x2goDebug << "Warning: unable to parse the SSH config file.";
+                        }
+
+                        unsigned int inferred_port = 0;
+                        ssh_options_get_port (tmp_session, &inferred_port);
+                        x2goDebug << "Temporary session port after config file parse: " << inferred_port;
+
+                        char *inferred_host = NULL;
+                        ssh_options_get (tmp_session, SSH_OPTIONS_HOST, &inferred_host);
+                        x2goDebug << "Temporary session host after config file parse: " << inferred_host;
+
+                        channelConnections[i].forwardHost = QString (inferred_host);
+                        channelConnections[i].forwardPort = static_cast<int> (inferred_port);
+
+                        ssh_string_free_char (inferred_host);
+                        ssh_free (tmp_session);
+                    }
+
                     {
-                        x2goDebug<<"New channel forwarded."<<endl;
+                        QByteArray tmp_BA_forward = channelConnections.at (i).forwardHost.toLocal8Bit ();
+                        QByteArray tmp_BA_local = channelConnections.at (i).localHost.toLocal8Bit ();
+
+                        if ( ssh_channel_open_forward ( channel,
+                                                        tmp_BA_forward.data (),
+                                                        channelConnections.at ( i ).forwardPort,
+                                                        tmp_BA_local.data (),
+                                                        channelConnections.at ( i ).localPort ) != SSH_OK )
+                        {
+                            QString err=ssh_get_error ( my_ssh_session );
+                            QString errorMsg=tr ( "%1 failed." ).arg ("ssh_channel_open_forward");
+                            emit ioErr ( channelConnections[i].creator, errorMsg, err );
+#ifdef DEBUG
+                            x2goDebug<<errorMsg.left (errorMsg.size () - 1)<<": "<<err<<endl;
+#endif
+                        }
+#ifdef DEBUG
+                        else
+                        {
+                            x2goDebug<<"New channel forwarded."<<endl;
+                        }
                     }
 #endif
                 }

--
Alioth's /srv/git/code.x2go.org/x2goclient.git//..//_hooks_/post-receive-email on /srv/git/code.x2go.org/x2goclient.git


More information about the x2go-commits mailing list