-
Notifications
You must be signed in to change notification settings - Fork 4
/
example_test.go
132 lines (122 loc) · 3.83 KB
/
example_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package knownhosts_test
import (
"fmt"
"log"
"net"
"os"
"github.com/skeema/knownhosts"
"golang.org/x/crypto/ssh"
)
func ExampleNew() {
sshHost := "yourserver.com:22"
kh, err := knownhosts.New("/home/myuser/.ssh/known_hosts")
if err != nil {
log.Fatal("Failed to read known_hosts: ", err)
}
config := &ssh.ClientConfig{
User: "myuser",
Auth: []ssh.AuthMethod{ /* ... */ },
HostKeyCallback: kh.HostKeyCallback(),
HostKeyAlgorithms: kh.HostKeyAlgorithms(sshHost),
}
client, err := ssh.Dial("tcp", sshHost, config)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
defer client.Close()
}
func ExampleNewDB() {
sshHost := "yourserver.com:22"
kh, err := knownhosts.NewDB("/home/myuser/.ssh/known_hosts")
if err != nil {
log.Fatal("Failed to read known_hosts: ", err)
}
config := &ssh.ClientConfig{
User: "myuser",
Auth: []ssh.AuthMethod{ /* ... */ },
HostKeyCallback: kh.HostKeyCallback(),
HostKeyAlgorithms: kh.HostKeyAlgorithms(sshHost),
}
client, err := ssh.Dial("tcp", sshHost, config)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
defer client.Close()
}
func ExampleHostKeyCallback_ToDB() {
khFile := "/home/myuser/.ssh/known_hosts"
var kh *knownhosts.HostKeyDB
var err error
// Example of using conditional logic to determine whether or not to perform
// extra parsing pass on the known_hosts file in order to enable enhanced
// behaviors
if os.Getenv("SKIP_KNOWNHOSTS_ENHANCEMENTS") != "" {
// Create a HostKeyDB using New + ToDB: this will skip the extra known_hosts
// processing
var cb knownhosts.HostKeyCallback
if cb, err = knownhosts.New(khFile); err == nil {
kh = cb.ToDB()
}
} else {
// Create a HostKeyDB using NewDB: this will perform extra known_hosts
// processing, allowing proper support for CAs, as well as OpenSSH-like
// wildcard matching on non-standard ports
kh, err = knownhosts.NewDB(khFile)
}
if err != nil {
log.Fatal("Failed to read known_hosts: ", err)
}
sshHost := "yourserver.com:22"
config := &ssh.ClientConfig{
User: "myuser",
Auth: []ssh.AuthMethod{ /* ... */ },
HostKeyCallback: kh.HostKeyCallback(),
HostKeyAlgorithms: kh.HostKeyAlgorithms(sshHost),
}
client, err := ssh.Dial("tcp", sshHost, config)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
defer client.Close()
}
func ExampleWriteKnownHost() {
sshHost := "yourserver.com:22"
khPath := "/home/myuser/.ssh/known_hosts"
kh, err := knownhosts.NewDB(khPath)
if err != nil {
log.Fatal("Failed to read known_hosts: ", err)
}
// Create a custom permissive hostkey callback which still errors on hosts
// with changed keys, but allows unknown hosts and adds them to known_hosts
cb := ssh.HostKeyCallback(func(hostname string, remote net.Addr, key ssh.PublicKey) error {
innerCallback := kh.HostKeyCallback()
err := innerCallback(hostname, remote, key)
if knownhosts.IsHostKeyChanged(err) {
return fmt.Errorf("REMOTE HOST IDENTIFICATION HAS CHANGED for host %s! This may indicate a MitM attack.", hostname)
} else if knownhosts.IsHostUnknown(err) {
f, ferr := os.OpenFile(khPath, os.O_APPEND|os.O_WRONLY, 0600)
if ferr == nil {
defer f.Close()
ferr = knownhosts.WriteKnownHost(f, hostname, remote, key)
}
if ferr == nil {
log.Printf("Added host %s to known_hosts\n", hostname)
} else {
log.Printf("Failed to add host %s to known_hosts: %v\n", hostname, ferr)
}
return nil // permit previously-unknown hosts (warning: may be insecure)
}
return err
})
config := &ssh.ClientConfig{
User: "myuser",
Auth: []ssh.AuthMethod{ /* ... */ },
HostKeyCallback: cb,
HostKeyAlgorithms: kh.HostKeyAlgorithms(sshHost),
}
client, err := ssh.Dial("tcp", sshHost, config)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
defer client.Close()
}