csftplibssh2libssh

C - libssh and sftp - client/server - creating sftp session hangs


I implemented a client/server communication over SSH with libssh. I also want to implement file upload from client to the server now and have been following the doc for it.

However, it hangs on the call sftp = sftp_new(session);. Do I have to explicitly open another ssh_channel for it on the server side as well? I only added the sftp code on the client so far.


Solution

  • For all who are struggling as well, I finally found the solution.

    I found on the thread of this question that libssh/sftp.h does have separate functions for the server at the very end. To enable them, you have to use #define WITH_SERVER.

    Despite the comment on the doc that you don't have to handle channels yourself, you do have to open a new channel on the server side for the SFTP communication. Implementing this worked for me:

    while ((msg = ssh_message_get(session)))
    {
    
        if (ssh_message_type(msg) == SSH_REQUEST_CHANNEL_OPEN && ssh_message_subtype(msg) == SSH_CHANNEL_SESSION)
        {
            printf("[+] Got channel open request, opening new channel for sftp\n");
            sftpChannel = ssh_message_channel_request_open_reply_accept(msg);
            ssh_message_free(msg);
        }
    
        if (ssh_message_type(msg) == SSH_REQUEST_CHANNEL && ssh_message_subtype(msg) == SSH_CHANNEL_REQUEST_SUBSYSTEM)
        {
            if (!strcmp(ssh_message_channel_request_subsystem(msg), "sftp"))
            {
                ssh_message_channel_request_reply_success(msg);
                ssh_message_free(msg);
    
                // setup SFTP session
                sftp_session sftp = sftp_server_new(session, sftpChannel);
                if (sftp == NULL)
                {
                    fprintf(stderr, "Error allocating SFTP session: %s\n", ssh_get_error(session));
                }                           
                int rc = sftp_server_init(sftp);
                if (rc != SSH_OK)
                {
                   fprintf(stderr, "Error initializing SFTP session: %i.\n", sftp_get_error(sftp));
                   sftp_free(sftp);
                }
    
                // handle communication...
             }
        }
    }