[X2Go-Commits] x2goclient.git - master (branch) updated: 4.0.1.1-64-gac14ad2

X2Go dev team git-admin at x2go.org
Thu Dec 12 11:14:19 CET 2013


The branch, master has been updated
       via  ac14ad24e7a2d3d3fd08e61098769b5391f4ea8b (commit)
      from  a77d761dbb16d28206e7c2446654539935746e4e (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 ac14ad24e7a2d3d3fd08e61098769b5391f4ea8b
Author: Oleksandr Shneyder <o.shneyder at phoca-gmbh.de>
Date:   Wed Dec 11 19:55:31 2013 +0100

    Support for ChallengeResponseAuthentication (Google Authenticator)

-----------------------------------------------------------------------

Summary of changes:
 debian/changelog        |    1 +
 onmainwindow.cpp        |   17 ++++--
 onmainwindow.h          |    2 +-
 sshmasterconnection.cpp |  148 +++++++++++++++++++++++++++++++++++++++++++----
 sshmasterconnection.h   |    7 ++-
 sshprocess.cpp          |    2 +-
 6 files changed, 159 insertions(+), 18 deletions(-)

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index f8d5a5b..582891f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -60,6 +60,7 @@ x2goclient (4.0.1.2-0x2go2) UNRELEASED; urgency=low
       sessions.
     - Support for GSSApi(Kerberos 5) authentication. Using ssh/scp commands
       on Linux and Mac and plink/pscp on Windows.   
+    - Support for ChallengeResponseAuthentication (Google Authenticator)
 
   [ Heinrich Schuchardt ]
   * New upstream version (4.0.1.2):
diff --git a/onmainwindow.cpp b/onmainwindow.cpp
index 7a0a2a8..946e6ae 100644
--- a/onmainwindow.cpp
+++ b/onmainwindow.cpp
@@ -2853,8 +2853,8 @@ SshMasterConnection* ONMainWindow::startSshConnection ( QString host, QString po
 
     connect ( con, SIGNAL ( serverAuthError ( int,QString, SshMasterConnection* ) ),this,
               SLOT ( slotSshServerAuthError ( int,QString, SshMasterConnection* ) ) );
-    connect ( con, SIGNAL ( needPassPhrase(SshMasterConnection*)),this,
-              SLOT ( slotSshServerAuthPassphrase(SshMasterConnection*)) );
+    connect ( con, SIGNAL ( needPassPhrase(SshMasterConnection*, bool)),this,
+              SLOT ( slotSshServerAuthPassphrase(SshMasterConnection*, bool)) );
     connect ( con, SIGNAL ( userAuthError ( QString ) ),this,SLOT ( slotSshUserAuthError ( QString ) ) );
     connect ( con, SIGNAL ( connectionError ( QString,QString ) ), this,
               SLOT ( slotSshConnectionError ( QString,QString ) ) );
@@ -2946,11 +2946,20 @@ void ONMainWindow::slotServSshConnectionOk(QString server)
     con->executeCommand( "export HOSTNAME && x2golistsessions", this, SLOT (slotListAllSessions ( bool,QString,int ) ));
 }
 
-void ONMainWindow::slotSshServerAuthPassphrase(SshMasterConnection* connection)
+void ONMainWindow::slotSshServerAuthPassphrase(SshMasterConnection* connection, bool verificationCode)
 {
     bool ok;
+    QString message;
+    if(verificationCode)
+    {
+        message=tr("Verification code:");
+    }
+    else
+    {
+        message=tr("Enter passphrase to decrypt a key");
+    }
     QString phrase=QInputDialog::getText(0,connection->getUser()+"@"+connection->getHost()+":"+QString::number(connection->getPort()),
-                                         tr("Enter passphrase to decrypt a key"),QLineEdit::Password,QString::null, &ok);
+                                         message,QLineEdit::Password,QString::null, &ok);
     if(!ok)
     {
         phrase=QString::null;
diff --git a/onmainwindow.h b/onmainwindow.h
index 7e51291..6f26417 100644
--- a/onmainwindow.h
+++ b/onmainwindow.h
@@ -941,7 +941,7 @@ private slots:
     void showSessionStatus();
     void slotSshConnectionError ( QString message, QString lastSessionError );
     void slotSshServerAuthError ( int error, QString sshMessage, SshMasterConnection* connection );
-    void slotSshServerAuthPassphrase ( SshMasterConnection* connection );
+    void slotSshServerAuthPassphrase ( SshMasterConnection* connection, bool verificationCode );
     void slotSshUserAuthError ( QString error );
     void slotSshConnectionOk();
     void slotServSshConnectionOk(QString server);
diff --git a/sshmasterconnection.cpp b/sshmasterconnection.cpp
index 9a81853..d705f7c 100644
--- a/sshmasterconnection.cpp
+++ b/sshmasterconnection.cpp
@@ -47,7 +47,7 @@
 #define PROXYTUNNELPORT 44444
 
 #undef DEBUG
-#define DEBUG
+// #define DEBUG
 
 #undef SSH_DEBUG
 // #define SSH_DEBUG
@@ -181,6 +181,7 @@ SshMasterConnection::SshMasterConnection (QObject* parent, QString host, int por
     reverseTunnel=false;
     mainWnd=(ONMainWindow*) parent;
     kerberos=krblogin;
+    challengeAuthVerificationCode=QString::null;
 #ifdef DEBUG
     if (kerberos)
     {
@@ -352,9 +353,13 @@ SshMasterConnection* SshMasterConnection::reverseTunnelConnection ( SshProcess*
             proxypassword, proxykey, proxyautologin, localProxyPort );
     con->kerberos=kerberos;
 
+    con->setVerficationCode(challengeAuthVerificationCode);
+
     connect ( con,SIGNAL ( ioErr ( SshProcess*,QString,QString ) ),this,SIGNAL ( ioErr ( SshProcess*,QString,QString ) ) );
     connect ( con,SIGNAL ( stdErr ( SshProcess*,QByteArray ) ),this,SIGNAL ( stdErr ( SshProcess*,QByteArray ) ) );
     connect ( con,SIGNAL ( reverseListenOk ( SshProcess* ) ), this, SIGNAL ( reverseListenOk ( SshProcess* ) ) );
+    connect ( con,SIGNAL ( needPassPhrase(SshMasterConnection*, bool)), this, SIGNAL (needPassPhrase(SshMasterConnection*, bool)));
+
     con->keyPhrase=keyPhrase;
     con->keyPhraseReady=true;
     con->start();
@@ -383,8 +388,8 @@ void SshMasterConnection::run()
 
         connect ( sshProxy, SIGNAL ( serverAuthError ( int,QString,SshMasterConnection* ) ),this,
                   SLOT ( slotSshProxyServerAuthError ( int,QString, SshMasterConnection* ) ) );
-        connect ( sshProxy, SIGNAL ( needPassPhrase(SshMasterConnection*)),this,
-                  SIGNAL ( needPassPhrase(SshMasterConnection*)) );
+        connect ( sshProxy, SIGNAL ( needPassPhrase(SshMasterConnection*, bool)),this,
+                  SIGNAL ( needPassPhrase(SshMasterConnection*, bool)) );
         connect ( sshProxy, SIGNAL ( serverAuthAborted()),this,
                   SLOT ( slotSshProxyServerAuthAborted()) );
         connect ( sshProxy, SIGNAL ( userAuthError ( QString ) ),this,SLOT ( slotSshProxyUserAuthError ( QString ) ) );
@@ -800,20 +805,141 @@ int SshMasterConnection::serverAuth ( QString& errorMsg )
     return state;
 }
 
+void SshMasterConnection::setVerficationCode(QString code)
+{
+    challengeAuthVerificationCode=code;
+}
 
-bool SshMasterConnection::userAuthWithPass()
+
+bool SshMasterConnection::userChallengeAuth()
 {
-    int rc = ssh_userauth_password ( my_ssh_session, NULL, pass.toAscii() );
-    if ( rc != SSH_AUTH_SUCCESS )
+    int rez=ssh_userauth_kbdint(my_ssh_session, NULL, NULL);
+    int prompts;
+
+    switch( rez)
     {
+    case SSH_AUTH_INFO:
+        prompts=ssh_userauth_kbdint_getnprompts(my_ssh_session);
+#ifdef DEBUG
+        x2goDebug<<"Have prompts: "<<prompts<<endl;
+#endif
+        if(prompts)
+        {
+            const char *prompt= ssh_userauth_kbdint_getprompt(my_ssh_session,0,NULL);
+#ifdef DEBUG
+            x2goDebug<<"Prompt[0]: |"<<prompt<<"|"<<endl;
+#endif
+            QString pr=prompt;
+            if(pr=="Password: ")
+            {
+#ifdef DEBUG
+                x2goDebug<<"Password request"<<endl;
+#endif
+                ssh_userauth_kbdint_setanswer(my_ssh_session,0,pass.toAscii());
+                return userChallengeAuth();
+            }
+            if(pr=="Verification code: ")
+            {
+#ifdef DEBUG
+                x2goDebug<<"Verification code request"<<endl;
+#endif
+
+                challengeAuthPasswordAccepted=true;
+                if(challengeAuthVerificationCode == QString::null)
+                {
+                    keyPhraseReady=false;
+                    emit needPassPhrase(this, true);
+                    for(;;)
+                    {
+                        bool ready=false;
+                        this->usleep(200);
+                        keyPhraseMutex.lock();
+                        if(keyPhraseReady)
+                            ready=true;
+                        keyPhraseMutex.unlock();
+                        if(ready)
+                            break;
+                    }
+                    challengeAuthVerificationCode=keyPhrase;
+                    if(challengeAuthVerificationCode==QString::null)
+                    {
+                        authErrors<<tr("Authentication failed");
+                        return false;
+                    }
+                }
+                ssh_userauth_kbdint_setanswer(my_ssh_session,0,challengeAuthVerificationCode.toAscii());
+                return userChallengeAuth();
+            }
+            QString err=ssh_get_error ( my_ssh_session );
+            authErrors<<err;
+
+            return false;
+        }
+        else
+        {
+            return userChallengeAuth();
+        }
+    case SSH_AUTH_SUCCESS:
+#ifdef DEBUG
+        x2goDebug<<"Challenge auth ok"<<endl;
+#endif
+        return true;
+    case SSH_AUTH_DENIED:
+        if(!challengeAuthPasswordAccepted )
+        {
+            QString err=ssh_get_error ( my_ssh_session );
+            authErrors<<err;
+            return false;
+        }
+        else
+        {
+            challengeAuthVerificationCode=QString::null;
+            //try with another verification code
+            return userChallengeAuth();
+        }
+    default:
         QString err=ssh_get_error ( my_ssh_session );
         authErrors<<err;
+
+        return false;
+    }
+    return false;
+
+}
+
+
+bool SshMasterConnection::userAuthWithPass()
+{
+    int method = ssh_userauth_list(my_ssh_session, NULL);
+
+    if (method& SSH_AUTH_METHOD_INTERACTIVE)
+    {
 #ifdef DEBUG
-        x2goDebug<<"userAuthWithPass failed:" <<err<<endl;
+        x2goDebug<<"Challenge authentication"<<endl;
 #endif
-        return false;
+        challengeAuthPasswordAccepted=false;
+        return userChallengeAuth();
     }
-    return true;
+
+    if (method & SSH_AUTH_METHOD_PASSWORD)
+    {
+#ifdef DEBUG
+        x2goDebug<<"Password authentication"<<endl;
+#endif
+        int rc = ssh_userauth_password ( my_ssh_session, NULL, pass.toAscii() );
+        if ( rc != SSH_AUTH_SUCCESS )
+        {
+            QString err=ssh_get_error ( my_ssh_session );
+            authErrors<<err;
+#ifdef DEBUG
+            x2goDebug<<"userAuthWithPass failed:" <<err<<endl;
+#endif
+            return false;
+        }
+        return true;
+    }
+
+    return false;
 }
 
 
@@ -826,7 +952,7 @@ bool SshMasterConnection::userAuthAuto()
         if(!reverseTunnel)
         {
             keyPhraseReady=false;
-            emit needPassPhrase(this);
+            emit needPassPhrase(this, false);
             for(;;)
             {
                 bool ready=false;
@@ -901,7 +1027,7 @@ bool SshMasterConnection::userAuthWithKey()
         if(!reverseTunnel)
         {
             keyPhraseReady=false;
-            emit needPassPhrase(this);
+            emit needPassPhrase(this, false);
             for(;;)
             {
                 bool ready=false;
diff --git a/sshmasterconnection.h b/sshmasterconnection.h
index dda9772..8a8c6a2 100644
--- a/sshmasterconnection.h
+++ b/sshmasterconnection.h
@@ -113,12 +113,14 @@ private:
     bool userAuthWithPass();
     bool userAuthAuto();
     bool userAuthWithKey();
+    bool userChallengeAuth();
     bool userAuth();
     bool userAuthKrb();
     void channelLoop();
     void finalize(int arg1);
     void copy();
     int serverAuth(QString& errorMsg);
+    void setVerficationCode(QString code);
 #ifdef Q_OS_WIN
     void parseKnownHosts();
 #endif
@@ -187,6 +189,9 @@ private:
     bool sshProxyReady;
     bool breakLoop;
 
+    bool challengeAuthPasswordAccepted;
+    QString challengeAuthVerificationCode;
+
 signals:
     void stdErr(SshProcess* caller, QByteArray data);
     void stdOut(SshProcess* caller, QByteArray data);
@@ -204,7 +209,7 @@ signals:
     void reverseListenOk(SshProcess* creator);
     void connectionOk( QString host);
 
-    void needPassPhrase(SshMasterConnection*);
+    void needPassPhrase(SshMasterConnection*, bool verificationCode);
 };
 
 
diff --git a/sshprocess.cpp b/sshprocess.cpp
index 69a057e..96d73e7 100644
--- a/sshprocess.cpp
+++ b/sshprocess.cpp
@@ -29,7 +29,7 @@
 #endif
 
 #undef DEBUG
-#define DEBUG
+// #define DEBUG
 
 #ifdef Q_OS_DARWIN
 #define KEEPALIVE_OPTION " -o ServerAliveInterval=60 "


hooks/post-receive
-- 
x2goclient.git (X2Go Client)

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 "x2goclient.git" (X2Go Client).




More information about the x2go-commits mailing list