1- /* $OpenBSD: hostfile.c,v 1.95 2023/02/21 06:48:18 dtucker Exp $ */
1+ /* $OpenBSD: hostfile.c,v 1.97 2025/04/30 05:26:15 djm Exp $ */
22/*
33 * Author: Tatu Ylonen <ylo@cs.hut.fi>
44 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -434,7 +434,7 @@ lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker)
434434}
435435
436436static int
437- write_host_entry ( FILE * f , const char * host , const char * ip ,
437+ format_host_entry ( struct sshbuf * entry , const char * host , const char * ip ,
438438 const struct sshkey * key , int store_hash )
439439{
440440 int r , success = 0 ;
@@ -449,22 +449,50 @@ write_host_entry(FILE *f, const char *host, const char *ip,
449449 free (lhost );
450450 return 0 ;
451451 }
452- fprintf (f , "%s " , hashed_host );
453- } else if (ip != NULL )
454- fprintf (f , "%s,%s " , lhost , ip );
455- else {
456- fprintf (f , "%s " , lhost );
452+ if ((r = sshbuf_putf (entry , "%s " , hashed_host )) != 0 )
453+ fatal_fr (r , "sshbuf_putf" );
454+ } else if (ip != NULL ) {
455+ if ((r = sshbuf_putf (entry , "%s,%s " , lhost , ip )) != 0 )
456+ fatal_fr (r , "sshbuf_putf" );
457+ } else {
458+ if ((r = sshbuf_putf (entry , "%s " , lhost )) != 0 )
459+ fatal_fr (r , "sshbuf_putf" );
457460 }
458461 free (hashed_host );
459462 free (lhost );
460- if ((r = sshkey_write (key , f )) == 0 )
463+ if ((r = sshkey_format_text (key , entry )) == 0 )
461464 success = 1 ;
462465 else
463466 error_fr (r , "sshkey_write" );
464- fputc ('\n' , f );
467+ if ((r = sshbuf_putf (entry , "\n" )) != 0 )
468+ fatal_fr (r , "sshbuf_putf" );
469+
465470 /* If hashing is enabled, the IP address needs to go on its own line */
466471 if (success && store_hash && ip != NULL )
467- success = write_host_entry (f , ip , NULL , key , 1 );
472+ success = format_host_entry (entry , ip , NULL , key , 1 );
473+ return success ;
474+ }
475+
476+ static int
477+ write_host_entry (FILE * f , const char * host , const char * ip ,
478+ const struct sshkey * key , int store_hash )
479+ {
480+ int r , success = 0 ;
481+ struct sshbuf * entry = NULL ;
482+
483+ if ((entry = sshbuf_new ()) == NULL )
484+ fatal_f ("allocation failed" );
485+ if ((r = format_host_entry (entry , host , ip , key , store_hash )) != 1 ) {
486+ debug_f ("failed to format host entry" );
487+ goto out ;
488+ }
489+ if ((r = fwrite (sshbuf_ptr (entry ), sshbuf_len (entry ), 1 , f )) != 1 ) {
490+ error_f ("fwrite: %s" , strerror (errno ));
491+ goto out ;
492+ }
493+ success = 1 ;
494+ out :
495+ sshbuf_free (entry );
468496 return success ;
469497}
470498
@@ -520,9 +548,9 @@ add_host_to_hostfile(const char *filename, const char *host,
520548 if (key == NULL )
521549 return 1 ; /* XXX ? */
522550 hostfile_create_user_ssh_dir (filename , 0 );
523- f = fopen (filename , "a+" );
524- if (!f )
551+ if ((f = fopen (filename , "a+" )) == NULL )
525552 return 0 ;
553+ setvbuf (f , NULL , _IONBF , 0 );
526554 /* Make sure we have a terminating newline. */
527555 if (fseek (f , -1L , SEEK_END ) == 0 && fgetc (f ) != '\n' )
528556 addnl = 1 ;
@@ -810,6 +838,12 @@ hostkeys_foreach_file(const char *path, FILE *f, hostkeys_foreach_fn *callback,
810838 /* Find the end of the host name portion. */
811839 for (cp2 = cp ; * cp2 && * cp2 != ' ' && * cp2 != '\t' ; cp2 ++ )
812840 ;
841+ if (* cp2 == '\0' ) {
842+ verbose_f ("truncated line at %s:%lu" , path , linenum );
843+ if ((options & HKF_WANT_MATCH ) == 0 )
844+ goto bad ;
845+ continue ;
846+ }
813847 lineinfo .hosts = cp ;
814848 * cp2 ++ = '\0' ;
815849
0 commit comments