Skip to content

Commit ba9d693

Browse files
committed
plumbing: support setting custom host key algorithms along with host key callback
1 parent 61916be commit ba9d693

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

Diff for: plumbing/transport/ssh/auth_method.go

+14-11
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (a *KeyboardInteractive) String() string {
5454
}
5555

5656
func (a *KeyboardInteractive) ClientConfig() (*ssh.ClientConfig, error) {
57-
return a.SetHostKeyCallback(&ssh.ClientConfig{
57+
return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
5858
User: a.User,
5959
Auth: []ssh.AuthMethod{
6060
a.Challenge,
@@ -78,7 +78,7 @@ func (a *Password) String() string {
7878
}
7979

8080
func (a *Password) ClientConfig() (*ssh.ClientConfig, error) {
81-
return a.SetHostKeyCallback(&ssh.ClientConfig{
81+
return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
8282
User: a.User,
8383
Auth: []ssh.AuthMethod{ssh.Password(a.Password)},
8484
})
@@ -101,7 +101,7 @@ func (a *PasswordCallback) String() string {
101101
}
102102

103103
func (a *PasswordCallback) ClientConfig() (*ssh.ClientConfig, error) {
104-
return a.SetHostKeyCallback(&ssh.ClientConfig{
104+
return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
105105
User: a.User,
106106
Auth: []ssh.AuthMethod{ssh.PasswordCallback(a.Callback)},
107107
})
@@ -150,7 +150,7 @@ func (a *PublicKeys) String() string {
150150
}
151151

152152
func (a *PublicKeys) ClientConfig() (*ssh.ClientConfig, error) {
153-
return a.SetHostKeyCallback(&ssh.ClientConfig{
153+
return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
154154
User: a.User,
155155
Auth: []ssh.AuthMethod{ssh.PublicKeys(a.Signer)},
156156
})
@@ -211,7 +211,7 @@ func (a *PublicKeysCallback) String() string {
211211
}
212212

213213
func (a *PublicKeysCallback) ClientConfig() (*ssh.ClientConfig, error) {
214-
return a.SetHostKeyCallback(&ssh.ClientConfig{
214+
return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
215215
User: a.User,
216216
Auth: []ssh.AuthMethod{ssh.PublicKeysCallback(a.Callback)},
217217
})
@@ -301,20 +301,23 @@ func filterKnownHostsFiles(files ...string) ([]string, error) {
301301
}
302302

303303
// HostKeyCallbackHelper is a helper that provides common functionality to
304-
// configure HostKeyCallback into a ssh.ClientConfig.
304+
// configure HostKeyCallback and HostKeyAlgorithms into a ssh.ClientConfig.
305305
type HostKeyCallbackHelper struct {
306306
// HostKeyCallback is the function type used for verifying server keys.
307307
// If nil, a default callback will be created using NewKnownHostsDb
308308
// without argument.
309309
HostKeyCallback ssh.HostKeyCallback
310310

311+
// HostKeyAlgorithms is a list of supported host key algorithms that will
312+
// be used for host key verification.
313+
HostKeyAlgorithms []string
311314
}
312315

313-
// SetHostKeyCallback sets the field HostKeyCallback in the given cfg.
314-
// If the host key callback is empty it is left empty. It will be handled
315-
// by the dial method by falling back to knownhosts.
316-
func (m *HostKeyCallbackHelper) SetHostKeyCallback(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) {
317-
316+
// SetHostKeyCallbackAndAlgorithms sets the field HostKeyCallback and HostKeyAlgorithms in the given cfg.
317+
// If the host key callback or algorithms is empty it is left empty. It will be handled by the dial method,
318+
// falling back to knownhosts.
319+
func (m *HostKeyCallbackHelper) SetHostKeyCallbackAndAlgorithms(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) {
318320
cfg.HostKeyCallback = m.HostKeyCallback
321+
cfg.HostKeyAlgorithms = m.HostKeyAlgorithms
319322
return cfg, nil
320323
}

Diff for: plumbing/transport/ssh/common_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,35 @@ func (s *SuiteCommon) TestFixedHostKeyCallback(c *C) {
129129
c.Assert(err, IsNil)
130130
c.Assert(auth, NotNil)
131131
auth.HostKeyCallback = stdssh.FixedHostKey(hostKey.PublicKey())
132+
auth.HostKeyAlgorithms = []string{"ssh-ed25519"}
132133
ep := uploadPack.newEndpoint(c, "bar.git")
133134
ps, err := uploadPack.Client.NewUploadPackSession(ep, auth)
134135
c.Assert(err, IsNil)
135136
c.Assert(ps, NotNil)
136137
}
137138

139+
func (s *SuiteCommon) TestFixedHostKeyCallbackUnexpectedAlgorithm(c *C) {
140+
hostKey, err := stdssh.ParsePrivateKey(testdata.PEMBytes["ed25519"])
141+
c.Assert(err, IsNil)
142+
uploadPack := &UploadPackSuite{
143+
opts: []ssh.Option{
144+
ssh.HostKeyPEM(testdata.PEMBytes["rsa"]),
145+
},
146+
}
147+
uploadPack.SetUpSuite(c)
148+
// Use the default client, which does not have a host key callback
149+
uploadPack.Client = DefaultClient
150+
auth, err := NewPublicKeys("foo", testdata.PEMBytes["rsa"], "")
151+
c.Assert(err, IsNil)
152+
c.Assert(auth, NotNil)
153+
auth.HostKeyCallback = stdssh.FixedHostKey(hostKey.PublicKey())
154+
auth.HostKeyAlgorithms = []string{"ssh-ed25519"}
155+
ep := uploadPack.newEndpoint(c, "bar.git")
156+
ps, err := uploadPack.Client.NewUploadPackSession(ep, auth)
157+
c.Assert(err, NotNil)
158+
c.Assert(ps, IsNil)
159+
}
160+
138161
func (s *SuiteCommon) TestFailHostKeyCallback(c *C) {
139162
uploadPack := &UploadPackSuite{
140163
opts: []ssh.Option{

0 commit comments

Comments
 (0)