From 0e76c5e50227ca2fc4e8e8846b0ec911f26e0684 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 26 Jun 2010 09:39:59 +1000 Subject: - djm@cvs.openbsd.org 2010/06/22 04:54:30 [ssh-keyscan.c] replace verbose and overflow-prone Linebuf code with read_keyfile_line() based on patch from joachim AT joachimschipper.nl; bz#1565; ok dtucker@ --- ssh-keyscan.c | 165 +++++++++++++--------------------------------------------- 1 file changed, 36 insertions(+), 129 deletions(-) (limited to 'ssh-keyscan.c') diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 7afe446ae..b6cf427cd 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.82 2010/06/22 04:54:30 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -104,122 +104,6 @@ typedef struct Connection { TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */ con *fdcon; -/* - * This is just a wrapper around fgets() to make it usable. - */ - -/* Stress-test. Increase this later. */ -#define LINEBUF_SIZE 16 - -typedef struct { - char *buf; - u_int size; - int lineno; - const char *filename; - FILE *stream; - void (*errfun) (const char *,...); -} Linebuf; - -static Linebuf * -Linebuf_alloc(const char *filename, void (*errfun) (const char *,...)) -{ - Linebuf *lb; - - if (!(lb = malloc(sizeof(*lb)))) { - if (errfun) - (*errfun) ("linebuf (%s): malloc failed\n", - filename ? filename : "(stdin)"); - return (NULL); - } - if (filename) { - lb->filename = filename; - if (!(lb->stream = fopen(filename, "r"))) { - xfree(lb); - if (errfun) - (*errfun) ("%s: %s\n", filename, strerror(errno)); - return (NULL); - } - } else { - lb->filename = "(stdin)"; - lb->stream = stdin; - } - - if (!(lb->buf = malloc((lb->size = LINEBUF_SIZE)))) { - if (errfun) - (*errfun) ("linebuf (%s): malloc failed\n", lb->filename); - xfree(lb); - return (NULL); - } - lb->errfun = errfun; - lb->lineno = 0; - return (lb); -} - -static void -Linebuf_free(Linebuf * lb) -{ - fclose(lb->stream); - xfree(lb->buf); - xfree(lb); -} - -#if 0 -static void -Linebuf_restart(Linebuf * lb) -{ - clearerr(lb->stream); - rewind(lb->stream); - lb->lineno = 0; -} - -static int -Linebuf_lineno(Linebuf * lb) -{ - return (lb->lineno); -} -#endif - -static char * -Linebuf_getline(Linebuf * lb) -{ - size_t n = 0; - void *p; - - lb->lineno++; - for (;;) { - /* Read a line */ - if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) { - if (ferror(lb->stream) && lb->errfun) - (*lb->errfun)("%s: %s\n", lb->filename, - strerror(errno)); - return (NULL); - } - n = strlen(lb->buf); - - /* Return it or an error if it fits */ - if (n > 0 && lb->buf[n - 1] == '\n') { - lb->buf[n - 1] = '\0'; - return (lb->buf); - } - if (n != lb->size - 1) { - if (lb->errfun) - (*lb->errfun)("%s: skipping incomplete last line\n", - lb->filename); - return (NULL); - } - /* Double the buffer if we need more space */ - lb->size *= 2; - if ((p = realloc(lb->buf, lb->size)) == NULL) { - lb->size /= 2; - if (lb->errfun) - (*lb->errfun)("linebuf (%s): realloc failed\n", - lb->filename); - return (NULL); - } - lb->buf = p; - } -} - static int fdlim_get(int hard) { @@ -724,8 +608,10 @@ int main(int argc, char **argv) { int debug_flag = 0, log_level = SYSLOG_LEVEL_INFO; - int opt, fopt_count = 0; - char *tname; + int opt, fopt_count = 0, j; + char *tname, *cp, line[NI_MAXHOST]; + FILE *fp; + u_long linenum; extern int optind; extern char *optarg; @@ -826,19 +712,40 @@ main(int argc, char **argv) read_wait_nfdset = howmany(maxfd, NFDBITS); read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); - if (fopt_count) { - Linebuf *lb; - char *line; - int j; + for (j = 0; j < fopt_count; j++) { + if (argv[j] == NULL) + fp = stdin; + else if ((fp = fopen(argv[j], "r")) == NULL) + fatal("%s: %s: %s", __progname, argv[j], + strerror(errno)); + linenum = 0; + + while (read_keyfile_line(fp, + argv[j] == NULL ? "(stdin)" : argv[j], line, sizeof(line), + &linenum) != -1) { + /* Chomp off trailing whitespace and comments */ + if ((cp = strchr(line, '#')) == NULL) + cp = line + strlen(line) - 1; + while (cp >= line) { + if (*cp == ' ' || *cp == '\t' || + *cp == '\n' || *cp == '#') + *cp-- = '\0'; + else + break; + } - for (j = 0; j < fopt_count; j++) { - lb = Linebuf_alloc(argv[j], error); - if (!lb) + /* Skip empty lines */ + if (*line == '\0') continue; - while ((line = Linebuf_getline(lb)) != NULL) - do_host(line); - Linebuf_free(lb); + + do_host(line); } + + if (ferror(fp)) + fatal("%s: %s: %s", __progname, argv[j], + strerror(errno)); + + fclose(fp); } while (optind < argc) -- cgit v1.2.3