@@ -176,39 +176,41 @@ func nextWord(line []byte) (string, []byte) {
176176	return  string (line [:i ]), bytes .TrimSpace (line [i :])
177177}
178178
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 ) {
180180	if  w , next  :=  nextWord (line ); w  ==  markerCert  ||  w  ==  markerRevoked  {
181181		marker  =  w 
182182		line  =  next 
183183	}
184184
185185	host , line  =  nextWord (line )
186186	if  len (line ) ==  0  {
187- 		return  "" , "" , nil , errors .New ("knownhosts: missing host pattern" )
187+ 		return  "" , "" , "" ,  nil , errors .New ("knownhosts: missing host pattern" )
188188	}
189189
190190	// ignore the keytype as it's in the key blob anyway. 
191191	_ , line  =  nextWord (line )
192192	if  len (line ) ==  0  {
193- 		return  "" , "" , nil , errors .New ("knownhosts: missing key type pattern" )
193+ 		return  "" , "" , "" ,  nil , errors .New ("knownhosts: missing key type pattern" )
194194	}
195195
196- 	keyBlob , _  :=  nextWord (line )
196+ 	keyBlob , line  :=  nextWord (line )
197197
198198	keyBytes , err  :=  base64 .StdEncoding .DecodeString (keyBlob )
199199	if  err  !=  nil  {
200- 		return  "" , "" , nil , err 
200+ 		return  "" , "" , "" ,  nil , err 
201201	}
202202	key , err  =  ssh .ParsePublicKey (keyBytes )
203203	if  err  !=  nil  {
204- 		return  "" , "" , nil , err 
204+ 		return  "" , "" , "" ,  nil , err 
205205	}
206+ 	// the rest of the line is the comment, and may include whitespace. 
207+ 	restOfLine  :=  string (bytes .TrimSpace (line ))
206208
207- 	return  marker , host , key , nil 
209+ 	return  marker , host , restOfLine ,  key , nil 
208210}
209211
210212func  (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 )
212214	if  err  !=  nil  {
213215		return  err 
214216	}
@@ -218,6 +220,7 @@ func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error
218220			Key :      key ,
219221			Filename : filename ,
220222			Line :     linenum ,
223+ 			Comments : comments ,
221224		}
222225
223226		return  nil 
@@ -229,6 +232,7 @@ func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error
229232			Filename : filename ,
230233			Line :     linenum ,
231234			Key :      key ,
235+ 			Comments : comments ,
232236		},
233237	}
234238
@@ -241,7 +245,6 @@ func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error
241245	if  err  !=  nil  {
242246		return  err 
243247	}
244- 
245248	db .lines  =  append (db .lines , entry )
246249	return  nil 
247250}
@@ -290,10 +293,11 @@ type KnownKey struct {
290293	Key       ssh.PublicKey 
291294	Filename  string 
292295	Line      int 
296+ 	Comments  string 
293297}
294298
295299func  (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 )
297301}
298302
299303// 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) {
435439	return  certChecker .CheckHostKey , nil 
436440}
437441
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+ 
438462// Normalize normalizes an address into the form used in known_hosts 
439463func  Normalize (address  string ) string  {
440464	host , port , err  :=  net .SplitHostPort (address )
0 commit comments