[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Trying to debug segfault


On 01/26/2018 02:25 AM, Andreas Schneider wrote:
On Thursday, 25 January 2018 18:57:28 CET Orion Poplawski wrote:
I'm trying to debug a segfault in libssh used by x2goclient.


Hi,

I'm starting with this valgrind report:

x2go-DEBUG-../src/sshmasterconnection.cpp:2199> New exec channel created.

I've just looked at

https://code.x2go.org/gitweb?p=x2goclient.git;a=blob;f=src/
sshmasterconnection.cpp;h=be327c683d28e0e054c570281c1cb2854132d7a6;hb=refs/
heads/master

I see no call for ssh_init() nor ssh_finalize()

[2018/01/25 10:05:34.194015, 3] ssh_socket_un
==22928==    by 0x4CA6BA: SshMasterConnection::sshConnect()
(sshmasterconnection.cpp:847)
==22928==    by 0x4D8203: SshMasterConnection::run()
(sshmasterconnection.cpp:637) ==22928==    by 0x71B511E:
QThreadPrivate::start(void*) (qthread_unix.cpp:338) ==22928==    by
0x762BE24: start_thread (pthread_create.c:308)

Esepecially, I don't see:

#include <libssh/callbacks.h>
..
ssh_threads_set_callbacks(ssh_threads_get_pthread());
ssh_init();


http://api.libssh.org/master/libssh_tutor_threads.html


Maybe that is done somewhere else, but make sure it is done. I would suggest
to set a gdb watchpoint on that poll pointer so see when it is being freed ...

It's done here:

https://code.x2go.org/gitweb?p=x2goclient.git;a=blob;f=src/onmainwindow.cpp;h=fdc043bcabe034c422c4ea3494438b6e7417acf1;hb=HEAD#l13087

The segfault seems to be triggered by my changes to libssh and/or x2goclient to try to better support SSH_AUTH_PARTIAL. Perhaps you can see something wrong with these changes - which I've attached.

I submitted the libssh change here -

https://bugs.libssh.org/T82

Although now that I look closer, maybe I shouldn't be freeing the agent state...

--
Orion Poplawski
Manager of NWRA Technical Systems          720-772-5637
NWRA, Boulder/CoRA Office             FAX: 303-415-9702
3380 Mitchell Lane                       orion@xxxxxxxx
Boulder, CO 80301                 https://www.nwra.com/
diff --git a/src/auth.c b/src/auth.c
index abfb594..9480552 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -846,6 +846,12 @@ int ssh_userauth_agent(ssh_session session,
                 ssh_agent_state_free (session->agent_state);
                 session->agent_state = NULL;
                 return rc;
+            } else if (rc == SSH_AUTH_PARTIAL) {
+                SSH_LOG(SSH_LOG_INFO,
+                        "Server accepted public key but requires more authentication");
+                ssh_agent_state_free (session->agent_state);
+                session->agent_state = NULL;
+                return SSH_AUTH_PARTIAL;
             } else if (rc != SSH_AUTH_SUCCESS) {
                 SSH_LOG(SSH_LOG_INFO,
                         "Server accepted public key but refused the signature");
@@ -943,7 +949,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
 #ifndef _WIN32
         /* Try authentication with ssh-agent first */
         rc = ssh_userauth_agent(session, username);
-        if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_AGAIN) {
+        if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_AGAIN || rc == SSH_AUTH_PARTIAL) {
             return rc;
         }
 #endif
diff --git a/src/socket.c b/src/socket.c
index 95dedbb..f94be0e 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -569,7 +569,7 @@ static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer,
 #endif
   s->write_wontblock = 0;
   /* Reactive the POLLOUT detector in the poll multiplexer system */
-  if(s->poll_out){
+  if(ssh_poll_get_ctx(s->poll_out)){
       SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket");
   	ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT);
   }
diff --git a/src/sshmasterconnection.cpp b/src/sshmasterconnection.cpp
index be327c6..bd8d18e 100644
--- a/src/sshmasterconnection.cpp
+++ b/src/sshmasterconnection.cpp
@@ -1244,12 +1244,14 @@ bool SshMasterConnection::userChallengeAuth()
 }
 
 
-bool SshMasterConnection::userAuthWithPass()
+bool SshMasterConnection::userAuthWithPass(bool partial)
 {
     bool ret = false;
 
-    // Populate the userauth_list
-    ssh_userauth_none(my_ssh_session, NULL);
+    // Populate the userauth_list, unless we're already partially authenticated
+    if (!partial) {
+        ssh_userauth_none(my_ssh_session, NULL);
+    }
 
     int method = ssh_userauth_list(my_ssh_session, NULL);
 
@@ -1316,11 +1318,12 @@ bool SshMasterConnection::userAuthWithPass()
 }
 
 
-bool SshMasterConnection::userAuthAuto()
+int SshMasterConnection::userAuthAuto()
 {
-    int rc = ssh_userauth_autopubkey ( my_ssh_session, "" );
+    x2goDebug << "userAuthAuto calling ssh_userauth_publickey_auto()" << endl;
+    int rc = ssh_userauth_publickey_auto ( my_ssh_session, NULL, "" );
     int i=0;
-    while(rc != SSH_AUTH_SUCCESS)
+    while(rc != SSH_AUTH_SUCCESS && rc != SSH_AUTH_PARTIAL)
     {
         if (SSH_AUTH_DENIED == rc) {
           /* No need to continue, all keys have been rejected by the server. */
@@ -1343,23 +1346,23 @@ bool SshMasterConnection::userAuthAuto()
         }
         if(keyPhrase==QString::null)
             break;
-        rc = ssh_userauth_autopubkey ( my_ssh_session, keyPhrase.toLatin1() );
+        rc = ssh_userauth_publickey_auto ( my_ssh_session, NULL, keyPhrase.toLatin1() );
         if(i++==2)
         {
             break;
         }
     }
 
-    if ( rc != SSH_AUTH_SUCCESS )
+    if ( rc != SSH_AUTH_SUCCESS && rc != SSH_AUTH_PARTIAL )
     {
         QString err=ssh_get_error ( my_ssh_session );
         authErrors<<err;
 #ifdef DEBUG
         x2goDebug << "userAuthAuto failed:" << err << " (code " << rc << ")" << endl;
 #endif
-        return false;
+        return rc;
     }
-    return true;
+    return rc;
 }
 
 void SshMasterConnection::setKeyPhrase(QString phrase)
@@ -1371,7 +1374,7 @@ void SshMasterConnection::setKeyPhrase(QString phrase)
 }
 
 
-bool SshMasterConnection::userAuthWithKey()
+int SshMasterConnection::userAuthWithKey()
 {
 #ifdef DEBUG
     x2goDebug<<"Trying to authenticate user with private key.";
@@ -1408,7 +1411,7 @@ bool SshMasterConnection::userAuthWithKey()
 
         ssh_key_free (priv_key);
 
-        return (false);
+        return (SSH_AUTH_ERROR);
     }
     else if (SSH_OK != rc) {
         x2goDebug << "Failed to get private key from " << keyName << "; trying to query passphrase.";
@@ -1425,7 +1428,7 @@ bool SshMasterConnection::userAuthWithKey()
       }
       else {
         /* Don't pass invalid files to privatekey_from_file () - it crashes in this case. */
-        return (false);
+        return (SSH_AUTH_ERROR);
       }
     }
     ssh_private_key priv_key = privatekey_from_file (my_ssh_session, tmp_ba.data (), 0, NULL);
@@ -1483,7 +1486,7 @@ bool SshMasterConnection::userAuthWithKey()
 #endif
         if ( autoRemove )
             QFile::remove ( keyName );
-        return false;
+        return (SSH_AUTH_ERROR);
     }
 
 #if LIBSSH_VERSION_INT >= SSH_VERSION_INT (0, 6, 0)
@@ -1514,7 +1517,7 @@ bool SshMasterConnection::userAuthWithKey()
 #endif
         if ( autoRemove )
             QFile::remove ( keyName );
-        return false;
+        return (SSH_AUTH_ERROR);
     }
 
 #if LIBSSH_VERSION_INT >= SSH_VERSION_INT (0, 6, 0)
@@ -1525,8 +1528,7 @@ bool SshMasterConnection::userAuthWithKey()
     ssh_key_free (pub_key);
     pub_key = NULL;
 
-    /* FIXME: handle SSH_AUTH_PARTIAL correctly! */
-    if (SSH_AUTH_SUCCESS != rc) {
+    if (rc != SSH_AUTH_SUCCESS && rc != SSH_AUTH_PARTIAL ) {
         x2goDebug << "Unable to authenticate with public key.";
 
         ssh_key_free (priv_key);
@@ -1536,7 +1538,7 @@ bool SshMasterConnection::userAuthWithKey()
             QFile::remove (keyName);
         }
 
-        return (false);
+        return (SSH_AUTH_ERROR);
     }
 
     do {
@@ -1560,8 +1562,7 @@ bool SshMasterConnection::userAuthWithKey()
     if ( autoRemove )
         QFile::remove ( keyName );
 
-    /* FIXME: handle SSH_AUTH_PARTIAL correctly! */
-    if ( rc != SSH_AUTH_SUCCESS )
+    if ( rc != SSH_AUTH_SUCCESS && rc != SSH_AUTH_PARTIAL )
     {
         QString err=ssh_get_error ( my_ssh_session );
         authErrors<<err;
@@ -1570,9 +1571,9 @@ bool SshMasterConnection::userAuthWithKey()
         x2goDebug<<"userAuthWithKey failed:" <<err<<endl;
 #endif
 
-        return false;
+        return (SSH_AUTH_ERROR);
     }
-    return true;
+    return (rc);
 }
 
 bool SshMasterConnection::userAuthKrb()
@@ -1829,17 +1830,22 @@ bool SshMasterConnection::checkLogin()
 
 bool SshMasterConnection::userAuth()
 {
+    int rc = 0;
     if (kerberos)
         return userAuthKrb();
     if ( autologin && key=="" )
-        if ( userAuthAuto() )
+    {
+        rc = userAuthAuto();
+        if ( rc == SSH_AUTH_SUCCESS )
             return true;
+    }
     if ( key!="" )
     {
-        if ( userAuthWithKey() )
+        rc = userAuthWithKey();
+        if ( rc == SSH_AUTH_SUCCESS )
             return true;
     }
-    return userAuthWithPass();
+    return userAuthWithPass(rc == SSH_AUTH_PARTIAL);
 }
 
 
diff --git a/src/sshmasterconnection.h b/src/sshmasterconnection.h
index ad6776b..70efb3f 100644
--- a/src/sshmasterconnection.h
+++ b/src/sshmasterconnection.h
@@ -125,9 +125,9 @@ public:
 
 private:
     bool sshConnect();
-    bool userAuthWithPass();
-    bool userAuthAuto();
-    bool userAuthWithKey();
+    bool userAuthWithPass(bool partial);
+    int userAuthAuto();
+    int userAuthWithKey();
     bool userChallengeAuth();
     bool checkLogin();
     bool userAuth();

Archive administrator: postmaster@lists.cynapses.org