Deleted Added
full compact
auth2-pubkey.c (247485) auth2-pubkey.c (251135)
1/* $OpenBSD: auth2-pubkey.c,v 1.30 2011/09/25 05:44:47 djm Exp $ */
1/* $OpenBSD: auth2-pubkey.c,v 1.34 2013/02/14 21:35:59 djm Exp $ */
2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 12 unchanged lines hidden (view full) ---

22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "includes.h"
27
28#include <sys/types.h>
29#include <sys/stat.h>
2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 12 unchanged lines hidden (view full) ---

22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "includes.h"
27
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/wait.h>
30
31
32#include <errno.h>
31#include <fcntl.h>
33#include <fcntl.h>
34#ifdef HAVE_PATHS_H
35# include <paths.h>
36#endif
32#include <pwd.h>
37#include <pwd.h>
38#include <signal.h>
33#include <stdio.h>
34#include <stdarg.h>
35#include <string.h>
36#include <time.h>
37#include <unistd.h>
38
39#include "xmalloc.h"
40#include "ssh.h"

--- 194 unchanged lines hidden (view full) ---

235 ;
236 line_opts = cp;
237 cp = ep;
238 }
239 for (i = 0; i < cert->nprincipals; i++) {
240 if (strcmp(cp, cert->principals[i]) == 0) {
241 debug3("matched principal \"%.100s\" "
242 "from file \"%s\" on line %lu",
39#include <stdio.h>
40#include <stdarg.h>
41#include <string.h>
42#include <time.h>
43#include <unistd.h>
44
45#include "xmalloc.h"
46#include "ssh.h"

--- 194 unchanged lines hidden (view full) ---

241 ;
242 line_opts = cp;
243 cp = ep;
244 }
245 for (i = 0; i < cert->nprincipals; i++) {
246 if (strcmp(cp, cert->principals[i]) == 0) {
247 debug3("matched principal \"%.100s\" "
248 "from file \"%s\" on line %lu",
243 cert->principals[i], file, linenum);
249 cert->principals[i], file, linenum);
244 if (auth_parse_options(pw, line_opts,
245 file, linenum) != 1)
246 continue;
247 fclose(f);
248 restore_uid();
249 return 1;
250 }
251 }
252 }
253 fclose(f);
254 restore_uid();
255 return 0;
250 if (auth_parse_options(pw, line_opts,
251 file, linenum) != 1)
252 continue;
253 fclose(f);
254 restore_uid();
255 return 1;
256 }
257 }
258 }
259 fclose(f);
260 restore_uid();
261 return 0;
256}
262}
257
263
258/* return 1 if user allows given key */
264/*
265 * Checks whether key is allowed in authorized_keys-format file,
266 * returns 1 if the key is allowed or 0 otherwise.
267 */
259static int
268static int
260user_key_allowed2(struct passwd *pw, Key *key, char *file)
269check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
261{
262 char line[SSH_MAX_PUBKEY_BYTES];
263 const char *reason;
264 int found_key = 0;
270{
271 char line[SSH_MAX_PUBKEY_BYTES];
272 const char *reason;
273 int found_key = 0;
265 FILE *f;
266 u_long linenum = 0;
267 Key *found;
268 char *fp;
269
274 u_long linenum = 0;
275 Key *found;
276 char *fp;
277
270 /* Temporarily use the user's uid. */
271 temporarily_use_uid(pw);
272
273 debug("trying public key file %s", file);
274 f = auth_openkeyfile(file, pw, options.strict_modes);
275
276 if (!f) {
277 restore_uid();
278 return 0;
279 }
280
281 found_key = 0;
282 found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
283
284 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
285 char *cp, *key_options = NULL;
286
287 auth_clear_options();
288

--- 76 unchanged lines hidden (view full) ---

365 file, linenum);
366 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
367 verbose("Found matching %s key: %s",
368 key_type(found), fp);
369 xfree(fp);
370 break;
371 }
372 }
278 found_key = 0;
279 found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
280
281 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
282 char *cp, *key_options = NULL;
283
284 auth_clear_options();
285

--- 76 unchanged lines hidden (view full) ---

362 file, linenum);
363 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
364 verbose("Found matching %s key: %s",
365 key_type(found), fp);
366 xfree(fp);
367 break;
368 }
369 }
373 restore_uid();
374 fclose(f);
375 key_free(found);
376 if (!found_key)
377 debug2("key not found");
378 return found_key;
379}
380
381/* Authenticate a certificate key against TrustedUserCAKeys */
382static int

--- 45 unchanged lines hidden (view full) ---

428 out:
429 if (principals_file != NULL)
430 xfree(principals_file);
431 if (ca_fp != NULL)
432 xfree(ca_fp);
433 return ret;
434}
435
370 key_free(found);
371 if (!found_key)
372 debug2("key not found");
373 return found_key;
374}
375
376/* Authenticate a certificate key against TrustedUserCAKeys */
377static int

--- 45 unchanged lines hidden (view full) ---

423 out:
424 if (principals_file != NULL)
425 xfree(principals_file);
426 if (ca_fp != NULL)
427 xfree(ca_fp);
428 return ret;
429}
430
436/* check whether given key is in .ssh/authorized_keys* */
431/*
432 * Checks whether key is allowed in file.
433 * returns 1 if the key is allowed or 0 otherwise.
434 */
435static int
436user_key_allowed2(struct passwd *pw, Key *key, char *file)
437{
438 FILE *f;
439 int found_key = 0;
440
441 /* Temporarily use the user's uid. */
442 temporarily_use_uid(pw);
443
444 debug("trying public key file %s", file);
445 if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) {
446 found_key = check_authkeys_file(f, file, key, pw);
447 fclose(f);
448 }
449
450 restore_uid();
451 return found_key;
452}
453
454/*
455 * Checks whether key is allowed in output of command.
456 * returns 1 if the key is allowed or 0 otherwise.
457 */
458static int
459user_key_command_allowed2(struct passwd *user_pw, Key *key)
460{
461 FILE *f;
462 int ok, found_key = 0;
463 struct passwd *pw;
464 struct stat st;
465 int status, devnull, p[2], i;
466 pid_t pid;
467 char *username, errmsg[512];
468
469 if (options.authorized_keys_command == NULL ||
470 options.authorized_keys_command[0] != '/')
471 return 0;
472
473 if (options.authorized_keys_command_user == NULL) {
474 error("No user for AuthorizedKeysCommand specified, skipping");
475 return 0;
476 }
477
478 username = percent_expand(options.authorized_keys_command_user,
479 "u", user_pw->pw_name, (char *)NULL);
480 pw = getpwnam(username);
481 if (pw == NULL) {
482 error("AuthorizedKeysCommandUser \"%s\" not found: %s",
483 username, strerror(errno));
484 free(username);
485 return 0;
486 }
487 free(username);
488
489 temporarily_use_uid(pw);
490
491 if (stat(options.authorized_keys_command, &st) < 0) {
492 error("Could not stat AuthorizedKeysCommand \"%s\": %s",
493 options.authorized_keys_command, strerror(errno));
494 goto out;
495 }
496 if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
497 errmsg, sizeof(errmsg)) != 0) {
498 error("Unsafe AuthorizedKeysCommand: %s", errmsg);
499 goto out;
500 }
501
502 if (pipe(p) != 0) {
503 error("%s: pipe: %s", __func__, strerror(errno));
504 goto out;
505 }
506
507 debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"",
508 options.authorized_keys_command, user_pw->pw_name, pw->pw_name);
509
510 /*
511 * Don't want to call this in the child, where it can fatal() and
512 * run cleanup_exit() code.
513 */
514 restore_uid();
515
516 switch ((pid = fork())) {
517 case -1: /* error */
518 error("%s: fork: %s", __func__, strerror(errno));
519 close(p[0]);
520 close(p[1]);
521 return 0;
522 case 0: /* child */
523 for (i = 0; i < NSIG; i++)
524 signal(i, SIG_DFL);
525
526 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
527 error("%s: open %s: %s", __func__, _PATH_DEVNULL,
528 strerror(errno));
529 _exit(1);
530 }
531 /* Keep stderr around a while longer to catch errors */
532 if (dup2(devnull, STDIN_FILENO) == -1 ||
533 dup2(p[1], STDOUT_FILENO) == -1) {
534 error("%s: dup2: %s", __func__, strerror(errno));
535 _exit(1);
536 }
537 closefrom(STDERR_FILENO + 1);
538
539 /* Don't use permanently_set_uid() here to avoid fatal() */
540 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
541 error("setresgid %u: %s", (u_int)pw->pw_gid,
542 strerror(errno));
543 _exit(1);
544 }
545 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
546 error("setresuid %u: %s", (u_int)pw->pw_uid,
547 strerror(errno));
548 _exit(1);
549 }
550 /* stdin is pointed to /dev/null at this point */
551 if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
552 error("%s: dup2: %s", __func__, strerror(errno));
553 _exit(1);
554 }
555
556 execl(options.authorized_keys_command,
557 options.authorized_keys_command, user_pw->pw_name, NULL);
558
559 error("AuthorizedKeysCommand %s exec failed: %s",
560 options.authorized_keys_command, strerror(errno));
561 _exit(127);
562 default: /* parent */
563 break;
564 }
565
566 temporarily_use_uid(pw);
567
568 close(p[1]);
569 if ((f = fdopen(p[0], "r")) == NULL) {
570 error("%s: fdopen: %s", __func__, strerror(errno));
571 close(p[0]);
572 /* Don't leave zombie child */
573 kill(pid, SIGTERM);
574 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
575 ;
576 goto out;
577 }
578 ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
579 fclose(f);
580
581 while (waitpid(pid, &status, 0) == -1) {
582 if (errno != EINTR) {
583 error("%s: waitpid: %s", __func__, strerror(errno));
584 goto out;
585 }
586 }
587 if (WIFSIGNALED(status)) {
588 error("AuthorizedKeysCommand %s exited on signal %d",
589 options.authorized_keys_command, WTERMSIG(status));
590 goto out;
591 } else if (WEXITSTATUS(status) != 0) {
592 error("AuthorizedKeysCommand %s returned status %d",
593 options.authorized_keys_command, WEXITSTATUS(status));
594 goto out;
595 }
596 found_key = ok;
597 out:
598 restore_uid();
599 return found_key;
600}
601
602/*
603 * Check whether key authenticates and authorises the user.
604 */
437int
438user_key_allowed(struct passwd *pw, Key *key)
439{
440 u_int success, i;
441 char *file;
442
443 if (auth_key_is_revoked(key))
444 return 0;
445 if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
446 return 0;
447
448 success = user_cert_trusted_ca(pw, key);
449 if (success)
450 return success;
451
605int
606user_key_allowed(struct passwd *pw, Key *key)
607{
608 u_int success, i;
609 char *file;
610
611 if (auth_key_is_revoked(key))
612 return 0;
613 if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
614 return 0;
615
616 success = user_cert_trusted_ca(pw, key);
617 if (success)
618 return success;
619
620 success = user_key_command_allowed2(pw, key);
621 if (success > 0)
622 return success;
623
452 for (i = 0; !success && i < options.num_authkeys_files; i++) {
624 for (i = 0; !success && i < options.num_authkeys_files; i++) {
625
626 if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
627 continue;
453 file = expand_authorized_keys(
454 options.authorized_keys_files[i], pw);
628 file = expand_authorized_keys(
629 options.authorized_keys_files[i], pw);
630
455 success = user_key_allowed2(pw, key, file);
456 xfree(file);
457 }
458
459 return success;
460}
461
462Authmethod method_pubkey = {
463 "publickey",
464 userauth_pubkey,
465 &options.pubkey_authentication
466};
631 success = user_key_allowed2(pw, key, file);
632 xfree(file);
633 }
634
635 return success;
636}
637
638Authmethod method_pubkey = {
639 "publickey",
640 userauth_pubkey,
641 &options.pubkey_authentication
642};