From ea067773e7c51e90cd791dc3946834dd804fa844 Mon Sep 17 00:00:00 2001 From: dtucker Date: Mon, 6 Dec 2004 11:47:41 +0000 Subject: [PATCH] - dtucker@cvs.openbsd.org 2004/12/06 11:41:03 [auth-rsa.c auth2-pubkey.c authfile.c misc.c misc.h ssh.h sshd.8] Discard over-length authorized_keys entries rather than complaining when they don't decode. bz #884, with & ok djm@ --- ChangeLog | 4 ++++ auth-rsa.c | 10 ++++------ auth2-pubkey.c | 9 +++++---- authfile.c | 9 +++++---- misc.c | 25 ++++++++++++++++++++++++- misc.h | 3 ++- ssh.h | 9 ++++++++- sshd.8 | 6 ++++-- 8 files changed, 56 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index c1d19601..72d49000 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,10 @@ - describe ls flags as a list - other minor improvements ok jmc, djm + - dtucker@cvs.openbsd.org 2004/12/06 11:41:03 + [auth-rsa.c auth2-pubkey.c authfile.c misc.c misc.h ssh.h sshd.8] + Discard over-length authorized_keys entries rather than complaining when + they don't decode. bz #884, with & ok djm@ 20041203 - (dtucker) OpenBSD CVS Sync diff --git a/auth-rsa.c b/auth-rsa.c index 16369d47..2060f839 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rsa.c,v 1.60 2004/06/21 17:36:31 avsm Exp $"); +RCSID("$OpenBSD: auth-rsa.c,v 1.61 2004/12/06 11:41:03 dtucker Exp $"); #include #include @@ -49,7 +49,7 @@ extern u_char session_id[16]; * options bits e n comment * where bits, e and n are decimal numbers, * and comment is any string of characters up to newline. The maximum - * length of a line is 8000 characters. See the documentation for a + * length of a line is SSH_MAX_PUBKEY_BYTES characters. See sshd(8) for a * description of the options. */ @@ -152,7 +152,7 @@ auth_rsa_challenge_dialog(Key *key) int auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) { - char line[8192], *file; + char line[SSH_MAX_PUBKEY_BYTES], *file; int allowed = 0; u_int bits; FILE *f; @@ -201,12 +201,10 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) * found, perform a challenge-response dialog to verify that the * user really has the corresponding private key. */ - while (fgets(line, sizeof(line), f)) { + while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { char *cp; char *key_options; - linenum++; - /* Skip leading whitespace, empty and comment lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; diff --git a/auth2-pubkey.c b/auth2-pubkey.c index bafea09d..41e23beb 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -23,8 +23,9 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-pubkey.c,v 1.7 2004/06/21 17:36:31 avsm Exp $"); +RCSID("$OpenBSD: auth2-pubkey.c,v 1.8 2004/12/06 11:41:03 dtucker Exp $"); +#include "ssh.h" #include "ssh2.h" #include "xmalloc.h" #include "packet.h" @@ -167,7 +168,7 @@ done: static int user_key_allowed2(struct passwd *pw, Key *key, char *file) { - char line[8192]; + char line[SSH_MAX_PUBKEY_BYTES]; int found_key = 0; FILE *f; u_long linenum = 0; @@ -204,9 +205,9 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) found_key = 0; found = key_new(key->type); - while (fgets(line, sizeof(line), f)) { + while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { char *cp, *key_options = NULL; - linenum++; + /* Skip leading whitespace, empty and comment lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; diff --git a/authfile.c b/authfile.c index 1c006c43..4038ab69 100644 --- a/authfile.c +++ b/authfile.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfile.c,v 1.58 2004/08/23 11:48:09 djm Exp $"); +RCSID("$OpenBSD: authfile.c,v 1.59 2004/12/06 11:41:03 dtucker Exp $"); #include #include @@ -601,13 +601,14 @@ static int key_try_load_public(Key *k, const char *filename, char **commentp) { FILE *f; - char line[4096]; + char line[SSH_MAX_PUBKEY_BYTES]; char *cp; + int linenum = 0; f = fopen(filename, "r"); if (f != NULL) { - while (fgets(line, sizeof(line), f)) { - line[sizeof(line)-1] = '\0'; + while (read_keyfile_line(f, filename, line, sizeof(line), + &linenum) != -1) { cp = line; switch (*cp) { case '#': diff --git a/misc.c b/misc.c index 8cb411cc..d0cc5382 100644 --- a/misc.c +++ b/misc.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.25 2004/08/11 21:43:05 avsm Exp $"); +RCSID("$OpenBSD: misc.c,v 1.26 2004/12/06 11:41:03 dtucker Exp $"); #include "misc.h" #include "log.h" @@ -332,3 +332,26 @@ addargs(arglist *args, char *fmt, ...) args->list[args->num++] = xstrdup(buf); args->list[args->num] = NULL; } + +/* + * 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, + int *lineno) +{ + while (fgets(buf, bufsz, f) != NULL) { + (*lineno)++; + if (buf[strlen(buf) - 1] == '\n' || feof(f)) { + return 0; + } else { + debug("%s: %s line %d exceeds size limit", __func__, + filename, lineno); + /* discard remainder of line */ + while(fgetc(f) != '\n' && !feof(f)) + ; /* nothing */ + } + } + return -1; +} diff --git a/misc.h b/misc.h index 0290a2d6..4aab2ca0 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.18 2004/10/29 22:53:56 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.19 2004/12/06 11:41:03 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -47,3 +47,4 @@ char *tilde_expand_filename(const char *, uid_t); 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, int *); diff --git a/ssh.h b/ssh.h index a3b2ebbb..07592415 100644 --- a/ssh.h +++ b/ssh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.h,v 1.75 2003/12/02 17:01:15 markus Exp $ */ +/* $OpenBSD: ssh.h,v 1.76 2004/12/06 11:41:03 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -39,6 +39,13 @@ */ #define SSH_MAX_IDENTITY_FILES 100 +/* + * Maximum length of lines in authorized_keys file. + * Current value permits 16kbit RSA and RSA1 keys and 8kbit DSA keys, with + * some room for options and comments. + */ +#define SSH_MAX_PUBKEY_BYTES 8192 + /* * Major protocol version. Different version indicates major incompatibility * that prevents communication. diff --git a/sshd.8 b/sshd.8 index 83d0f48d..2ac7b727 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.202 2004/08/26 16:00:55 markus Exp $ +.\" $OpenBSD: sshd.8,v 1.203 2004/12/06 11:41:03 dtucker Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -420,7 +420,9 @@ or .Dq ssh-rsa . .Pp Note that lines in this file are usually several hundred bytes long -(because of the size of the public key encoding). +(because of the size of the public key encoding) up to a limit of +8 kilobytes, which permits DSA keys up to 8 kilobits and RSA +keys up to 16 kilobits. You don't want to type them in; instead, copy the .Pa identity.pub , .Pa id_dsa.pub -- 2.45.1