summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c113
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 */
156static int
157sshkey_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? */
181int 139int
@@ -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 */
349int 307int
350sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) 308sshkey_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