Skip to content

Commit

Permalink
Merge pull request #525 from milkpirate/HostKeyAlgorithms-slice
Browse files Browse the repository at this point in the history
  • Loading branch information
moul authored May 28, 2022
2 parents 867a30c + d8e8454 commit 6664fb4
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 57 deletions.
38 changes: 19 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,22 @@ examples: $(TARGET)
.PHONY: gen-release
gen-release: generate
mkdir -p .release
GOOS=linux GOARCH=amd64 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_linux_amd64 .
GOOS=linux GOARCH=386 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_linux_386 .
GOOS=linux GOARCH=arm go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_linux_arm .
GOOS=linux GOARCH=arm64 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_linux_arm64 .
GOOS=openbsd GOARCH=amd64 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_openbsd_amd64 .
GOOS=openbsd GOARCH=386 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_openbsd_386 .
GOOS=openbsd GOARCH=arm go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_openbsd_arm .
GOOS=darwin GOARCH=amd64 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_darwin_amd64 .
#GOOS=darwin GOARCH=386 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_darwin_386 .
#GOOS=darwin GOARCH=arm go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_darwin_arm .
GOOS=netbsd GOARCH=amd64 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_netbsd_amd64 .
GOOS=netbsd GOARCH=386 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_netbsd_386 .
GOOS=netbsd GOARCH=arm go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_netbsd_arm .
GOOS=freebsd GOARCH=amd64 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_freebsd_amd64 .
GOOS=freebsd GOARCH=386 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_freebsd_386 .
GOOS=freebsd GOARCH=arm go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_freebsd_arm .
GOOS=windows GOARCH=amd64 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_windows_amd64.exe .
GOOS=windows GOARCH=386 go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_windows_386.exe .
#GOOS=windows GOARCH=arm go build $(GO_INSTALL_OPTS) -i -v -o .release/assh_windows_arm.exe .
GOOS=linux GOARCH=amd64 go build $(GO_INSTALL_OPTS) -v -o .release/assh_linux_amd64 .
GOOS=linux GOARCH=386 go build $(GO_INSTALL_OPTS) -v -o .release/assh_linux_386 .
GOOS=linux GOARCH=arm go build $(GO_INSTALL_OPTS) -v -o .release/assh_linux_arm .
GOOS=linux GOARCH=arm64 go build $(GO_INSTALL_OPTS) -v -o .release/assh_linux_arm64 .
GOOS=openbsd GOARCH=amd64 go build $(GO_INSTALL_OPTS) -v -o .release/assh_openbsd_amd64 .
GOOS=openbsd GOARCH=386 go build $(GO_INSTALL_OPTS) -v -o .release/assh_openbsd_386 .
GOOS=openbsd GOARCH=arm go build $(GO_INSTALL_OPTS) -v -o .release/assh_openbsd_arm .
GOOS=darwin GOARCH=amd64 go build $(GO_INSTALL_OPTS) -v -o .release/assh_darwin_amd64 .
# GOOS=darwin GOARCH=386 go build $(GO_INSTALL_OPTS) -v -o .release/assh_darwin_386 .
# GOOS=darwin GOARCH=arm go build $(GO_INSTALL_OPTS) -v -o .release/assh_darwin_arm .
GOOS=netbsd GOARCH=amd64 go build $(GO_INSTALL_OPTS) -v -o .release/assh_netbsd_amd64 .
GOOS=netbsd GOARCH=386 go build $(GO_INSTALL_OPTS) -v -o .release/assh_netbsd_386 .
GOOS=netbsd GOARCH=arm go build $(GO_INSTALL_OPTS) -v -o .release/assh_netbsd_arm .
GOOS=freebsd GOARCH=amd64 go build $(GO_INSTALL_OPTS) -v -o .release/assh_freebsd_amd64 .
GOOS=freebsd GOARCH=386 go build $(GO_INSTALL_OPTS) -v -o .release/assh_freebsd_386 .
GOOS=freebsd GOARCH=arm go build $(GO_INSTALL_OPTS) -v -o .release/assh_freebsd_arm .
GOOS=windows GOARCH=amd64 go build $(GO_INSTALL_OPTS) -v -o .release/assh_windows_amd64.exe .
GOOS=windows GOARCH=386 go build $(GO_INSTALL_OPTS) -v -o .release/assh_windows_386.exe .
# GOOS=windows GOARCH=arm go build $(GO_INSTALL_OPTS) -v -o .release/assh_windows_arm.exe .
60 changes: 35 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,23 @@ For specific examples, see [3rd Party Integration](#3rd-party-integration)

Connect to `hosta` using `hostb` as a gateway.

```
┌─────┐
│ YOU │─ ─ ─ ─ ─
└─────┘ │
┃ ▽
┃ ┌─────┐
firewall │hostb│
┃ └─────┘
▼ │
┌─────┐
│hosta│◁─ ─ ─ ─ ┘
└─────┘
```mermaid
flowchart
direction TB
y[you]
a[hosta]
b[hostb]
fw((firewall))
style fw fill:#f00,color:#fff
y ==x fw
fw .-> a
y --> b
b --> a
```

```console
Expand All @@ -70,19 +75,24 @@ Equivalent to `ssh -o ProxyCommand="ssh hostb nc %h %p" hosta`

Connect to `hosta` using `hostb` as a gateway using `hostc` as a gateway.

```
┌─────┐ ┌─────┐
│ YOU │─ ─ ─ ─ ─ ─ ─▷│hostc│
└─────┘ └─────┘
┃ │
firewall │
┃ │
▼ ▽
┌─────┐ ┌─────┐
│hosta│◁─ ─ ─ ─ ─ ─ ─│hostb│
└─────┘ └─────┘
```mermaid
flowchart
direction TB
y[you]
a[hosta]
b[hostb]
c[hostc]
fw((firewall))
style fw fill:#f00,color:#fff
y ==x fw
fw ..-> a
y --> c
c --> b
b --> a
```

```console
Expand Down
11 changes: 7 additions & 4 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func dummyConfig() *Config {
HashKnownHosts: "no",
HostbasedAuthentication: "no",
HostbasedKeyTypes: "*",
HostKeyAlgorithms: "ecdsa-sha2-nistp256-cert-v01@openssh.com",
HostKeyAlgorithms: []string{"ecdsa-sha2-nistp256-cert-v01@openssh.com", "test"},
HostKeyAlias: "z",
IdentitiesOnly: "yes",
IdentityFile: []string{"~/.ssh/identity", "~/.ssh/identity2"},
Expand Down Expand Up @@ -512,7 +512,10 @@ func TestConfig_JSONString(t *testing.T) {
"HashKnownHosts": "no",
"HostbasedAuthentication": "no",
"HostbasedKeyTypes": "*",
"HostKeyAlgorithms": "ecdsa-sha2-nistp256-cert-v01@openssh.com",
"HostKeyAlgorithms": [
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
"test"
],
"HostKeyAlias": "z",
"IdentitiesOnly": "yes",
"IdentityFile": [
Expand Down Expand Up @@ -1283,7 +1286,7 @@ func TestConfig_GetHostSafe(t *testing.T) {
func TestConfig_String(t *testing.T) {
Convey("Testing Config.String", t, func() {
config := dummyConfig()
So(config.String(), ShouldEqual, `{"hosts":{"*.ddd":{"PasswordAuthentication":"yes","HostName":"1.3.5.7"},"empty":{},"nnn":{"Port":"26","Inherits":["mmm"]},"ooo1":{"Port":"23","Aliases":["ooo11","ooo12"]},"ooo2":{"Port":"24","Aliases":["ooo21","ooo22"]},"tata":{"Inherits":["tutu","titi","toto","tutu"]},"titi":{"Port":"23","User":"moul","HostName":"tata","ProxyCommand":"nc -v 4242","ControlMasterMkdir":"true","Comment":["Hello World"]},"tonton":{"ResolveNameservers":["a.com","1.2.3.4"],"Comment":["AAA","BBB"]},"toto":{"HostName":"1.2.3.4"},"toto[1-5]toto":{"User":"toto1"},"toto[7-9]toto":{"User":"toto2"},"toutou":{"RemoteCommand":"date \u003e\u003e /tmp/logs","ResolveCommand":"dig -t %h","Comment":["First line Second line Third line\n"]},"tutu":{"Inherits":["toto","tutu","*.ddd"],"Gateways":["titi","direct","1.2.3.4"]},"zzz":{"AddressFamily":"any","AskPassGUI":"yes","BatchMode":"no","CanonicalDomains":"42.am","CanonicalizeFallbackLocal":"no","CanonicalizeHostname":"yes","CanonicalizeMaxDots":"1","CanonicalizePermittedCNAMEs":"*.a.example.com:*.b.example.com:*.c.example.com","ChallengeResponseAuthentication":"yes","CheckHostIP":"yes","Cipher":"blowfish","Ciphers":["aes128-ctr,aes192-ctr","aes256-ctr"],"ClearAllForwardings":"yes","Compression":"yes","CompressionLevel":6,"ConnectionAttempts":"1","ConnectTimeout":10,"ControlMaster":"yes","ControlPath":"/tmp/%L-%l-%n-%p-%u-%r-%C-%h","ControlPersist":"yes","DynamicForward":["0.0.0.0:4242","0.0.0.0:4343"],"EnableSSHKeysign":"yes","EscapeChar":"~","ExitOnForwardFailure":"yes","FingerprintHash":"sha256","ForwardAgent":"yes","ForwardX11":"yes","ForwardX11Timeout":42,"ForwardX11Trusted":"yes","GatewayPorts":"yes","GlobalKnownHostsFile":["/etc/ssh/ssh_known_hosts","/tmp/ssh_known_hosts"],"GSSAPIAuthentication":"no","GSSAPIClientIdentity":"moul","GSSAPIDelegateCredentials":"no","GSSAPIKeyExchange":"no","GSSAPIRenewalForcesRekey":"no","GSSAPIServerIdentity":"gssapi.example.com","GSSAPITrustDNS":"no","HashKnownHosts":"no","HostbasedAuthentication":"no","HostbasedKeyTypes":"*","HostKeyAlgorithms":"ecdsa-sha2-nistp256-cert-v01@openssh.com","HostKeyAlias":"z","IdentitiesOnly":"yes","IdentityFile":["~/.ssh/identity","~/.ssh/identity2"],"IgnoreUnknown":"testtest","IPQoS":["lowdelay","highdelay"],"KbdInteractiveAuthentication":"yes","KbdInteractiveDevices":["bsdauth","test"],"KexAlgorithms":["curve25519-sha256@libssh.org","test"],"KeychainIntegration":"yes","LocalCommand":"echo %h \u003e /tmp/logs","LocalForward":["0.0.0.0:1234","0.0.0.0:1235"],"LogLevel":"DEBUG3","MACs":["umac-64-etm@openssh.com,umac-128-etm@openssh.com","test"],"Match":"all","NoHostAuthenticationForLocalhost":"yes","NumberOfPasswordPrompts":"3","PasswordAuthentication":"yes","PermitLocalCommand":"yes","PKCS11Provider":"/a/b/c/pkcs11.so","Port":"22","PreferredAuthentications":"gssapi-with-mic,hostbased,publickey","Protocol":["2","3"],"ProxyUseFdpass":"no","PubkeyAuthentication":"yes","RekeyLimit":"default none","RemoteForward":["0.0.0.0:1234","0.0.0.0:1255"],"RequestTTY":"yes","RevokedHostKeys":"/a/revoked-keys","RhostsRSAAuthentication":"no","RSAAuthentication":"yes","SendEnv":["CUSTOM_*,TEST","TEST2"],"ServerAliveCountMax":3,"StreamLocalBindMask":"0177","StreamLocalBindUnlink":"no","StrictHostKeyChecking":"ask","TCPKeepAlive":"yes","Tunnel":"yes","TunnelDevice":"any:any","UpdateHostKeys":"ask","UseKeychain":"no","UsePrivilegedPort":"no","User":"moul","UserKnownHostsFile":["~/.ssh/known_hosts ~/.ssh/known_hosts2","/tmp/known_hosts"],"VerifyHostKeyDNS":"no","VisualHostKey":"yes","XAuthLocation":"xauth","HostName":"zzz.com","ProxyCommand":"nc %h %p"}},"templates":{"mmm":{"Port":"25","User":"mmmm","HostName":"5.5.5.5","Inherits":["tata"]}},"defaults":{"Port":"22","User":"root","Hooks":{}},"asshknownhostfile":"~/.ssh/assh_known_hosts"}`)
So(config.String(), ShouldEqual, `{"hosts":{"*.ddd":{"PasswordAuthentication":"yes","HostName":"1.3.5.7"},"empty":{},"nnn":{"Port":"26","Inherits":["mmm"]},"ooo1":{"Port":"23","Aliases":["ooo11","ooo12"]},"ooo2":{"Port":"24","Aliases":["ooo21","ooo22"]},"tata":{"Inherits":["tutu","titi","toto","tutu"]},"titi":{"Port":"23","User":"moul","HostName":"tata","ProxyCommand":"nc -v 4242","ControlMasterMkdir":"true","Comment":["Hello World"]},"tonton":{"ResolveNameservers":["a.com","1.2.3.4"],"Comment":["AAA","BBB"]},"toto":{"HostName":"1.2.3.4"},"toto[1-5]toto":{"User":"toto1"},"toto[7-9]toto":{"User":"toto2"},"toutou":{"RemoteCommand":"date \u003e\u003e /tmp/logs","ResolveCommand":"dig -t %h","Comment":["First line Second line Third line\n"]},"tutu":{"Inherits":["toto","tutu","*.ddd"],"Gateways":["titi","direct","1.2.3.4"]},"zzz":{"AddressFamily":"any","AskPassGUI":"yes","BatchMode":"no","CanonicalDomains":"42.am","CanonicalizeFallbackLocal":"no","CanonicalizeHostname":"yes","CanonicalizeMaxDots":"1","CanonicalizePermittedCNAMEs":"*.a.example.com:*.b.example.com:*.c.example.com","ChallengeResponseAuthentication":"yes","CheckHostIP":"yes","Cipher":"blowfish","Ciphers":["aes128-ctr,aes192-ctr","aes256-ctr"],"ClearAllForwardings":"yes","Compression":"yes","CompressionLevel":6,"ConnectionAttempts":"1","ConnectTimeout":10,"ControlMaster":"yes","ControlPath":"/tmp/%L-%l-%n-%p-%u-%r-%C-%h","ControlPersist":"yes","DynamicForward":["0.0.0.0:4242","0.0.0.0:4343"],"EnableSSHKeysign":"yes","EscapeChar":"~","ExitOnForwardFailure":"yes","FingerprintHash":"sha256","ForwardAgent":"yes","ForwardX11":"yes","ForwardX11Timeout":42,"ForwardX11Trusted":"yes","GatewayPorts":"yes","GlobalKnownHostsFile":["/etc/ssh/ssh_known_hosts","/tmp/ssh_known_hosts"],"GSSAPIAuthentication":"no","GSSAPIClientIdentity":"moul","GSSAPIDelegateCredentials":"no","GSSAPIKeyExchange":"no","GSSAPIRenewalForcesRekey":"no","GSSAPIServerIdentity":"gssapi.example.com","GSSAPITrustDNS":"no","HashKnownHosts":"no","HostbasedAuthentication":"no","HostbasedKeyTypes":"*","HostKeyAlgorithms":["ecdsa-sha2-nistp256-cert-v01@openssh.com","test"],"HostKeyAlias":"z","IdentitiesOnly":"yes","IdentityFile":["~/.ssh/identity","~/.ssh/identity2"],"IgnoreUnknown":"testtest","IPQoS":["lowdelay","highdelay"],"KbdInteractiveAuthentication":"yes","KbdInteractiveDevices":["bsdauth","test"],"KexAlgorithms":["curve25519-sha256@libssh.org","test"],"KeychainIntegration":"yes","LocalCommand":"echo %h \u003e /tmp/logs","LocalForward":["0.0.0.0:1234","0.0.0.0:1235"],"LogLevel":"DEBUG3","MACs":["umac-64-etm@openssh.com,umac-128-etm@openssh.com","test"],"Match":"all","NoHostAuthenticationForLocalhost":"yes","NumberOfPasswordPrompts":"3","PasswordAuthentication":"yes","PermitLocalCommand":"yes","PKCS11Provider":"/a/b/c/pkcs11.so","Port":"22","PreferredAuthentications":"gssapi-with-mic,hostbased,publickey","Protocol":["2","3"],"ProxyUseFdpass":"no","PubkeyAuthentication":"yes","RekeyLimit":"default none","RemoteForward":["0.0.0.0:1234","0.0.0.0:1255"],"RequestTTY":"yes","RevokedHostKeys":"/a/revoked-keys","RhostsRSAAuthentication":"no","RSAAuthentication":"yes","SendEnv":["CUSTOM_*,TEST","TEST2"],"ServerAliveCountMax":3,"StreamLocalBindMask":"0177","StreamLocalBindUnlink":"no","StrictHostKeyChecking":"ask","TCPKeepAlive":"yes","Tunnel":"yes","TunnelDevice":"any:any","UpdateHostKeys":"ask","UseKeychain":"no","UsePrivilegedPort":"no","User":"moul","UserKnownHostsFile":["~/.ssh/known_hosts ~/.ssh/known_hosts2","/tmp/known_hosts"],"VerifyHostKeyDNS":"no","VisualHostKey":"yes","XAuthLocation":"xauth","HostName":"zzz.com","ProxyCommand":"nc %h %p"}},"templates":{"mmm":{"Port":"25","User":"mmmm","HostName":"5.5.5.5","Inherits":["tata"]}},"defaults":{"Port":"22","User":"root","Hooks":{}},"asshknownhostfile":"~/.ssh/assh_known_hosts"}`)
})
}

Expand Down Expand Up @@ -1448,7 +1451,7 @@ Host zzz
HashKnownHosts no
HostbasedAuthentication no
HostbasedKeyTypes *
HostKeyAlgorithms ecdsa-sha2-nistp256-cert-v01@openssh.com
HostKeyAlgorithms ecdsa-sha2-nistp256-cert-v01@openssh.com,test
HostKeyAlias z
IdentitiesOnly yes
IdentityFile ~/.ssh/identity
Expand Down
14 changes: 7 additions & 7 deletions pkg/config/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type Host struct {
HashKnownHosts string `yaml:"hashknownhosts,omitempty,flow" json:"HashKnownHosts,omitempty"`
HostbasedAuthentication string `yaml:"hostbasedauthentication,omitempty,flow" json:"HostbasedAuthentication,omitempty"`
HostbasedKeyTypes string `yaml:"hostbasedkeytypes,omitempty,flow" json:"HostbasedKeyTypes,omitempty"`
HostKeyAlgorithms string `yaml:"hostkeyalgorithms,omitempty,flow" json:"HostKeyAlgorithms,omitempty"`
HostKeyAlgorithms composeyaml.Stringorslice `yaml:"hostkeyalgorithms,omitempty,flow" json:"HostKeyAlgorithms,omitempty"`
HostKeyAlias string `yaml:"hostkeyalias,omitempty,flow" json:"HostKeyAlias,omitempty"`
IdentitiesOnly string `yaml:"identitiesonly,omitempty,flow" json:"IdentitiesOnly,omitempty"`
IdentityAgent string `yaml:"identityagent,omitempty,flow" json:"IdentityAgent,omitempty"`
Expand Down Expand Up @@ -371,8 +371,8 @@ func (h *Host) Options() OptionsList {
if h.HostbasedKeyTypes != "" {
options = append(options, Option{Name: "HostbasedKeyTypes", Value: h.HostbasedKeyTypes})
}
if h.HostKeyAlgorithms != "" {
options = append(options, Option{Name: "HostKeyAlgorithms", Value: h.HostKeyAlgorithms})
if len(h.HostKeyAlgorithms) > 0 {
options = append(options, Option{Name: "HostKeyAlgorithms", Value: strings.Join(h.HostKeyAlgorithms, ",")})
}
if h.HostKeyAlias != "" {
options = append(options, Option{Name: "HostKeyAlias", Value: h.HostKeyAlias})
Expand Down Expand Up @@ -793,10 +793,10 @@ func (h *Host) ApplyDefaults(defaults *Host) {
}
h.HostbasedKeyTypes = utils.ExpandField(h.HostbasedKeyTypes)

if h.HostKeyAlgorithms == "" {
if len(h.HostKeyAlgorithms) == 0 {
h.HostKeyAlgorithms = defaults.HostKeyAlgorithms
}
h.HostKeyAlgorithms = utils.ExpandField(h.HostKeyAlgorithms)
h.HostKeyAlgorithms = utils.ExpandSliceField(h.HostKeyAlgorithms)

if h.HostKeyAlias == "" {
h.HostKeyAlias = defaults.HostKeyAlias
Expand Down Expand Up @@ -1286,8 +1286,8 @@ func (h *Host) WriteSSHConfigTo(w io.Writer) error {
if h.HostbasedKeyTypes != "" {
_, _ = fmt.Fprintf(w, " HostbasedKeyTypes %s\n", h.HostbasedKeyTypes)
}
if h.HostKeyAlgorithms != "" {
_, _ = fmt.Fprintf(w, " HostKeyAlgorithms %s\n", h.HostKeyAlgorithms)
if len(h.HostKeyAlgorithms) > 0 {
_, _ = fmt.Fprintf(w, " HostKeyAlgorithms %s\n", strings.Join(h.HostKeyAlgorithms, ","))
}
if h.HostKeyAlias != "" {
_, _ = fmt.Fprintf(w, " HostKeyAlias %s\n", h.HostKeyAlias)
Expand Down
Loading

0 comments on commit 6664fb4

Please sign in to comment.