#How do I read an SSH config file?

21 messages Β· Page 1 of 1 (latest)

turbid trout
#

Hey there! I'm looking to read an SSH config file and get a list of the hosts in it. Such a config file is shown below:

Host testing1 test-hosts
  HostName x.x.x.x
  User ubuntu
#  ... there is often more

Host testing2 test-hosts
  HostName y.y.y.y
  User jeffrey
  IdentityFile ~/.ssh/identities/testing2

I've already read the contents of the file into an std::string and I'm looping over the lines, but what do I do next? I need the data in a struct like the following:

struct Host {
    std::string name;
    std::string group;
    std::string user;
};

I'm using CMake so it is preferred that any libraries are CMake compatible πŸ˜„
Any help is appreciated!

viral hawkBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

cobalt snow
#

What is your problem?

#

You dont need any libraries to do this

turbid trout
#

how to parse the file

cobalt snow
#

Well do you have an ifstream already to the file?

turbid trout
#
#if defined(unix) || defined(__unix__) || defined(__unix)
# define PREDEF_PLATFORM_UNIX
#endif

#if defined(PREDEF_PLATFORM_UNIX) || defined(__linux__) || defined(__APPLE)
# define PREDEF_PLATFORM_UNIX_LIKE
#endif

#if defined(_WIN32) || defined(_WIN64)
# define PREDEF_PLATFORM_WINDOWS
#endif

#include <cstdlib>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <filesystem>
#ifdef PREDEF_PLATFORM_UNIX_LIKE
#include <pwd.h>
#include <unistd.h>
#endif // PREDEF_PLATFORM_UNIX_LIKE
#include <vector>

namespace fs = std::filesystem;

// thanks for the help, https://stackoverflow.com/questions/2552416/how-can-i-find-the-users-home-dir-in-a-cross-platform-manner-using-c
std::string getHome() {
#if defined(_WIN32) || defined(_WIN64)
#error Windows is not currently supported. Check back soon, though!
#elif defined(PREDEF_PLATFORM_UNIX_LIKE)
    std::string homePath = "NULL";
    struct passwd* pwd = getpwuid(getuid());
    if (pwd) {
        homePath = pwd->pw_dir;
    } else {
        homePath = std::getenv("HOME");
    }
#else
#error Unsupported platform!
#endif
    return homePath;
}

struct Host {
    std::string name;
    std::string group;
    std::string user;
};

int main() {
    std::string homeDirectory = getHome();
    if (homeDirectory == "NULL") {
        printf("Unable to find home directory!\n");
        return 1;
    }

    fs::path configPath = fs::path(homeDirectory) / fs::path(".ssh") / fs::path("config");
    std::ifstream f = std::ifstream(configPath.string());
    if (!f) {
        printf("SSH config file does not exist.\n");
        return 1;
    }

    std::stringstream buffer;

    std::vector<std::string> hosts;
    std::string line;
    std::string currentHost;
    while (std::getline(f, line)) {
        if (line.empty() || line[0] == '#') { continue; }
        printf("%s\n", line.c_str());
    }
    return 0;
}

#

that's my code

viral hawkBOT
#

@turbid trout Has your question been resolved? If so, type !solved :)

turbid trout
#

anyway yeah @cobalt snow I just can't work out how to parse it into that struct

#

or, a simpler way, would be to take all of the root Hosts (ignoring non-Hosts) and put their properties in a map

#

but how would I do that

cobalt snow
#

Well each new block starts with Host , so you can check if your string contains that and you fill your Host struct data with the information from that until you hit another Host block and then you store it somewhere and reset the host struct data again

turbid trout
cobalt snow
turbid trout
#

oh, thanks you πŸ˜„

#

also, how can I strip all preceeding whitespace characters?

viral hawkBOT
#

This question is being automatically marked as stale.
If your question has been answered, type !solved.
If your question is not answered feel free to bump the post or re-ask.
Take a look at !howto ask for tips on improving your question.

frigid vortex
#

@turbid trout You have two choice use boost::trim