@@ -176,39 +176,41 @@ func nextWord(line []byte) (string, []byte) {
176
176
return string (line [:i ]), bytes .TrimSpace (line [i :])
177
177
}
178
178
179
- func parseLine (line []byte ) (marker , host string , key ssh.PublicKey , err error ) {
179
+ func parseLine (line []byte ) (marker , host , comments string , key ssh.PublicKey , err error ) {
180
180
if w , next := nextWord (line ); w == markerCert || w == markerRevoked {
181
181
marker = w
182
182
line = next
183
183
}
184
184
185
185
host , line = nextWord (line )
186
186
if len (line ) == 0 {
187
- return "" , "" , nil , errors .New ("knownhosts: missing host pattern" )
187
+ return "" , "" , "" , nil , errors .New ("knownhosts: missing host pattern" )
188
188
}
189
189
190
190
// ignore the keytype as it's in the key blob anyway.
191
191
_ , line = nextWord (line )
192
192
if len (line ) == 0 {
193
- return "" , "" , nil , errors .New ("knownhosts: missing key type pattern" )
193
+ return "" , "" , "" , nil , errors .New ("knownhosts: missing key type pattern" )
194
194
}
195
195
196
- keyBlob , _ := nextWord (line )
196
+ keyBlob , line := nextWord (line )
197
197
198
198
keyBytes , err := base64 .StdEncoding .DecodeString (keyBlob )
199
199
if err != nil {
200
- return "" , "" , nil , err
200
+ return "" , "" , "" , nil , err
201
201
}
202
202
key , err = ssh .ParsePublicKey (keyBytes )
203
203
if err != nil {
204
- return "" , "" , nil , err
204
+ return "" , "" , "" , nil , err
205
205
}
206
+ // the rest of the line is the comment, and may include whitespace.
207
+ restOfLine := string (bytes .TrimSpace (line ))
206
208
207
- return marker , host , key , nil
209
+ return marker , host , restOfLine , key , nil
208
210
}
209
211
210
212
func (db * hostKeyDB ) parseLine (line []byte , filename string , linenum int ) error {
211
- marker , pattern , key , err := parseLine (line )
213
+ marker , pattern , comments , key , err := parseLine (line )
212
214
if err != nil {
213
215
return err
214
216
}
@@ -218,6 +220,7 @@ func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error
218
220
Key : key ,
219
221
Filename : filename ,
220
222
Line : linenum ,
223
+ Comments : comments ,
221
224
}
222
225
223
226
return nil
@@ -229,6 +232,7 @@ func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error
229
232
Filename : filename ,
230
233
Line : linenum ,
231
234
Key : key ,
235
+ Comments : comments ,
232
236
},
233
237
}
234
238
@@ -241,7 +245,6 @@ func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error
241
245
if err != nil {
242
246
return err
243
247
}
244
-
245
248
db .lines = append (db .lines , entry )
246
249
return nil
247
250
}
@@ -290,10 +293,11 @@ type KnownKey struct {
290
293
Key ssh.PublicKey
291
294
Filename string
292
295
Line int
296
+ Comments string
293
297
}
294
298
295
299
func (k * KnownKey ) String () string {
296
- return fmt .Sprintf ("%s:%d: %s" , k .Filename , k .Line , serialize (k .Key ))
300
+ return fmt .Sprintf ("%s:%d: %s %s " , k .Filename , k .Line , serialize (k .Key ), k . Comments )
297
301
}
298
302
299
303
// KeyError is returned if we did not find the key in the host key
@@ -435,6 +439,26 @@ func New(files ...string) (ssh.HostKeyCallback, error) {
435
439
return certChecker .CheckHostKey , nil
436
440
}
437
441
442
+ func NewKnownKeys (files ... string ) ([]KnownKey , error ) {
443
+ db := newHostKeyDB ()
444
+ for _ , fn := range files {
445
+ f , err := os .Open (fn )
446
+ if err != nil {
447
+ return nil , err
448
+ }
449
+ defer f .Close ()
450
+ if err := db .Read (f , fn ); err != nil {
451
+ return nil , err
452
+ }
453
+ }
454
+
455
+ keys := make ([]KnownKey , 0 , len (db .lines ))
456
+ for _ , l := range db .lines {
457
+ keys = append (keys , l .knownKey )
458
+ }
459
+ return keys , nil
460
+ }
461
+
438
462
// Normalize normalizes an address into the form used in known_hosts
439
463
func Normalize (address string ) string {
440
464
host , port , err := net .SplitHostPort (address )
0 commit comments