Git Product home page Git Product logo

Comments (12)

djphoenix avatar djphoenix commented on July 22, 2024

Confirmed on Mac OS X (1.6.0 homebrew, both _fromfile and _frommemory).

from libssh2.

mohisan avatar mohisan commented on July 22, 2024

Hi djphoenix,
do you know a release, where libssh2_userauth_publickey_fromfile works well.
I really need this function for a project.

Thanks

from libssh2.

djphoenix avatar djphoenix commented on July 22, 2024

Oh, got it work, I was unnecessary added an zero byte at the end of username.
@mohisan try to use _ex version with master branch. It works for me. Also I was not use public_key param, libssh2 calculates it from private key.

from libssh2.

mohisan avatar mohisan commented on July 22, 2024

Hi djphoenix,
I tried to do what you have mentioned in your last comment, that is: _libssh2_userauth_publickey_fromfile_ex_ from latest branch, both with and without public key param.
In the main site of libssh2 (https://github.com/libssh2/libssh2), I selected the tab page _<> code_ and downloaded the already selected _Branch: Master_.
I have built the project against MinGW Makefiles and using OpenSSL.
I don't want to show you a code snippet but the complete code I am using.

Code flow:

  1. Establishing TCP Connection
  2. Initializing libssh2 [ see method below _void MySSH2Connection::initialize()_ ]
  3. calling _libssh2_userauth_publickey_fromfile_ex_ through
    _MySSH2Connection::authenticateByKeys_ [ see also method below ]
...
...
// until here the TCP connection is already established
    try
    {
        // the constructor will call MySSH2Connection::initialize(), see method below
        MySSH2Connection ssh2Connection( mySocket.socketDescriptor(), this );
        // authenticate by public key.
        // strUserName, strPrivate, strPublic contains user name, private & public key
        ssh2Connection.authenticateByKeys( strUserName, strPrivate, strPublic );
        ....
        ....
    }
    catch( MyException& e )
    {
        myStateTextEdit->appendHtml("<font color=\"red\">" +
                       QString( e.what() ) + "</font>" );
    }
....
....

Ignore the _emit signalMessageInfo(), it is just a process information for
internal use to write in a log file, as well as _throw MyException

/*!
 * \copydoc MySSH2Connection::initialize
 */
void MySSH2Connection::initialize()
{
    // libssh2_init returns 0 if succeeded, or a negative value for error.
    int iResult = libssh2_init( 0 );
    if( iResult == 0 /*succeeded*/)
    {
        emit signalMessageInfo( "Initialisierung 1. Schritt von 3 erledigt." );

        //Create a session instance
        mySession = libssh2_session_init();
        if( mySession )
        {
            emit signalMessageInfo( "Initialisierung 2. Schritt von 3 erledigt." );

            // tell libssh2 we are blocking
            libssh2_session_set_blocking( mySession, 1 );

            // start it up. This will trade welcome banners, exchange keys,
            // and setup crypto, compression, and MAC layers
            iResult = libssh2_session_handshake( mySession, mySocketDescriptor );
            if( iResult == 0 /*succeeded*/ )
            {
                emit signalMessageInfo( "Initialisierung 3. Schritt von 3 erledigt." );
                libssh2_hostkey_hash( mySession, LIBSSH2_HOSTKEY_HASH_SHA1 );
            }
            else
                throw MyException( "handshake." );
        }
        else throw MyException( "session" );
    }
    else
        throw MyException( "init." );
}

And now the authenticateByKeys function, which calls _libssh2_userauth_publickey_fromfile_ex_
and always fails with the return value -19 or _LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED_

/*!
 * \copydoc MySSH2Connection::authenticateByKeys
 */
bool MySSH2Connection::authenticateByKeys( const QString& strUserName,
                           const QString& strPrivateKeyPath,
                           const QString& strPublicKeyPath )
{
    if( ! mySession )
        throw MyException( "session." );

    const char* caUser = myStrUser.toLatin1().constData();
    const char* caPrivate = strPrivateKeyPath.toLatin1().constData();
    const char* caPublic = strPublicKeyPath .toLatin1().constData();
    // authenticate by public key.
    int iResult = libssh2_userauth_publickey_fromfile_ex( mySession, caUser, 
                        (unsigned int) myStrUser.length(),
                        caPublic, caPrivate, NULL );
    if( iResult )
    {
        throw MyException( QString( "Authentication by public key failed. %1" ).
                   arg( iResult ) );
    }
    else
        emit signalMessageInfo( "Authentication by public key succeeded" );

    return true;
}

As I mentioned, I always get error result -19.
Do you see anything wrong?
As I wrote in previous comments, authentication by password works fine.

from libssh2.

alamaison avatar alamaison commented on July 22, 2024

On Mon, 11 Jan 2016 10:18 mohisan [email protected] wrote:

Hi djphoenix,
I tried to do what you have mentioned in your last comment, that is:
libssh2_userauth_publickey_fromfile_ex from latest branch, both with
and without public key param.
In the main site of libssh2 (https://github.com/libssh2/libssh2), I
selected the tab page <> code and downloaded the already selected Branch:
Master
.
I have built the project against MinGW Makefiles and using OpenSSL.
I don't want to show you a code snippet but the complete code I am using.

Code flow:

  1. Establishing TCP Connection
  2. Initializing libssh2 [ see method below void
    MySSH2Connection::initialize()
    ]
  3. calling libssh2_userauth_publickey_fromfile_ex through
    MySSH2Connection::authenticateByKeys [ see also method below ]

...
...
// until here the TCP connection is already established
try
{
// the constructor will call MySSH2Connection::initialize(), see method below
MySSH2Connection ssh2Connection( mySocket.socketDescriptor(), this );
// authenticate by public key.
// strUserName, strPrivate, strPublic contains user name, private & public key
ssh2Connection.authenticateByKeys( strUserName, strPrivate, strPublic );
....
....
}
catch( MyException& e )
{
myStateTextEdit->appendHtml("<font color="red">" +
QString( e.what() ) + "" );
}
....
....

Ignore the emit signalMessageInfo(), it is just a process information
for
internal use to write in a log file, as well as throw MyException

/*!

  • \copydoc MySSH2Connection::initialize
    _/
    void MySSH2Connection::initialize()
    {
    // libssh2_init returns 0 if succeeded, or a negative value for error.
    int iResult = libssh2_init( 0 );
    if( iResult == 0 /_succeeded*/)
    {
    emit signalMessageInfo( "Initialisierung 1. Schritt von 3 erledigt." );

    //Create a session instance
    mySession = libssh2_session_init();
    if( mySession )
    {
        emit signalMessageInfo( "Initialisierung 2. Schritt von 3 erledigt." );
    
        // tell libssh2 we are blocking
        libssh2_session_set_blocking( mySession, 1 );
    
        // start it up. This will trade welcome banners, exchange keys,
        // and setup crypto, compression, and MAC layers
        iResult = libssh2_session_handshake( mySession, mySocketDescriptor );
        if( iResult == 0 /*succeeded*/ )
        {
            emit signalMessageInfo( "Initialisierung 3. Schritt von 3 erledigt." );
            libssh2_hostkey_hash( mySession, LIBSSH2_HOSTKEY_HASH_SHA1 );
        }
        else
            throw MyException( "handshake." );
    }
    else throw MyException( "session" );
    

    }
    else
    throw MyException( "init." );
    }

And now the authenticateByKeys function, which calls
libssh2_userauth_publickey_fromfile_ex
and always fails with the return value -19 or
LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED

/*!

  • \copydoc MySSH2Connection::authenticateByKeys
    */
    bool MySSH2Connection::authenticateByKeys( const QString& strUserName,
    const QString& strPrivateKeyPath,
    const QString& strPublicKeyPath )
    {
    if( ! mySession )
    throw MyException( "session." );

    const char* caUser = myStrUser.toLatin1().constData();

I don't know if this is your issue, but username in SFTP should be given in
UTF8. Also, I'm not familiar with QTString, but it looks a lot like you are
storing a pointer to a temporary string's bytes and then using it later.
That can't be good.

Alex

from libssh2.

mohisan avatar mohisan commented on July 22, 2024

Hi Alex (alamaison),
I was also using hardcoded strings

...
int iResult = libssh2_userauth_publickey_fromfile_ex( mySession,
                "testUser",                          // the user name
                (unsigned int)myStrUser.length(),    // length of the user name string
                "keys/rdtest",                       // path to public key
                "keys/private/rdtest.rsa",           // path to private key
                NULL );                              // no passphrase
...

When I use _libssh2_userauth_password_ex()_, then it works fine, also with QString.
Since the pointer I am storing are in the same scope, they will work fine and I am not using them if I exit the scope. As I said, authentication by password works fine.
Have you tried a public key authentication? If yes, did it work successfully for you?

Thank you for your answer Alex, I apreciate it.

mohisan

from libssh2.

alamaison avatar alamaison commented on July 22, 2024

When I use * libssh2_userauth_password_ex()*, then it works fine

Then the problem must be either with the contents of the key files, or how you pass them. Can you enable libssh2 debug living and attach

from libssh2.

alamaison avatar alamaison commented on July 22, 2024

Sorry, fat fingers on my phone keyboard. Can you enable libssh2 debug logging and attach the log?

from libssh2.

avengerx avatar avengerx commented on July 22, 2024

Struggling with this issue with cygwin 2.11.2 for a while now. But it has libssh2 1.7.0 still, built with no trace support... Will try to build 1.8.0 and see what happens.

Can't use RSA nor ECDSA keys with it, at least. I get error -19 if I provide both public and private keys, and -16 if I provide only private key ((error codes here)[https://libssh2.org/libssh2_userauth_publickey_frommemory.html].

Rsa key created with ssh-keygen -t rsa (or ecdsa) from cygwin's openssh 7.9p1 (linked against OpenSSL 1.0.2p).

Not sure I will be able to build libssh2 under cygwin by myself, but if I can progress in that, I'll share my findings.

I started trying on Net::SSH2 perl module and went down to the ssh2.c sample to minimize the scenario. Getting the proper libssh2_config.h was another story (for the curious, I needed to grab cygwin source package for libssh, apply the patches and ./configure --prefix=/usr to have it generated).

from libssh2.

avengerx avatar avengerx commented on July 22, 2024

Okay, 1.8.0 built. Trace support included, still fails pubkey auth.

Build went smooth just as 1.7.0 would, applying the cygwin specific patch which just removes -DLIBSSH2_WIN32 from configure.ac).

For the record, after building it, I only could reliably run the simple ssh2.c sample with the custom build if I statically linked during build. Cygwin happens, I guess, so the compile line turned to:

gcc -o sshc sshc.c -static -I${PREFIX}/include -L${PREFIX}/lib -lssh2 -L/usr/lib -lcrypto -lz

Where ${PREFIX} is whatever you provided to ./configure at build time.

And then the output I got from trace:

Authentication methods: publickey,keyboard-interactive
[libssh2] 0.866438 Userauth: Loading public key file: ~/.ssh/id_rsa.pub
[libssh2] 0.866651 Userauth: Attempting publickey authentication
=> libssh2_transport_write plain (338 bytes)
<chunk of hexdump data... should I share this block?>
[libssh2] 0.866733 Socket: Sent 384/384 bytes at 0x600009f80
=> libssh2_transport_write send() (384 bytes)
<another chunk of hexdump data...>
[libssh2] 0.866786 Transport: Looking for packet of type: 52
[libssh2] 0.866789 Transport: Looking for packet of type: 51
[libssh2] 0.866793 Transport: Looking for packet of type: 60
[libssh2] 0.866799 Failure Event: -37 - Would block
[libssh2] 1.034728 Transport: Looking for packet of type: 52
[libssh2] 1.034743 Transport: Looking for packet of type: 51
[libssh2] 1.034748 Transport: Looking for packet of type: 60
[libssh2] 1.034757 Socket: Recved 336/16384 bytes to 0x600005f40+0
=> libssh2_transport_read() raw (336 bytes)
<yet another block of hexdump data...>
=> libssh2_transport_read() plain (295 bytes)
<and more hexdump data...>
[libssh2] 1.034848 Transport: Packet type 60 received, length=295
[libssh2] 1.034853 Transport: Looking for packet of type: 52
[libssh2] 1.034856 Transport: Looking for packet of type: 51
[libssh2] 1.034859 Transport: Looking for packet of type: 60
[libssh2] 1.034864 Userauth: Loading private key file: ~/.ssh/id_rsa
[libssh2] 1.035078 Failure Event: -16 - Unable to initialize private key from file
[libssh2] 1.035084 Failure Event: -19 - Callback returned error
Return status: -19
        Authentication by public key failed!
[libssh2] 1.035104 Transport: Disconnecting: reason=11, desc=Normal Shutdown, Thank you for playing, lang=

Again, the rsa key was generated by simple ssh-keygen -t rsa, empty passphrase. I also created a passphrase-filled key for no avail. I always tried the keys to a test host after adding to authorized keys and trying with ssh -i <key> <user>@<host> before trying with the simple ssh2.c test.

from libssh2.

avengerx avatar avengerx commented on July 22, 2024

Good news.
Just built off master (currently at ~31aea1ec68d50f37b544f4e0157cd1657084b689) and...

[libssh2] 0.375031 Userauth: Loading private key file: ~/.ssh/id_rsa_phrased
[libssh2] 0.584330 Userauth: Computing RSA keys from private key data
[libssh2] 0.585424 Userauth: Attempting publickey authentication -- phase 2
=> libssh2_transport_write plain (613 bytes)
<hex chunk>
[libssh2] 0.585555 Socket: Sent 656/656 bytes at 0x600009fa8
=> libssh2_transport_write send() (656 bytes)
<hex chunk>
[libssh2] 0.585642 Transport: Looking for packet of type: 52
[libssh2] 0.585646 Transport: Looking for packet of type: 51
[libssh2] 0.585657 Failure Event: -37 - Would block requesting userauth list
[libssh2] 0.750282 Transport: Looking for packet of type: 52
[libssh2] 0.750295 Transport: Looking for packet of type: 51
[libssh2] 0.750304 Socket: Recved 48/16384 bytes to 0x600005f68+0
=> libssh2_transport_read() raw (48 bytes)
<hex chunk>
=> libssh2_transport_read() plain (1 bytes)
0000: 34                                               : 4
[libssh2] 0.750328 Transport: Packet type 52 received, length=1
[libssh2] 0.750332 Transport: Looking for packet of type: 52
[libssh2] 0.750335 Userauth: Publickey authentication successful
        Authentication by public key succeeded.
[libssh2] 0.750347 Conn: Allocated new channel ID#0

Tested keys:

  • rsa, empty passprhase
  • rsa, with passphrase
  • ecdsa, empty passprhase

So, all great! Currently craving for the next release of libssh2!

Still, I wonder how could I generate SSH keys compatible with versions 1.7.0 and 1.8.0. I believe this issue can be closed, as it is already fixed in non-released current version of libssh2.

from libssh2.

willco007 avatar willco007 commented on July 22, 2024

You can generate RSA keys that work with both versions by using the old key format when generating keys using ssh. As you noted, master now supports the new key openssh format which resolves this issue so I'll go ahead and close this.

from libssh2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.