knownhosts

package module
v0.0.0-...-e328a8c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 9, 2019 License: MIT Imports: 20 Imported by: 0

README

knownhosts

Documentation Build Status Report Card

About

gigawatt.io/knownhosts is a golang package for programmatically parsing, querying and manipulating SSH known_hosts files (usually located under ~/.ssh/known_hosts).

This package provides functionality beyond the go stdlib crypto/ssh/knownhosts, which doesn't expose much of practical use for known_hosts file management.

There are many possible (ab)use-cases for this library, so before importing it's recommended you review the Security Considerations section below and think critically about the possible implications for your implementation.

Created by Jay Taylor.

Security Considerations

Programmatic addition of entries to ~/.ssh/known_hosts can be risky due to the potential for exposing MITM attacks vulnerabilities in your application. It is critical to account for this aspect in your design before importing this go package.

Further Reading
Usage
package main

import (
    "fmt"

    "gigawatt.io/knownhosts"
)

func main() {
    khs, err := knownhosts.New("/tmp/test_known_tests")
    if err != nil {
        panic(err)
    }

    if _, err := khs.Add("github.com", "gitlab.com"); err != nil {
        panic(err)
    }

    fmt.Printf("khs.String() =>\n---\n%v\n---\n", khs.String())

    if err := khs.Sync(); err != nil {
        panic(err)
    }

    gh := khs.FindByAddr("ssh-rsa", "github.com")
    fmt.Printf("github.com query result: %# v\n", gh)

    gl := khs.FindByAddr("ssh-rsa", "gitlab.com")
    fmt.Printf("gitlab.com query result: %# v\n", gl)
}

Also see the examples in the docs.

Motivation

This started with a requirement to clone git repositories non-interactively. This gets around interactive SSH authentication prompts by always ensuring there is a known_hosts entry for each git host before initiating a clone.

Cloning into 'target'...
The authenticity of host 'gitlab.com (35.231.145.151)' can't be established.
ECDSA key fingerprint is f1:d0:fb:46:73:7a:70:92:5a:ab:5d:ef:43:e2:1c:35.
Are you sure you want to continue connecting (yes/no)?
The authenticity of host '[madmax.utwente.nl]:62222 ([4.3.2.1]:62222)' can't be established.
RSA key fingerprint is SHA256:USgS2JZsu19qqQQf16TomcatUPdogQuicksilvaAUSS.
RSA key fingerprint is MD5:8a:b9:db:ca:40:fe:32:ba:00:be:ef:04:ac:bd:9b:a8.
Are you sure you want to continue connecting (yes/no)?
Requirements
  • Go version 1.9 or newer
Running the test suite
go test ./...
License

Permissive MIT license, see the LICENSE file for more information.

Documentation

Overview

Package knownhosts supports programmatic parsing, querying and manipulation of SSH known_hosts files.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	DefaultKnownHostsTimeout = 10 * time.Second
	DefaultKnownHostsPath    = filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts")

	ErrKeyChanged = errors.New("security violation: unexpected public key change detected")
)

Functions

func HashAddr

func HashAddr(salt string, addr string) (string, error)

HashAddr takes a salt and host address and returns the corresponding hash value.

func IsErrKeyChanged

func IsErrKeyChanged(err error) bool

IsErrKeyChanged returns true if the error message begins with the ErrKeyChanged message string.

Types

type KnownHost

type KnownHost struct {
	Addrs     []string
	KeyType   string
	PublicKey string
}

func (KnownHost) HasAddress

func (kh KnownHost) HasAddress(addr string) bool

HasAddress returns true if the specified addr or addr:port is contained.

func (KnownHost) String

func (kh KnownHost) String() string

String turns the known host information into a known_hosts file formatted entry.

type KnownHosts

type KnownHosts struct {
	FilePath string
	Items    []*KnownHost
}

func New

func New(f string) (*KnownHosts, error)

New creates a new instance of KnownHosts. If f is empty, then DefaultKnownHostsPath will be used.

func (*KnownHosts) Add

func (khs *KnownHosts) Add(addrs ...string) (bool, error)

Add resolves and adds a new set of known hosts, then renders to disk. There are obvious security considerations and implications here, since automatically adding to known_hosts can be MITM'd.

Returns bool indicating if any state was changed, and any encountered error.

Automatically merges records for different addresses sharing the same key.

Example
filePath, err := WriteSampleFile()
if err != nil {
	panic(err)
}

khs, err := New(filePath)
if err != nil {
	panic(err)
}
if _, err := khs.Add("gitlab.com"); err != nil {
	panic(err)
}
if err := khs.Sync(); err != nil {
	panic(err)
}
bs, _ := ioutil.ReadFile(filePath)
fmt.Println(string(bs))
Output:

func (*KnownHosts) FindByAddr

func (khs *KnownHosts) FindByAddr(keyType string, addr string) *KnownHost

FindByAddr returns nil if no corresponding addr:port entry is found.

Example
filePath, err := WriteSampleFile()
if err != nil {
	panic(err)
}

khs, err := New(filePath)
if err != nil {
	panic(err)
}
fmt.Printf("%# v\n", khs.FindByAddr("ssh-rsa", "github.com"))
Output:

func (*KnownHosts) FindByKey

func (khs *KnownHosts) FindByKey(keyType string, publicKey string) *KnownHost

FindByKey returns nil if no corresponding key type and value entry is found.

Example
filePath, err := WriteSampleFile()
if err != nil {
	panic(err)
}

khs, err := New(filePath)
if err != nil {
	panic(err)
}
fmt.Printf("%# v\n", khs.FindByKey("ssh-rsa", "AAAA...KUr2oK9EJ5e81"))
Output:

func (*KnownHosts) Len

func (khs *KnownHosts) Len() int

func (*KnownHosts) Parse

func (khs *KnownHosts) Parse() error

Parse refreshes and parses the known hosts data from disk.

func (*KnownHosts) String

func (khs *KnownHosts) String() string

String transforms the current state known hosts into a string representation.

func (*KnownHosts) Sync

func (khs *KnownHosts) Sync() error

Sync renders the current state to disk.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL