Skip to content

Commit

Permalink
upstream: switch config file parsing to getline(3) as this avoids
Browse files Browse the repository at this point in the history
static limits noted by gerhard@; ok dtucker@, djm@

OpenBSD-Commit-ID: 6d702eabef0fa12e5a1d75c334a8c8b325298b5c
  • Loading branch information
mfriedl authored and djmdjm committed Jun 6, 2018
1 parent 392db2b commit 7f90635
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 94 deletions.
16 changes: 11 additions & 5 deletions auth2-pubkey.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.78 2018/06/01 03:33:53 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.79 2018/06/06 18:29:18 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -319,14 +319,16 @@ static int
process_principals(struct ssh *ssh, FILE *f, const char *file,
const struct sshkey_cert *cert, struct sshauthopt **authoptsp)
{
char loc[256], line[SSH_MAX_PUBKEY_BYTES], *cp, *ep;
char loc[256], *line = NULL, *cp, *ep;
size_t linesize = 0;
u_long linenum = 0;
u_int found_principal = 0;

if (authoptsp != NULL)
*authoptsp = NULL;

while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
while (getline(&line, &linesize, f) != -1) {
linenum++;
/* Always consume entire input */
if (found_principal)
continue;
Expand All @@ -344,6 +346,7 @@ process_principals(struct ssh *ssh, FILE *f, const char *file,
if (check_principals_line(ssh, cp, cert, loc, authoptsp) == 0)
found_principal = 1;
}
free(line);
return found_principal;
}

Expand Down Expand Up @@ -687,14 +690,16 @@ static int
check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f,
char *file, struct sshkey *key, struct sshauthopt **authoptsp)
{
char *cp, line[SSH_MAX_PUBKEY_BYTES], loc[256];
char *cp, *line = NULL, loc[256];
size_t linesize = 0;
int found_key = 0;
u_long linenum = 0;

if (authoptsp != NULL)
*authoptsp = NULL;

while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
while (getline(&line, &linesize, f) != -1) {
linenum++;
/* Always consume entire file */
if (found_key)
continue;
Expand All @@ -708,6 +713,7 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f,
if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0)
found_key = 1;
}
free(line);
return found_key;
}

Expand Down
22 changes: 11 additions & 11 deletions authfile.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: authfile.c,v 1.128 2018/02/23 15:58:37 markus Exp $ */
/* $OpenBSD: authfile.c,v 1.129 2018/06/06 18:29:18 markus Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -265,17 +265,15 @@ static int
sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
{
FILE *f;
char line[SSH_MAX_PUBKEY_BYTES];
char *cp;
u_long linenum = 0;
char *line = NULL, *cp;
size_t linesize = 0;
int r;

if (commentp != NULL)
*commentp = NULL;
if ((f = fopen(filename, "r")) == NULL)
return SSH_ERR_SYSTEM_ERROR;
while (read_keyfile_line(f, filename, line, sizeof(line),
&linenum) != -1) {
while (getline(&line, &linesize, f) != -1) {
cp = line;
switch (*cp) {
case '#':
Expand All @@ -299,11 +297,13 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
if (*commentp == NULL)
r = SSH_ERR_ALLOC_FAIL;
}
free(line);
fclose(f);
return r;
}
}
}
free(line);
fclose(f);
return SSH_ERR_INVALID_FORMAT;
}
Expand Down Expand Up @@ -447,19 +447,18 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
int check_ca)
{
FILE *f;
char line[SSH_MAX_PUBKEY_BYTES];
char *cp;
u_long linenum = 0;
char *line = NULL, *cp;
size_t linesize = 0;
int r = 0;
struct sshkey *pub = NULL;

int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
strict_type ? sshkey_equal : sshkey_equal_public;

if ((f = fopen(filename, "r")) == NULL)
return SSH_ERR_SYSTEM_ERROR;

while (read_keyfile_line(f, filename, line, sizeof(line),
&linenum) != -1) {
while (getline(&line, &linesize, f) != -1) {
cp = line;

/* Skip leading whitespace. */
Expand Down Expand Up @@ -491,6 +490,7 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
}
r = SSH_ERR_KEY_NOT_FOUND;
out:
free(line);
sshkey_free(pub);
fclose(f);
return r;
Expand Down
18 changes: 12 additions & 6 deletions dh.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: dh.c,v 1.63 2018/02/07 02:06:50 jsing Exp $ */
/* $OpenBSD: dh.c,v 1.64 2018/06/06 18:29:18 markus Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
Expand Down Expand Up @@ -145,9 +145,9 @@ DH *
choose_dh(int min, int wantbits, int max)
{
FILE *f;
char line[4096];
int best, bestcount, which;
int linenum;
char *line = NULL;
size_t linesize = 0;
int best, bestcount, which, linenum;
struct dhgroup dhg;

if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
Expand All @@ -158,7 +158,7 @@ choose_dh(int min, int wantbits, int max)

linenum = 0;
best = bestcount = 0;
while (fgets(line, sizeof(line), f)) {
while (getline(&line, &linesize, f) != -1) {
linenum++;
if (!parse_prime(linenum, line, &dhg))
continue;
Expand All @@ -176,6 +176,9 @@ choose_dh(int min, int wantbits, int max)
if (dhg.size == best)
bestcount++;
}
free(line);
line = NULL;
linesize = 0;
rewind(f);

if (bestcount == 0) {
Expand All @@ -186,7 +189,8 @@ choose_dh(int min, int wantbits, int max)

linenum = 0;
which = arc4random_uniform(bestcount);
while (fgets(line, sizeof(line), f)) {
while (getline(&line, &linesize, f) != -1) {
linenum++;
if (!parse_prime(linenum, line, &dhg))
continue;
if ((dhg.size > max || dhg.size < min) ||
Expand All @@ -198,6 +202,8 @@ choose_dh(int min, int wantbits, int max)
}
break;
}
free(line);
line = NULL;
fclose(f);
if (linenum != which+1) {
logit("WARNING: line %d disappeared in %s, giving up",
Expand Down
15 changes: 9 additions & 6 deletions hostfile.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: hostfile.c,v 1.71 2017/05/31 09:15:42 deraadt Exp $ */
/* $OpenBSD: hostfile.c,v 1.72 2018/06/06 18:29:18 markus Exp $ */
/*
* Author: Tatu Ylonen <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -663,14 +663,14 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
const char *host, const char *ip, u_int options)
{
FILE *f;
char line[8192], oline[8192], ktype[128];
char *line = NULL, ktype[128];
u_long linenum = 0;
char *cp, *cp2;
u_int kbits;
int hashed;
int s, r = 0;
struct hostkey_foreach_line lineinfo;
size_t l;
size_t linesize = 0, l;

memset(&lineinfo, 0, sizeof(lineinfo));
if (host == NULL && (options & HKF_WANT_MATCH) != 0)
Expand All @@ -679,15 +679,16 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
return SSH_ERR_SYSTEM_ERROR;

debug3("%s: reading file \"%s\"", __func__, path);
while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) {
while (getline(&line, &linesize, f) != -1) {
linenum++;
line[strcspn(line, "\n")] = '\0';
strlcpy(oline, line, sizeof(oline));

sshkey_free(lineinfo.key);
memset(&lineinfo, 0, sizeof(lineinfo));
lineinfo.path = path;
lineinfo.linenum = linenum;
lineinfo.line = oline;
free(lineinfo.line);
lineinfo.line = xstrdup(line);
lineinfo.marker = MRK_NONE;
lineinfo.status = HKF_STATUS_OK;
lineinfo.keytype = KEY_UNSPEC;
Expand Down Expand Up @@ -826,6 +827,8 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
break;
}
sshkey_free(lineinfo.key);
free(lineinfo.line);
free(line);
fclose(f);
return r;
}
27 changes: 1 addition & 26 deletions misc.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.127 2018/03/12 00:52:01 djm Exp $ */
/* $OpenBSD: misc.c,v 1.128 2018/06/06 18:29:18 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
Expand Down Expand Up @@ -1005,31 +1005,6 @@ percent_expand(const char *string, ...)
#undef EXPAND_MAX_KEYS
}

/*
* Read an entire line from a public key file into a static buffer, discarding
* lines that exceed the buffer size. Returns 0 on success, -1 on failure.
*/
int
read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
u_long *lineno)
{
while (fgets(buf, bufsz, f) != NULL) {
if (buf[0] == '\0')
continue;
(*lineno)++;
if (buf[strlen(buf) - 1] == '\n' || feof(f)) {
return 0;
} else {
debug("%s: %s line %lu exceeds size limit", __func__,
filename, *lineno);
/* discard remainder of line */
while (fgetc(f) != '\n' && !feof(f))
; /* nothing */
}
}
return -1;
}

int
tun_open(int tun, int mode, char **ifname)
{
Expand Down
3 changes: 1 addition & 2 deletions misc.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: misc.h,v 1.71 2018/03/12 00:52:01 djm Exp $ */
/* $OpenBSD: misc.h,v 1.72 2018/06/06 18:29:18 markus Exp $ */

/*
* Author: Tatu Ylonen <[email protected]>
Expand Down Expand Up @@ -166,7 +166,6 @@ int safe_path_fd(int, const char *, struct passwd *,

char *read_passphrase(const char *, int);
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);

#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
Expand Down
10 changes: 5 additions & 5 deletions readconf.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.288 2018/06/01 03:33:53 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.289 2018/06/06 18:29:18 markus Exp $ */
/*
* Author: Tatu Ylonen <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -1728,7 +1728,8 @@ read_config_file_depth(const char *filename, struct passwd *pw,
int flags, int *activep, int depth)
{
FILE *f;
char line[4096];
char *line = NULL;
size_t linesize = 0;
int linenum;
int bad_options = 0;

Expand All @@ -1755,15 +1756,14 @@ read_config_file_depth(const char *filename, struct passwd *pw,
* on/off by Host specifications.
*/
linenum = 0;
while (fgets(line, sizeof(line), f)) {
while (getline(&line, &linesize, f) != -1) {
/* Update line number counter. */
linenum++;
if (strlen(line) == sizeof(line) - 1)
fatal("%s line %d too long", filename, linenum);
if (process_config_line_depth(options, pw, host, original_host,
line, filename, linenum, activep, flags, depth) != 0)
bad_options++;
}
free(line);
fclose(f);
if (bad_options > 0)
fatal("%s: terminating, %d bad configuration options",
Expand Down
10 changes: 5 additions & 5 deletions servconf.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* $OpenBSD: servconf.c,v 1.330 2018/06/06 18:23:32 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.331 2018/06/06 18:29:18 markus Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
* All rights reserved
Expand Down Expand Up @@ -2103,7 +2103,8 @@ process_server_config_line(ServerOptions *options, char *line,
void
load_server_config(const char *filename, Buffer *conf)
{
char line[4096], *cp;
char *line = NULL, *cp;
size_t linesize = 0;
FILE *f;
int lineno = 0;

Expand All @@ -2113,10 +2114,8 @@ load_server_config(const char *filename, Buffer *conf)
exit(1);
}
buffer_clear(conf);
while (fgets(line, sizeof(line), f)) {
while (getline(&line, &linesize, f) != -1) {
lineno++;
if (strlen(line) == sizeof(line) - 1)
fatal("%s line %d too long", filename, lineno);
/*
* Trim out comments and strip whitespace
* NB - preserve newlines, they are needed to reproduce
Expand All @@ -2128,6 +2127,7 @@ load_server_config(const char *filename, Buffer *conf)

buffer_append(conf, cp, strlen(cp));
}
free(line);
buffer_append(conf, "\0", 1);
fclose(f);
debug2("%s: done config len = %d", __func__, buffer_len(conf));
Expand Down
Loading

0 comments on commit 7f90635

Please sign in to comment.