diff options
author | Colin Watson <cjwatson@debian.org> | 2017-10-04 11:23:58 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-10-05 23:58:12 +0100 |
commit | 0556ea972b15607b7e13ff31bc05840881c91dd3 (patch) | |
tree | d6b8d48062d0278b5ae0eeff42d0e9afa9f26860 /authfile.c | |
parent | db2122d97eb1ecdd8d99b7bf79b0dd2b5addfd92 (diff) | |
parent | 801a62eedaaf47b20dbf4b426dc3e084bf0c8d49 (diff) |
New upstream release (7.6p1)
Diffstat (limited to 'authfile.c')
-rw-r--r-- | authfile.c | 113 |
1 files changed, 22 insertions, 91 deletions
diff --git a/authfile.c b/authfile.c index 7411b68f6..d09b700d2 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */ | 1 | /* $OpenBSD: authfile.c,v 1.127 2017/07/01 13:50:45 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -42,7 +42,6 @@ | |||
42 | #include "ssh.h" | 42 | #include "ssh.h" |
43 | #include "log.h" | 43 | #include "log.h" |
44 | #include "authfile.h" | 44 | #include "authfile.h" |
45 | #include "rsa.h" | ||
46 | #include "misc.h" | 45 | #include "misc.h" |
47 | #include "atomicio.h" | 46 | #include "atomicio.h" |
48 | #include "sshkey.h" | 47 | #include "sshkey.h" |
@@ -100,25 +99,13 @@ sshkey_load_file(int fd, struct sshbuf *blob) | |||
100 | u_char buf[1024]; | 99 | u_char buf[1024]; |
101 | size_t len; | 100 | size_t len; |
102 | struct stat st; | 101 | struct stat st; |
103 | int r, dontmax = 0; | 102 | int r; |
104 | 103 | ||
105 | if (fstat(fd, &st) < 0) | 104 | if (fstat(fd, &st) < 0) |
106 | return SSH_ERR_SYSTEM_ERROR; | 105 | return SSH_ERR_SYSTEM_ERROR; |
107 | if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && | 106 | if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && |
108 | st.st_size > MAX_KEY_FILE_SIZE) | 107 | st.st_size > MAX_KEY_FILE_SIZE) |
109 | return SSH_ERR_INVALID_FORMAT; | 108 | return SSH_ERR_INVALID_FORMAT; |
110 | /* | ||
111 | * Pre-allocate the buffer used for the key contents and clamp its | ||
112 | * maximum size. This ensures that key contents are never leaked via | ||
113 | * implicit realloc() in the sshbuf code. | ||
114 | */ | ||
115 | if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) { | ||
116 | st.st_size = 64*1024; /* 64k should be enough for anyone :) */ | ||
117 | dontmax = 1; | ||
118 | } | ||
119 | if ((r = sshbuf_allocate(blob, st.st_size)) != 0 || | ||
120 | (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0)) | ||
121 | return r; | ||
122 | for (;;) { | 109 | for (;;) { |
123 | if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { | 110 | if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { |
124 | if (errno == EPIPE) | 111 | if (errno == EPIPE) |
@@ -147,35 +134,6 @@ sshkey_load_file(int fd, struct sshbuf *blob) | |||
147 | return r; | 134 | return r; |
148 | } | 135 | } |
149 | 136 | ||
150 | #ifdef WITH_SSH1 | ||
151 | /* | ||
152 | * Loads the public part of the ssh v1 key file. Returns NULL if an error was | ||
153 | * encountered (the file does not exist or is not readable), and the key | ||
154 | * otherwise. | ||
155 | */ | ||
156 | static int | ||
157 | sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp) | ||
158 | { | ||
159 | struct sshbuf *b = NULL; | ||
160 | int r; | ||
161 | |||
162 | if (keyp != NULL) | ||
163 | *keyp = NULL; | ||
164 | if (commentp != NULL) | ||
165 | *commentp = NULL; | ||
166 | |||
167 | if ((b = sshbuf_new()) == NULL) | ||
168 | return SSH_ERR_ALLOC_FAIL; | ||
169 | if ((r = sshkey_load_file(fd, b)) != 0) | ||
170 | goto out; | ||
171 | if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0) | ||
172 | goto out; | ||
173 | r = 0; | ||
174 | out: | ||
175 | sshbuf_free(b); | ||
176 | return r; | ||
177 | } | ||
178 | #endif /* WITH_SSH1 */ | ||
179 | 137 | ||
180 | /* XXX remove error() calls from here? */ | 138 | /* XXX remove error() calls from here? */ |
181 | int | 139 | int |
@@ -345,75 +303,48 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp) | |||
345 | return SSH_ERR_INVALID_FORMAT; | 303 | return SSH_ERR_INVALID_FORMAT; |
346 | } | 304 | } |
347 | 305 | ||
348 | /* load public key from ssh v1 private or any pubkey file */ | 306 | /* load public key from any pubkey file */ |
349 | int | 307 | int |
350 | sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) | 308 | sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) |
351 | { | 309 | { |
352 | struct sshkey *pub = NULL; | 310 | struct sshkey *pub = NULL; |
353 | char file[PATH_MAX]; | 311 | char *file = NULL; |
354 | int r, fd; | 312 | int r; |
355 | 313 | ||
356 | if (keyp != NULL) | 314 | if (keyp != NULL) |
357 | *keyp = NULL; | 315 | *keyp = NULL; |
358 | if (commentp != NULL) | 316 | if (commentp != NULL) |
359 | *commentp = NULL; | 317 | *commentp = NULL; |
360 | 318 | ||
361 | /* XXX should load file once and attempt to parse each format */ | ||
362 | |||
363 | if ((fd = open(filename, O_RDONLY)) < 0) | ||
364 | goto skip; | ||
365 | #ifdef WITH_SSH1 | ||
366 | /* try rsa1 private key */ | ||
367 | r = sshkey_load_public_rsa1(fd, keyp, commentp); | ||
368 | close(fd); | ||
369 | switch (r) { | ||
370 | case SSH_ERR_INTERNAL_ERROR: | ||
371 | case SSH_ERR_ALLOC_FAIL: | ||
372 | case SSH_ERR_INVALID_ARGUMENT: | ||
373 | case SSH_ERR_SYSTEM_ERROR: | ||
374 | case 0: | ||
375 | return r; | ||
376 | } | ||
377 | #else /* WITH_SSH1 */ | ||
378 | close(fd); | ||
379 | #endif /* WITH_SSH1 */ | ||
380 | |||
381 | /* try ssh2 public key */ | ||
382 | if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) | 319 | if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) |
383 | return SSH_ERR_ALLOC_FAIL; | 320 | return SSH_ERR_ALLOC_FAIL; |
384 | if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) { | 321 | if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) { |
385 | if (keyp != NULL) | 322 | if (keyp != NULL) { |
386 | *keyp = pub; | ||
387 | return 0; | ||
388 | } | ||
389 | sshkey_free(pub); | ||
390 | |||
391 | #ifdef WITH_SSH1 | ||
392 | /* try rsa1 public key */ | ||
393 | if ((pub = sshkey_new(KEY_RSA1)) == NULL) | ||
394 | return SSH_ERR_ALLOC_FAIL; | ||
395 | if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) { | ||
396 | if (keyp != NULL) | ||
397 | *keyp = pub; | 323 | *keyp = pub; |
398 | return 0; | 324 | pub = NULL; |
325 | } | ||
326 | r = 0; | ||
327 | goto out; | ||
399 | } | 328 | } |
400 | sshkey_free(pub); | 329 | sshkey_free(pub); |
401 | #endif /* WITH_SSH1 */ | ||
402 | 330 | ||
403 | skip: | ||
404 | /* try .pub suffix */ | 331 | /* try .pub suffix */ |
405 | if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) | 332 | if (asprintf(&file, "%s.pub", filename) == -1) |
406 | return SSH_ERR_ALLOC_FAIL; | 333 | return SSH_ERR_ALLOC_FAIL; |
407 | r = SSH_ERR_ALLOC_FAIL; /* in case strlcpy or strlcat fail */ | 334 | if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) { |
408 | if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && | 335 | r = SSH_ERR_ALLOC_FAIL; |
409 | (strlcat(file, ".pub", sizeof file) < sizeof(file)) && | 336 | goto out; |
410 | (r = sshkey_try_load_public(pub, file, commentp)) == 0) { | 337 | } |
411 | if (keyp != NULL) | 338 | if ((r = sshkey_try_load_public(pub, file, commentp)) == 0) { |
339 | if (keyp != NULL) { | ||
412 | *keyp = pub; | 340 | *keyp = pub; |
413 | return 0; | 341 | pub = NULL; |
342 | } | ||
343 | r = 0; | ||
414 | } | 344 | } |
345 | out: | ||
346 | free(file); | ||
415 | sshkey_free(pub); | 347 | sshkey_free(pub); |
416 | |||
417 | return r; | 348 | return r; |
418 | } | 349 | } |
419 | 350 | ||