1 diff -aur old/authfile.c new/authfile.c
2 --- old/authfile.c 2011-06-12 02:21:52.262338254 +0200
3 +++ new/authfile.c 2011-06-12 02:13:43.051467269 +0200
5 -/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */
6 +/* $OpenBSD: authfile.c,v 1.95 2011/05/29 11:42:08 djm Exp $ */
8 * Author: Tatu Ylonen <ylo@cs.hut.fi>
9 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
14 +#define MAX_KEY_FILE_SIZE (1024 * 1024)
16 /* Version identification string for SSH v1 identity files. */
17 static const char authfile_id_string[] =
18 "SSH PRIVATE KEY FILE FORMAT 1.1\n";
23 -/* Load the contents of a key file into a buffer */
25 +/* Load a key from a fd into a buffer */
27 key_load_file(int fd, const char *filename, Buffer *blob)
34 if (fstat(fd, &st) < 0) {
36 filename == NULL ? "" : filename,
37 filename == NULL ? "" : " ",
42 - if (st.st_size > 1*1024*1024) {
43 + if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
44 + st.st_size > MAX_KEY_FILE_SIZE) {
46 error("%s: key file %.200s%stoo large", __func__,
47 filename == NULL ? "" : filename,
48 filename == NULL ? "" : " ");
52 - len = (size_t)st.st_size; /* truncated */
55 - cp = buffer_append_space(blob, len);
57 - if (atomicio(read, fd, cp, len) != len) {
58 - debug("%s: read from key file %.200s%sfailed: %.100s", __func__,
59 - filename == NULL ? "" : filename,
60 - filename == NULL ? "" : " ",
63 + if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
66 + debug("%s: read from key file %.200s%sfailed: %.100s",
67 + __func__, filename == NULL ? "" : filename,
68 + filename == NULL ? "" : " ", strerror(errno));
70 + bzero(buf, sizeof(buf));
73 + buffer_append(blob, buf, len);
74 + if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
76 + bzero(buf, sizeof(buf));
80 + bzero(buf, sizeof(buf));
81 + if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
82 + st.st_size != buffer_len(blob)) {
83 + debug("%s: key file %.200s%schanged size while reading",
84 + __func__, filename == NULL ? "" : filename,
85 + filename == NULL ? "" : " ");
95 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
96 error("Permissions 0%3.3o for '%s' are too open.",
97 (u_int)st.st_mode & 0777, filename);
98 - error("It is recommended that your private key files are NOT accessible by others.");
99 + error("It is required that your private key files are NOT accessible by others.");
100 error("This private key will be ignored.");
105 return key_parse_private_pem(blob, type, passphrase, commentp);
107 + error("%s: cannot parse key type %d", __func__, type);
111 @@ -670,11 +688,38 @@
115 +key_parse_private(Buffer *buffer, const char *filename,
116 + const char *passphrase, char **commentp)
121 + buffer_init(&pubcopy);
122 + buffer_append(&pubcopy, buffer_ptr(buffer), buffer_len(buffer));
123 + /* it's a SSH v1 key if the public key part is readable */
124 + pub = key_parse_public_rsa1(&pubcopy, commentp);
125 + buffer_free(&pubcopy);
127 + prv = key_parse_private_type(buffer, KEY_UNSPEC,
129 + /* use the filename as a comment for PEM */
130 + if (commentp && prv)
131 + *commentp = xstrdup(filename);
134 + /* key_parse_public_rsa1() has already loaded the comment */
135 + prv = key_parse_private_type(buffer, KEY_RSA1, passphrase,
142 key_load_private(const char *filename, const char *passphrase,
146 - Buffer buffer, pubcopy;
151 fd = open(filename, O_RDONLY);
156 - buffer_init(&pubcopy);
157 - buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
158 - /* it's a SSH v1 key if the public key part is readable */
159 - pub = key_parse_public_rsa1(&pubcopy, commentp);
160 - buffer_free(&pubcopy);
162 - prv = key_parse_private_type(&buffer, KEY_UNSPEC,
164 - /* use the filename as a comment for PEM */
165 - if (commentp && prv)
166 - *commentp = xstrdup(filename);
169 - /* key_parse_public_rsa1() has already loaded the comment */
170 - prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
173 + prv = key_parse_private(&buffer, filename, passphrase, commentp);
174 buffer_free(&buffer);
177 @@ -737,13 +766,19 @@
181 + /* Abort loading if this looks like a private key */
182 + if (strncmp(cp, "-----BEGIN", 10) == 0)
184 /* Skip leading whitespace. */
185 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
188 if (key_read(k, &cp) == 1) {
190 - *commentp=xstrdup(filename);
191 + cp[strcspn(cp, "\r\n")] = '\0';
193 + *commentp = xstrdup(*cp ?