An ssh config parser for ssh2-rs

Overview

ssh2-config

Changelog · Get started · Documentation

Developed by @veeso

Current version: 0.1.0 (04/12/2021)

License-MIT Repo stars Downloads counter Latest version Ko-fi

Build Coveralls Docs



About ssh2-config

ssh2-config a library which provides a parser for the SSH configuration file, to be used in pair with the ssh2 crate.

This library provides a method to parse the configuration file and returns the configuration parsed into a structure. The SshConfig structure provides all the attributes which can be used to configure the ssh2 Session and to resolve the host, port and username.

Once the configuration has been parsed you can use the query(&str) method to query configuration for a certain host, based on the configured patterns.

Even if many attributes are not exposed, since not supported, there is anyway a validation of the configuration, so invalid configuration will result in a parsing error.

Exposed attributes

  • BindAddress: you can use this attribute to bind the socket to a certain address
  • BindInterface: you can use this attribute to bind the socket to a certain network interface
  • CASignatureAlgorithms: you can use this attribute to handle CA certificates
  • CertificateFile: you can use this attribute to parse the certificate file in case is necessary
  • Ciphers: you can use this attribute to set preferred methods with the session method session.method_pref(MethodType::CryptCs, ...) and session.method_pref(MethodType::CryptSc, ...)
  • Compression: you can use this attribute to set whether compression is enabled with session.set_compress(value)
  • ConnectionAttempts: you can use this attribute to cycle over connect in order to retry
  • ConnectTimeout: you can use this attribute to set the connection timeout for the socket
  • HostName: you can use this attribute to get the real name of the host to connect to
  • KexAlgorithms: you can use this attribute to configure Key exchange methods with session.method_pref(MethodType::Kex, algos.join(",").as_str())
  • MACs: you can use this attribute to configure the MAC algos with session.method_pref(MethodType::MacCs, algos.join(",").as_str()) and session.method_pref(MethodType::MacSc, algos.join(",").as_str())
  • Port: you can use this attribute to resolve the port to connect to
  • PubkeyAuthentication: you can use this attribute to set whether to use the pubkey authentication
  • RemoteForward: you can use this method to implement port forwarding with session.channel_forward_listen()
  • ServerAliveInterval: you can use this method to implement keep alive message interval
  • TcpKeepAlive: you can use this method to tell whether to send keep alive message
  • User: you can use this method to resolve the user to use to log in as

Missing features


Get started 🚀

First of all, add ssh2-config to your dependencies

[dependencies]
ssh2-config = "^0.1.0"

then parse the configuration

use ssh2_config::{SshConfig};
use std::fs::File;
use std::io::BufReader;

let mut reader = BufReader::new(File::open(config_path).expect("Could not open configuration file"));
let config = SshConfig::default().parse(&mut reader).expect("Failed to parse configuration");

// Query attributes for a certain host
let params = config.query("192.168.1.2");

then you can use the parsed parameters to configure the session:

use ssh2::Session;
use ssh2_config::{HostParams};

fn configure_session(session: &mut Session, params: &HostParams) {
    if let Some(compress) = params.compression {
        session.set_compress(compress);
    }
    if params.tcp_keep_alive.unwrap_or(false) && params.server_alive_interval.is_some() {
        let interval = params.server_alive_interval.unwrap().as_secs() as u32;
        session.set_keepalive(true, interval);
    }
    // algos
    if let Some(algos) = params.kex_algorithms.as_deref() {
        if let Err(err) = session.method_pref(MethodType::Kex, algos.join(",").as_str()) {
            panic!("Could not set KEX algorithms: {}", err);
        }
    }
    if let Some(algos) = params.host_key_algorithms.as_deref() {
        if let Err(err) = session.method_pref(MethodType::HostKey, algos.join(",").as_str()) {
            panic!("Could not set host key algorithms: {}", err);
        }
    }
    if let Some(algos) = params.ciphers.as_deref() {
        if let Err(err) = session.method_pref(MethodType::CryptCs, algos.join(",").as_str()) {
            panic!("Could not set crypt algorithms (client-server): {}", err);
        }
        if let Err(err) = session.method_pref(MethodType::CryptSc, algos.join(",").as_str()) {
            panic!("Could not set crypt algorithms (server-client): {}", err);
        }
    }
    if let Some(algos) = params.mac.as_deref() {
        if let Err(err) = session.method_pref(MethodType::MacCs, algos.join(",").as_str()) {
            panic!("Could not set MAC algorithms (client-server): {}", err);
        }
        if let Err(err) = session.method_pref(MethodType::MacSc, algos.join(",").as_str()) {
            panic!("Could not set MAC algorithms (server-client): {}", err);
        }
    }
}

Examples

You can view a working examples of an implementation of ssh2-config with ssh2 in the examples folder at client.rs.

You can run the example with

cargo run --example client -- <remote-host> [config-file-path]

Support the developer

If you like ssh2-config and you're grateful for the work I've done, please consider a little donation 🥳

You can make a donation with one of these platforms:

ko-fi PayPal


Contributing and issues 🤝🏻

Contributions, bug reports, new features and questions are welcome! 😉 If you have any question or concern, or you want to suggest a new feature, or you want just want to improve ssh2-config, feel free to open an issue or a PR.

Please follow our contributing guidelines


Changelog

View ssh2-config's changelog HERE


License 📃

ssh2-config is licensed under the MIT license.

You can read the entire license HERE

You might also like...
Rust query string parser with nesting support

What is Queryst? This is a fork of the original, with serde and serde_json updated to 0.9 A query string parsing library for Rust inspired by https://

A fast, extensible, command-line arguments parser

parkour A fast, extensible, command-line arguments parser. Introduction 📚 The most popular argument parser, clap, allows you list all the possible ar

Soon to be AsciiDoc parser implemented in rust!

pagliascii "But ASCII Doc, I am Pagliascii" Soon to be AsciiDoc parser implemented in rust! This project is the current implementation of the requeste

An LR parser generator, implemented as a proc macro

parsegen parsegen is an LR parser generator, similar to happy, ocamlyacc, and lalrpop. It currently generates canonical LR(1) parsers, but LALR(1) and

A rusty, dual-wielding Quake and Half-Life texture WAD parser.

Ogre   A rusty, dual-wielding Quake and Half-Life texture WAD parser ogre is a rust representation and nom parser for Quake and Half-Life WAD files. I

A modern dialogue executor and tree parser using YAML.

A modern dialogue executor and tree parser using YAML. This crate is for building(ex), importing/exporting(ex), and walking(ex) dialogue trees. convo

A friendly parser combinator crate

Chumsky A friendly parser combinator crate that makes writing LL-1 parsers with error recovery easy. Example Here follows a Brainfuck parser. See exam

Minimalist pedantic command line parser

Lexopt Lexopt is an argument parser for Rust. It tries to have the simplest possible design that's still correct. It's so simple that it's a bit tedio

Universal configuration library parser

LIBUCL Table of Contents generated with DocToc Introduction Basic structure Improvements to the json notation General syntax sugar Automatic arrays cr

Comments
  • [Feature Request] - parser fails when it sees ForwardX11Trusted

    [Feature Request] - parser fails when it sees ForwardX11Trusted

    Description

    The parser fails when it sees ForwardX11Trusted option in the config file.

    Changes

    1. I think the library can accept this option or
    2. in the worst case expose a try_parse method which can ignore unhandled options
    feature-request 
    opened by vmiheer 2
  • [BUG] - Sometimes an unexpected identity file path is parsed

    [BUG] - Sometimes an unexpected identity file path is parsed

    Description

    The wrong identity file path is parsed. When the wrong identity file path is present, there is a configuration in which the Host parameter is just a wildcard. If there are multiple wildcards, the last one is used when the wrong identity file path is parsed.

    Steps to reproduce

    Put the following in your ~/.ssh/config file

    Host remote_host
      HostName hostname.com
      User user
      IdentityFile ~/.ssh/id_rsa_good
    
    Host *
      AddKeysToAgent yes
      IdentityFile ~/.ssh/id_rsa_bad
    

    Parse the config with the following code:

    use ssh2_config::SshConfig;
    use std::io::BufReader;
    
    // Parsing ssh config
    let config_path = <path to your config>;
    let config = std::fs::File::open(config_path).unwrap();
    let mut buf_rdr_conf = BufReader::new(config);
    let ssh_config = SshConfig::default().parse(&mut buf_rdr_conf).unwrap();
    
    // Get settings from config
    let config = ssh_config.query("remote_host");
    let host_name = config.host_name.unwrap();
    eprintln!("host = {host_name}");
    let mut identity_paths = config.identity_file.unwrap();
    eprintln!("available identity paths = {identity_paths:#?}");
    
    let identity_path = identity_paths.pop().unwrap();
    eprintln!("identity path = {}", identity_path.display());
    let user_name = config.user.unwrap();
    eprintln!("user = {user_name}");
    

    Note that the program prints other parameters just to be sure that all the others are correct. Up until now, I've never had an issue with the others, but maybe that's because I don't actually use any other overlapping parameters in the wildcard configuration.

    Expected behaviour

    Program prints

    identity path = ~/.ssh/id_rsa_good
    

    Actual behavior

    Program prints

    identity path = ~/.ssh/id_rsa_bad
    

    Environment

    • OS: MacOS Ventura
    • Architecture: Arm
    • Rust version: 1.64.0
    • remotefs version: N/A
    • Protocol used: N/A
    • Remote server version and name: N/A

    Additional information

    bug 
    opened by teamwork-alockhart 0
Releases(v0.1.3)
Owner
Christian Visintin
24 years old, software and web developer and geek. I mostly develop in Rust, Elixir and Python.
Christian Visintin
Website for Microformats Rust parser (using 'microformats-parser'/'mf2')

Website for Microformats Rust parser (using 'microformats-parser'/'mf2')

Microformats 5 Jul 19, 2022
A native Rust port of Google's robots.txt parser and matcher C++ library.

robotstxt A native Rust port of Google's robots.txt parser and matcher C++ library. Native Rust port, no third-part crate dependency Zero unsafe code

Folyd 72 Dec 11, 2022
Rust parser combinator framework

nom, eating data byte by byte nom is a parser combinators library written in Rust. Its goal is to provide tools to build safe parsers without compromi

Geoffroy Couprie 7.6k Jan 7, 2023
url parameter parser for rest filter inquiry

inquerest Inquerest can parse complex url query into a SQL abstract syntax tree. Example this url: /person?age=lt.42&(student=eq.true|gender=eq.'M')&

Jovansonlee Cesar 25 Nov 2, 2020
Parsing Expression Grammar (PEG) parser generator for Rust

Parsing Expression Grammars in Rust Documentation | Release Notes rust-peg is a simple yet flexible parser generator that makes it easy to write robus

Kevin Mehall 1.2k Dec 30, 2022
A fast monadic-style parser combinator designed to work on stable Rust.

Chomp Chomp is a fast monadic-style parser combinator library designed to work on stable Rust. It was written as the culmination of the experiments de

Martin Wernstål 228 Oct 31, 2022
A parser combinator library for Rust

combine An implementation of parser combinators for Rust, inspired by the Haskell library Parsec. As in Parsec the parsers are LL(1) by default but th

Markus Westerlind 1.1k Dec 28, 2022
LR(1) parser generator for Rust

LALRPOP LALRPOP is a Rust parser generator framework with usability as its primary goal. You should be able to write compact, DRY, readable grammars.

null 2.4k Jan 7, 2023
The Elegant Parser

pest. The Elegant Parser pest is a general purpose parser written in Rust with a focus on accessibility, correctness, and performance. It uses parsing

pest 3.5k Jan 8, 2023
A typed parser generator embedded in Rust code for Parsing Expression Grammars

Oak Compiled on the nightly channel of Rust. Use rustup for managing compiler channels. You can download and set up the exact same version of the comp

Pierre Talbot 138 Nov 25, 2022