summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 14:23:51 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 16:48:11 +0100
commit0f0841b2d28b7463267d4d91577e72e3340a1d3a (patch)
treeba55fcd2b6e2cc22b30f5afb561dbb3da4c8b6c7 /authfile.c
parentf2a5f5dae656759efb0b76c3d94890b65c197a02 (diff)
parent8698446b972003b63dfe5dcbdb86acfe986afb85 (diff)
New upstream release (6.8p1).
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c125
1 files changed, 74 insertions, 51 deletions
diff --git a/authfile.c b/authfile.c
index e93d86738..3a81786c7 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.111 2015/02/23 16:55:51 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 *
@@ -27,7 +27,6 @@
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/stat.h> 29#include <sys/stat.h>
30#include <sys/param.h>
31#include <sys/uio.h> 30#include <sys/uio.h>
32 31
33#include <errno.h> 32#include <errno.h>
@@ -37,6 +36,7 @@
37#include <stdlib.h> 36#include <stdlib.h>
38#include <string.h> 37#include <string.h>
39#include <unistd.h> 38#include <unistd.h>
39#include <limits.h>
40 40
41#include "cipher.h" 41#include "cipher.h"
42#include "key.h" 42#include "key.h"
@@ -48,6 +48,7 @@
48#include "atomicio.h" 48#include "atomicio.h"
49#include "sshbuf.h" 49#include "sshbuf.h"
50#include "ssherr.h" 50#include "ssherr.h"
51#include "krl.h"
51 52
52#define MAX_KEY_FILE_SIZE (1024 * 1024) 53#define MAX_KEY_FILE_SIZE (1024 * 1024)
53 54
@@ -94,7 +95,7 @@ sshkey_save_private(struct sshkey *key, const char *filename,
94 95
95/* Load a key from a fd into a buffer */ 96/* Load a key from a fd into a buffer */
96int 97int
97sshkey_load_file(int fd, const char *filename, struct sshbuf *blob) 98sshkey_load_file(int fd, struct sshbuf *blob)
98{ 99{
99 u_char buf[1024]; 100 u_char buf[1024];
100 size_t len; 101 size_t len;
@@ -141,8 +142,7 @@ sshkey_load_file(int fd, const char *filename, struct sshbuf *blob)
141 * otherwise. 142 * otherwise.
142 */ 143 */
143static int 144static int
144sshkey_load_public_rsa1(int fd, const char *filename, 145sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)
145 struct sshkey **keyp, char **commentp)
146{ 146{
147 struct sshbuf *b = NULL; 147 struct sshbuf *b = NULL;
148 int r; 148 int r;
@@ -153,7 +153,7 @@ sshkey_load_public_rsa1(int fd, const char *filename,
153 153
154 if ((b = sshbuf_new()) == NULL) 154 if ((b = sshbuf_new()) == NULL)
155 return SSH_ERR_ALLOC_FAIL; 155 return SSH_ERR_ALLOC_FAIL;
156 if ((r = sshkey_load_file(fd, filename, b)) != 0) 156 if ((r = sshkey_load_file(fd, b)) != 0)
157 goto out; 157 goto out;
158 if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0) 158 if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
159 goto out; 159 goto out;
@@ -164,33 +164,6 @@ sshkey_load_public_rsa1(int fd, const char *filename,
164} 164}
165#endif /* WITH_SSH1 */ 165#endif /* WITH_SSH1 */
166 166
167#ifdef WITH_OPENSSL
168/* XXX Deprecate? */
169int
170sshkey_load_private_pem(int fd, int type, const char *passphrase,
171 struct sshkey **keyp, char **commentp)
172{
173 struct sshbuf *buffer = NULL;
174 int r;
175
176 *keyp = NULL;
177 if (commentp != NULL)
178 *commentp = NULL;
179
180 if ((buffer = sshbuf_new()) == NULL)
181 return SSH_ERR_ALLOC_FAIL;
182 if ((r = sshkey_load_file(fd, NULL, buffer)) != 0)
183 goto out;
184 if ((r = sshkey_parse_private_pem_fileblob(buffer, type, passphrase,
185 keyp, commentp)) != 0)
186 goto out;
187 r = 0;
188 out:
189 sshbuf_free(buffer);
190 return r;
191}
192#endif /* WITH_OPENSSL */
193
194/* XXX remove error() calls from here? */ 167/* XXX remove error() calls from here? */
195int 168int
196sshkey_perm_ok(int fd, const char *filename) 169sshkey_perm_ok(int fd, const char *filename)
@@ -226,7 +199,6 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase,
226 struct sshkey **keyp, char **commentp, int *perm_ok) 199 struct sshkey **keyp, char **commentp, int *perm_ok)
227{ 200{
228 int fd, r; 201 int fd, r;
229 struct sshbuf *buffer = NULL;
230 202
231 *keyp = NULL; 203 *keyp = NULL;
232 if (commentp != NULL) 204 if (commentp != NULL)
@@ -246,18 +218,31 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase,
246 if (perm_ok != NULL) 218 if (perm_ok != NULL)
247 *perm_ok = 1; 219 *perm_ok = 1;
248 220
221 r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp);
222 out:
223 close(fd);
224 return r;
225}
226
227int
228sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
229 struct sshkey **keyp, char **commentp)
230{
231 struct sshbuf *buffer = NULL;
232 int r;
233
249 if ((buffer = sshbuf_new()) == NULL) { 234 if ((buffer = sshbuf_new()) == NULL) {
250 r = SSH_ERR_ALLOC_FAIL; 235 r = SSH_ERR_ALLOC_FAIL;
251 goto out; 236 goto out;
252 } 237 }
253 if ((r = sshkey_load_file(fd, filename, buffer)) != 0) 238 if ((r = sshkey_load_file(fd, buffer)) != 0 ||
254 goto out; 239 (r = sshkey_parse_private_fileblob_type(buffer, type,
255 if ((r = sshkey_parse_private_fileblob_type(buffer, type, passphrase, 240 passphrase, keyp, commentp)) != 0)
256 keyp, commentp)) != 0)
257 goto out; 241 goto out;
242
243 /* success */
258 r = 0; 244 r = 0;
259 out: 245 out:
260 close(fd);
261 if (buffer != NULL) 246 if (buffer != NULL)
262 sshbuf_free(buffer); 247 sshbuf_free(buffer);
263 return r; 248 return r;
@@ -286,7 +271,7 @@ sshkey_load_private(const char *filename, const char *passphrase,
286 r = SSH_ERR_ALLOC_FAIL; 271 r = SSH_ERR_ALLOC_FAIL;
287 goto out; 272 goto out;
288 } 273 }
289 if ((r = sshkey_load_file(fd, filename, buffer)) != 0 || 274 if ((r = sshkey_load_file(fd, buffer)) != 0 ||
290 (r = sshkey_parse_private_fileblob(buffer, passphrase, filename, 275 (r = sshkey_parse_private_fileblob(buffer, passphrase, filename,
291 keyp, commentp)) != 0) 276 keyp, commentp)) != 0)
292 goto out; 277 goto out;
@@ -350,7 +335,7 @@ int
350sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) 335sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
351{ 336{
352 struct sshkey *pub = NULL; 337 struct sshkey *pub = NULL;
353 char file[MAXPATHLEN]; 338 char file[PATH_MAX];
354 int r, fd; 339 int r, fd;
355 340
356 if (keyp != NULL) 341 if (keyp != NULL)
@@ -358,11 +343,13 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
358 if (commentp != NULL) 343 if (commentp != NULL)
359 *commentp = NULL; 344 *commentp = NULL;
360 345
346 /* XXX should load file once and attempt to parse each format */
347
361 if ((fd = open(filename, O_RDONLY)) < 0) 348 if ((fd = open(filename, O_RDONLY)) < 0)
362 goto skip; 349 goto skip;
363#ifdef WITH_SSH1 350#ifdef WITH_SSH1
364 /* try rsa1 private key */ 351 /* try rsa1 private key */
365 r = sshkey_load_public_rsa1(fd, filename, keyp, commentp); 352 r = sshkey_load_public_rsa1(fd, keyp, commentp);
366 close(fd); 353 close(fd);
367 switch (r) { 354 switch (r) {
368 case SSH_ERR_INTERNAL_ERROR: 355 case SSH_ERR_INTERNAL_ERROR:
@@ -409,6 +396,7 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
409 return 0; 396 return 0;
410 } 397 }
411 sshkey_free(pub); 398 sshkey_free(pub);
399
412 return r; 400 return r;
413} 401}
414 402
@@ -494,11 +482,14 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
494/* 482/*
495 * Returns success if the specified "key" is listed in the file "filename", 483 * Returns success if the specified "key" is listed in the file "filename",
496 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. 484 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
497 * If strict_type is set then the key type must match exactly, 485 * If "strict_type" is set then the key type must match exactly,
498 * otherwise a comparison that ignores certficiate data is performed. 486 * otherwise a comparison that ignores certficiate data is performed.
487 * If "check_ca" is set and "key" is a certificate, then its CA key is
488 * also checked and sshkey_in_file() will return success if either is found.
499 */ 489 */
500int 490int
501sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) 491sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
492 int check_ca)
502{ 493{
503 FILE *f; 494 FILE *f;
504 char line[SSH_MAX_PUBKEY_BYTES]; 495 char line[SSH_MAX_PUBKEY_BYTES];
@@ -509,12 +500,8 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
509 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = 500 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
510 strict_type ? sshkey_equal : sshkey_equal_public; 501 strict_type ? sshkey_equal : sshkey_equal_public;
511 502
512 if ((f = fopen(filename, "r")) == NULL) { 503 if ((f = fopen(filename, "r")) == NULL)
513 if (errno == ENOENT) 504 return SSH_ERR_SYSTEM_ERROR;
514 return SSH_ERR_KEY_NOT_FOUND;
515 else
516 return SSH_ERR_SYSTEM_ERROR;
517 }
518 505
519 while (read_keyfile_line(f, filename, line, sizeof(line), 506 while (read_keyfile_line(f, filename, line, sizeof(line),
520 &linenum) != -1) { 507 &linenum) != -1) {
@@ -538,7 +525,9 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
538 } 525 }
539 if ((r = sshkey_read(pub, &cp)) != 0) 526 if ((r = sshkey_read(pub, &cp)) != 0)
540 goto out; 527 goto out;
541 if (sshkey_compare(key, pub)) { 528 if (sshkey_compare(key, pub) ||
529 (check_ca && sshkey_is_cert(key) &&
530 sshkey_compare(key->cert->signature_key, pub))) {
542 r = 0; 531 r = 0;
543 goto out; 532 goto out;
544 } 533 }
@@ -553,3 +542,37 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
553 return r; 542 return r;
554} 543}
555 544
545/*
546 * Checks whether the specified key is revoked, returning 0 if not,
547 * SSH_ERR_KEY_REVOKED if it is or another error code if something
548 * unexpected happened.
549 * This will check both the key and, if it is a certificate, its CA key too.
550 * "revoked_keys_file" may be a KRL or a one-per-line list of public keys.
551 */
552int
553sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
554{
555 int r;
556
557 r = ssh_krl_file_contains_key(revoked_keys_file, key);
558 /* If this was not a KRL to begin with then continue below */
559 if (r != SSH_ERR_KRL_BAD_MAGIC)
560 return r;
561
562 /*
563 * If the file is not a KRL or we can't handle KRLs then attempt to
564 * parse the file as a flat list of keys.
565 */
566 switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {
567 case 0:
568 /* Key found => revoked */
569 return SSH_ERR_KEY_REVOKED;
570 case SSH_ERR_KEY_NOT_FOUND:
571 /* Key not found => not revoked */
572 return 0;
573 default:
574 /* Some other error occurred */
575 return r;
576 }
577}
578