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}; |