Deleted Added
full compact
auth.c (247485) auth.c (251135)
1/* $OpenBSD: auth.c,v 1.96 2012/05/13 01:42:32 dtucker Exp $ */
1/* $OpenBSD: auth.c,v 1.101 2013/02/06 00:22:21 dtucker 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.

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

19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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"
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.

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

19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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__RCSID("$FreeBSD: stable/9/crypto/openssh/auth.c 247485 2013-02-28 18:43:50Z des $");
27__RCSID("$FreeBSD: stable/9/crypto/openssh/auth.c 251135 2013-05-30 12:25:58Z des $");
28
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/param.h>
32
33#include <netinet/in.h>
34
35#include <errno.h>

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

67#include "misc.h"
68#include "packet.h"
69#include "loginrec.h"
70#ifdef GSSAPI
71#include "ssh-gss.h"
72#endif
73#include "authfile.h"
74#include "monitor_wrap.h"
28
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/param.h>
32
33#include <netinet/in.h>
34
35#include <errno.h>

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

67#include "misc.h"
68#include "packet.h"
69#include "loginrec.h"
70#ifdef GSSAPI
71#include "ssh-gss.h"
72#endif
73#include "authfile.h"
74#include "monitor_wrap.h"
75#include "krl.h"
75
76/* import */
77extern ServerOptions options;
78extern int use_privsep;
79extern Buffer loginmsg;
80extern struct passwd *privsep_pw;
81
82/* Debugging messages */

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

247 return 0;
248#endif
249
250 /* We found no reason not to let this user try to log on... */
251 return 1;
252}
253
254void
76
77/* import */
78extern ServerOptions options;
79extern int use_privsep;
80extern Buffer loginmsg;
81extern struct passwd *privsep_pw;
82
83/* Debugging messages */

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

248 return 0;
249#endif
250
251 /* We found no reason not to let this user try to log on... */
252 return 1;
253}
254
255void
255auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
256auth_log(Authctxt *authctxt, int authenticated, int partial,
257 const char *method, const char *submethod, const char *info)
256{
257 void (*authlog) (const char *fmt,...) = verbose;
258 char *authmsg;
259
260 if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
261 return;
262
263 /* Raise logging level */
264 if (authenticated == 1 ||
265 !authctxt->valid ||
266 authctxt->failures >= options.max_authtries / 2 ||
267 strcmp(method, "password") == 0)
268 authlog = logit;
269
270 if (authctxt->postponed)
271 authmsg = "Postponed";
258{
259 void (*authlog) (const char *fmt,...) = verbose;
260 char *authmsg;
261
262 if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
263 return;
264
265 /* Raise logging level */
266 if (authenticated == 1 ||
267 !authctxt->valid ||
268 authctxt->failures >= options.max_authtries / 2 ||
269 strcmp(method, "password") == 0)
270 authlog = logit;
271
272 if (authctxt->postponed)
273 authmsg = "Postponed";
274 else if (partial)
275 authmsg = "Partial";
272 else
273 authmsg = authenticated ? "Accepted" : "Failed";
274
276 else
277 authmsg = authenticated ? "Accepted" : "Failed";
278
275 authlog("%s %s for %s%.100s from %.200s port %d%s",
279 authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
276 authmsg,
277 method,
280 authmsg,
281 method,
282 submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
278 authctxt->valid ? "" : "invalid user ",
279 authctxt->user,
280 get_remote_ipaddr(),
281 get_remote_port(),
282 info);
283
284#ifdef CUSTOM_FAILED_LOGIN
285 if (authenticated == 0 && !authctxt->postponed &&

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

299 audit_event(audit_classify_auth(method));
300#endif
301}
302
303/*
304 * Check whether root logins are disallowed.
305 */
306int
283 authctxt->valid ? "" : "invalid user ",
284 authctxt->user,
285 get_remote_ipaddr(),
286 get_remote_port(),
287 info);
288
289#ifdef CUSTOM_FAILED_LOGIN
290 if (authenticated == 0 && !authctxt->postponed &&

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

304 audit_event(audit_classify_auth(method));
305#endif
306}
307
308/*
309 * Check whether root logins are disallowed.
310 */
311int
307auth_root_allowed(char *method)
312auth_root_allowed(const char *method)
308{
309 switch (options.permit_root_login) {
310 case PERMIT_YES:
311 return 1;
312 case PERMIT_NO_PASSWD:
313 if (strcmp(method, "password") != 0)
314 return 1;
315 break;

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

405 else
406 debug("%s: key for host %s not found", __func__, host);
407
408 free_hostkeys(hostkeys);
409
410 return host_status;
411}
412
313{
314 switch (options.permit_root_login) {
315 case PERMIT_YES:
316 return 1;
317 case PERMIT_NO_PASSWD:
318 if (strcmp(method, "password") != 0)
319 return 1;
320 break;

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

410 else
411 debug("%s: key for host %s not found", __func__, host);
412
413 free_hostkeys(hostkeys);
414
415 return host_status;
416}
417
413
414/*
418/*
415 * Check a given file for security. This is defined as all components
419 * Check a given path for security. This is defined as all components
416 * of the path to the file must be owned by either the owner of
417 * of the file or root and no directories must be group or world writable.
418 *
419 * XXX Should any specific check be done for sym links ?
420 *
420 * of the path to the file must be owned by either the owner of
421 * of the file or root and no directories must be group or world writable.
422 *
423 * XXX Should any specific check be done for sym links ?
424 *
421 * Takes an open file descriptor, the file name, a uid and and
425 * Takes a file name, its stat information (preferably from fstat() to
426 * avoid races), the uid of the expected owner, their home directory and an
422 * error buffer plus max size as arguments.
423 *
424 * Returns 0 on success and -1 on failure
425 */
427 * error buffer plus max size as arguments.
428 *
429 * Returns 0 on success and -1 on failure
430 */
426static int
427secure_filename(FILE *f, const char *file, struct passwd *pw,
428 char *err, size_t errlen)
431int
432auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
433 uid_t uid, char *err, size_t errlen)
429{
434{
430 uid_t uid = pw->pw_uid;
431 char buf[MAXPATHLEN], homedir[MAXPATHLEN];
432 char *cp;
433 int comparehome = 0;
434 struct stat st;
435
435 char buf[MAXPATHLEN], homedir[MAXPATHLEN];
436 char *cp;
437 int comparehome = 0;
438 struct stat st;
439
436 if (realpath(file, buf) == NULL) {
437 snprintf(err, errlen, "realpath %s failed: %s", file,
440 if (realpath(name, buf) == NULL) {
441 snprintf(err, errlen, "realpath %s failed: %s", name,
438 strerror(errno));
439 return -1;
440 }
442 strerror(errno));
443 return -1;
444 }
441 if (realpath(pw->pw_dir, homedir) != NULL)
445 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
442 comparehome = 1;
443
446 comparehome = 1;
447
444 /* check the open file to avoid races */
445 if (fstat(fileno(f), &st) < 0 ||
446 (st.st_uid != 0 && st.st_uid != uid) ||
447 (st.st_mode & 022) != 0) {
448 if (!S_ISREG(stp->st_mode)) {
449 snprintf(err, errlen, "%s is not a regular file", buf);
450 return -1;
451 }
452 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
453 (stp->st_mode & 022) != 0) {
448 snprintf(err, errlen, "bad ownership or modes for file %s",
449 buf);
450 return -1;
451 }
452
453 /* for each component of the canonical path, walking upwards */
454 for (;;) {
455 if ((cp = dirname(buf)) == NULL) {
456 snprintf(err, errlen, "dirname() failed");
457 return -1;
458 }
459 strlcpy(buf, cp, sizeof(buf));
460
461 if (stat(buf, &st) < 0 ||
454 snprintf(err, errlen, "bad ownership or modes for file %s",
455 buf);
456 return -1;
457 }
458
459 /* for each component of the canonical path, walking upwards */
460 for (;;) {
461 if ((cp = dirname(buf)) == NULL) {
462 snprintf(err, errlen, "dirname() failed");
463 return -1;
464 }
465 strlcpy(buf, cp, sizeof(buf));
466
467 if (stat(buf, &st) < 0 ||
462 (st.st_uid != 0 && st.st_uid != uid) ||
468 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
463 (st.st_mode & 022) != 0) {
464 snprintf(err, errlen,
465 "bad ownership or modes for directory %s", buf);
466 return -1;
467 }
468
469 /* If are past the homedir then we can stop */
470 if (comparehome && strcmp(homedir, buf) == 0)

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

475 * but we can be paranoid and check for "." too
476 */
477 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
478 break;
479 }
480 return 0;
481}
482
469 (st.st_mode & 022) != 0) {
470 snprintf(err, errlen,
471 "bad ownership or modes for directory %s", buf);
472 return -1;
473 }
474
475 /* If are past the homedir then we can stop */
476 if (comparehome && strcmp(homedir, buf) == 0)

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

481 * but we can be paranoid and check for "." too
482 */
483 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
484 break;
485 }
486 return 0;
487}
488
489/*
490 * Version of secure_path() that accepts an open file descriptor to
491 * avoid races.
492 *
493 * Returns 0 on success and -1 on failure
494 */
495static int
496secure_filename(FILE *f, const char *file, struct passwd *pw,
497 char *err, size_t errlen)
498{
499 struct stat st;
500
501 /* check the open file to avoid races */
502 if (fstat(fileno(f), &st) < 0) {
503 snprintf(err, errlen, "cannot stat file %s: %s",
504 file, strerror(errno));
505 return -1;
506 }
507 return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
508}
509
483static FILE *
484auth_openfile(const char *file, struct passwd *pw, int strict_modes,
485 int log_missing, char *file_type)
486{
487 char line[1024];
488 struct stat st;
489 int fd;
490 FILE *f;

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

610/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
611int
612auth_key_is_revoked(Key *key)
613{
614 char *key_fp;
615
616 if (options.revoked_keys_file == NULL)
617 return 0;
510static FILE *
511auth_openfile(const char *file, struct passwd *pw, int strict_modes,
512 int log_missing, char *file_type)
513{
514 char line[1024];
515 struct stat st;
516 int fd;
517 FILE *f;

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

637/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
638int
639auth_key_is_revoked(Key *key)
640{
641 char *key_fp;
642
643 if (options.revoked_keys_file == NULL)
644 return 0;
618
645 switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) {
646 case 0:
647 return 0; /* Not revoked */
648 case -2:
649 break; /* Not a KRL */
650 default:
651 goto revoked;
652 }
653 debug3("%s: treating %s as a key list", __func__,
654 options.revoked_keys_file);
619 switch (key_in_file(key, options.revoked_keys_file, 0)) {
620 case 0:
621 /* key not revoked */
622 return 0;
623 case -1:
624 /* Error opening revoked_keys_file: refuse all keys */
625 error("Revoked keys file is unreadable: refusing public key "
626 "authentication");
627 return 1;
628 case 1:
655 switch (key_in_file(key, options.revoked_keys_file, 0)) {
656 case 0:
657 /* key not revoked */
658 return 0;
659 case -1:
660 /* Error opening revoked_keys_file: refuse all keys */
661 error("Revoked keys file is unreadable: refusing public key "
662 "authentication");
663 return 1;
664 case 1:
665 revoked:
629 /* Key revoked */
630 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
631 error("WARNING: authentication attempt with a revoked "
632 "%s key %s ", key_type(key), key_fp);
633 xfree(key_fp);
634 return 1;
635 }
636 fatal("key_in_file returned junk");

--- 62 unchanged lines hidden ---
666 /* Key revoked */
667 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
668 error("WARNING: authentication attempt with a revoked "
669 "%s key %s ", key_type(key), key_fp);
670 xfree(key_fp);
671 return 1;
672 }
673 fatal("key_in_file returned junk");

--- 62 unchanged lines hidden ---