c++windowspathlibssh

Windows path problems using libssh C++ wrapper


I am having problems with Windows file path separators using the libssh c++ wrapper libsshpp.

Suppose I have following code:

#define SSH_NO_CPP_EXCEPTIONS
#include "libssh/libsshpp.hpp"

#include <iostream>

#pragma comment(lib, "ssh")

int main() 
{
    ssh::Session session;

    int sessionMsg = -1;

    std::string host        = "myhost.com";
    std::string user        = "username";
    std::string idfile      = "%s\\.ssh\\id_ed25519";
    std::string hostkeys    = "ssh-ed25519";
    std::string keyExchange = "curve25519-sha256";

    session.setOption(SSH_OPTIONS_HOST,                 host.c_str());
    session.setOption(SSH_OPTIONS_USER,                 user.c_str());
    session.setOption(SSH_OPTIONS_STRICTHOSTKEYCHECK,   (long)0);
    session.setOption(SSH_OPTIONS_HOSTKEYS,             hostkeys.c_str());
    session.setOption(SSH_OPTIONS_KEY_EXCHANGE,         keyExchange.c_str());
    session.setOption(SSH_OPTIONS_ADD_IDENTITY,         idfile.c_str());

    std::cout << "Trying to connect to " << host << " with user " << user << "...\n";

    session.connect();

    if (session.isServerKnown() != SSH_SERVER_KNOWN_OK) {
        std::cout << "Server unknown.\n";

        if (session.writeKnownhost() != SSH_OK) {
            std::cout << "Unable to write to known_hosts file.\n";
        }
        else {
            session.connect();
        }
    }

    sessionMsg = session.userauthPublickeyAuto();

    std::string err = session.getError();

    if (sessionMsg != SSH_AUTH_SUCCESS) {
        if (!err.empty()) {
            std::cout << err;
        }

        std::cout << "Auth failed.";
    }
    else {
        std::cout << err.empty() ? session.getIssueBanner() : err;
    }
}

In the beginning I had set the idfile value to just id_ed25519 but then libssh complained: Failed to read private key: C:\Users\MyUser/.ssh/id_ed25519 (notice the switching slashes). After changing it to %s\\.ssh\\id_ed25519 it seemed to have had a positive impact on the connection routine, however now I keep falling into the (session.writeKnownhost() != SSH_OK) code part.

Now, I am wondering if this might be due to the same "switching slashes" problem which came up for the private key file path because apparently libssh wants to access C:\Users\MyUser\.ssh\known_hosts but quite possibly the path is set as something like C:\Users\MyUser/.ssh/known_hosts.

My question is: is there a possibility to change the path seperators to windows-style somehow in the session or is there something else I am overseeing or doing wrong here?


Solution

  • I was able to solve the problem adding the SSH_OPTIONS_SSH_DIR option and changing the private key and known_hosts paths (now relative to the ssh directory path):

    // note here: %s will be replaced by libssh with the home directory path
    std::string sshDir = "%s//.ssh"; 
    std::string idFile = "id_ed25519";
    std::string knownHosts = "known_hosts";
    
    // ...
    session.setOption(SSH_OPTIONS_USER, user.c_str());
    session.setOption(SSH_OPTIONS_SSH_DIR, sshDir.c_str()); // <-- added
    // ...