From 8056a9d46ac2d75560c2fd9fc69c75ee46a43922 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 15 Mar 2006 12:05:40 +1100 Subject: - dtucker@cvs.openbsd.org 2006/03/13 08:43:16 [ssh-keygen.c] Make ssh-keygen handle CR and CRLF line termination when converting IETF format keys, in adition to vanilla LF. mindrot #1157, tested by Chris Pepper, ok djm@ --- ChangeLog | 7 ++++++- ssh-keygen.c | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cc666a58..74ece7805 100644 --- a/ChangeLog +++ b/ChangeLog @@ -215,6 +215,11 @@ Set TCP_NODELAY for all connections not just "interactive" ones. Fixes poor performance and protocol stalls under some network conditions (mindrot bugs #556 and #981). Patch originally from markus@, ok djm@ + - dtucker@cvs.openbsd.org 2006/03/13 08:43:16 + [ssh-keygen.c] + Make ssh-keygen handle CR and CRLF line termination when converting IETF + format keys, in adition to vanilla LF. mindrot #1157, tested by Chris + Pepper, ok djm@ 20060313 - (dtucker) [configure.ac] Bug #1171: Don't use printf("%lld", longlong) @@ -4116,4 +4121,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4201 2006/03/15 01:05:22 djm Exp $ +$Id: ChangeLog,v 1.4202 2006/03/15 01:05:40 djm Exp $ diff --git a/ssh-keygen.c b/ssh-keygen.c index 8acbf7783..bea4ed59b 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keygen.c,v 1.136 2006/02/20 17:19:54 stevesk Exp $"); +RCSID("$OpenBSD: ssh-keygen.c,v 1.137 2006/03/13 08:43:16 dtucker Exp $"); #include #include @@ -305,13 +305,42 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) return key; } +static int +get_line(FILE *fp, char *line, size_t len) +{ + int c; + size_t pos = 0; + + line[0] = '\0'; + while ((c = fgetc(fp)) != EOF) { + if (pos >= len - 1) { + fprintf(stderr, "input line too long.\n"); + exit(1); + } + switch(c) { + case '\r': + c = fgetc(fp); + if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) { + fprintf(stderr, "unget: %s\n", strerror(errno)); + exit(1); + } + return pos; + case '\n': + return pos; + } + line[pos++] = c; + line[pos] = '\0'; + } + return pos; +} + static void do_convert_from_ssh2(struct passwd *pw) { Key *k; int blen; u_int len; - char line[1024], *p; + char line[1024]; u_char blob[8096]; char encoded[8096]; struct stat st; @@ -330,12 +359,8 @@ do_convert_from_ssh2(struct passwd *pw) exit(1); } encoded[0] = '\0'; - while (fgets(line, sizeof(line), fp)) { - if (!(p = strchr(line, '\n'))) { - fprintf(stderr, "input line too long.\n"); - exit(1); - } - if (p > line && p[-1] == '\\') + while ((blen = get_line(fp, line, sizeof(line))) != -1) { + if (line[blen - 1] == '\\') escaped++; if (strncmp(line, "----", 4) == 0 || strstr(line, ": ") != NULL) { @@ -352,7 +377,6 @@ do_convert_from_ssh2(struct passwd *pw) /* fprintf(stderr, "escaped: %s", line); */ continue; } - *p = '\0'; strlcat(encoded, line, sizeof(encoded)); } len = strlen(encoded); -- cgit v1.2.3