1

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.

phoebus
  • 1,280
  • 1
  • 16
  • 36
  • 2
    The link you provide is pretty clear *"you don't handle directly the SSH channels"*. Please provide [A Minimal, Complete, and Verifiable Example (MCVE)](http://stackoverflow.com/help/mcve). – David C. Rankin Jun 29 '19 at 05:16
  • I've understood it the way that the client side (or whoever is uploading the file) isn't using any channels. But I'm clueless what to do on the server side where I have an initiated ssh_session and ssh_channel. Do I create another sftp_session there, or open another channel etc. – phoebus Jun 29 '19 at 05:37
  • 1
    sftp occurs over ssh. The underlying ssh connection from the client to the server handles access to the server. If you look several examples down they have an example where they create a file on the server. So unlike opening a TCP connection where you need an application running on the server listening for a connection, sshd handles that for sftp. – David C. Rankin Jun 29 '19 at 05:50
  • 2
    [libssh2 sftp example](https://www.libssh2.org/examples/sftp.html) and [libssh/examples/samplesftp.c](https://github.com/substack/libssh/blob/master/examples/samplesftp.c) should help. – David C. Rankin Jun 29 '19 at 05:56

1 Answers1

2

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...
         }
    }
}
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
phoebus
  • 1,280
  • 1
  • 16
  • 36
  • how do you avoid that requests are intercepeted by OpenSSH SFTP itself ? Because Libssh is using OpenSSH on port 22 so all requests are processed by OpenSSH SFTP rather than your Libssh SFTP server. – bruno bb Oct 16 '20 at 14:03