2

I am using libssh's C++ wrapper (libsshpp.hpp) and I'm trying to call ssh_scp_new for an SCP routine by giving it my ssh::Session variable but I get the following error:

cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’ for argument ‘1’ to ‘ssh_scp_struct* ssh_scp_new(ssh_session, int, const char*)’

I am able to get SCP working by completely not using the C++ ssh::Session class and going with the C example but obviously this is not my preferred workaround. Looking at libsshpp.hpp I was able to find a getCSession() function but it is only privately accessible and I'm not sure how to use it (or if it's even what I think it is).

Here is my sample code:

#include <iostream>
#include <fstream>

#include <libssh/libsshpp.hpp>

int main()
{
  int port      = 22;
  int verbosity = SSH_LOG_PROTOCOL;

  ssh::Session session;

  try
  {
    session.setOption(SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
    session.setOption(SSH_OPTIONS_PORT,          &port);
    session.setOption(SSH_OPTIONS_USER,          "user");
    session.setOption(SSH_OPTIONS_HOST,          "host");

    session.connect();

    if (session.isServerKnown() != SSH_SERVER_KNOWN_OK)
    {
      if (session.writeKnownhost() != SSH_OK)
      {
        std::cout << "writeKnownHost failed" << std::endl;
      }
      else
      {
        session.connect();
      }
    }

    if (session.userauthPassword("password") !=
        SSH_AUTH_SUCCESS)
    {
      std::cout << "Authentication Error" << std::endl;
    }

    ssh_scp scp;
    int     rc;

    // error cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’
    scp = ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
  }
  catch (ssh::SshException e)
  {
    std::cout << "Error during connection : ";
    std::cout << e.getError() << std::endl;
  }

  return 0;
}

How do I SCP send or receive a file with libssh using C++ methods?

Thanks!

Simog
  • 193
  • 3
  • 13

1 Answers1

1

As you can see the error. You have to decide to weather use ssh::Session class or ssh_session structure. The libssh library is a C library, and it has just a C++ wrapper (that may not contain all functionalities like in the original language) Here is how to send connect and send files using libssh library (current stable version 0.7.3) according to official documentation.

  1. Using ssh_session: (in C) -use ssh_new() to create a ssh_session pointer. -use int ssh_connect(ssh_session session) to connect. -use *int ssh_options_set ( ssh_session session, enum ssh_options_e type,const void * value )* Take a look on this documentation http://api.libssh.org/stable/group__libssh__session.html#ga7a801b85800baa3f4e16f5b47db0a73d -add your controls -send file using ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, "."); -free the connection using ssh_free(ssh_session session)

    //You can try this simple program (from official libssh tutorials)
    #include <libssh/libssh.h>
    #include <stdlib.h>
    #include <stdio.h>
    int scp_write(ssh_session session)
    {
        ssh_scp scp;
        int rc;
        scp = ssh_scp_new
            (session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
        if (scp == NULL)
        {
            fprintf(stderr, "Error allocating scp session: %s\n",         ssh_get_error(session));
            return SSH_ERROR;
        }
        rc = ssh_scp_init(scp);
        if (rc != SSH_OK)
        {
            fprintf(stderr, "Error initializing scp session: %s\n", ssh_get_error(session));
            ssh_scp_free(scp);
            return rc;
        }
        ssh_scp_close(scp);
        ssh_scp_free(scp);
        return SSH_OK;
    }
    
    int main(int argc, char* argv[])
        ssh_session my_ssh_session = ssh_new();
        if (my_ssh_session == NULL)
            return 1;
        scp_write(my_ssh_session );
        ssh_free(my_ssh_session);
        return 0;
    }     
    
  2. Using ssh::Session (in C++) well, no wrapper allows this currently :( .

Here is some useful examples for the use of libssh library. Hope it helps ! http://api.libssh.org/master/libssh_tutorial.html

  • 1
    As mentioned in my question, I am already able to get it working using C-style ssh_session (I even linked the same examples you suggested...). I'm asking if it's possible to use the ssh::Session class to get SCP working. – Simog Jun 05 '17 at 02:25
  • well, as you can notice the only classes implemented in C++ are Session http://api.libssh.org/stable/classssh_1_1Session.html and Channel http://api.libssh.org/master/classssh_1_1Channel.html. so if you stick to C++, you may try Channel class to send data, instead of SCP. – Spoutnick1990 Jun 05 '17 at 02:39
  • 1
    a non conventional solution would be to edit libssh code and rebuild it, after making getCSession() function public to use C functions to get a ssh_struct from the wrapper class. BUT this is dirty ! since you're modifying libssh code (assumed to be well tested and stable). this is not a good practice. – Spoutnick1990 Jun 05 '17 at 02:48
  • I considered modifying the code as well, but as you say, it's not clean. I find it odd that they would have a C++ wrapper that doesn't implement everything they are capable natively without resorting to C code. – Simog Jun 05 '17 at 03:23