xref: /netbsd-src/crypto/external/bsd/openssh/dist/auth.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /*	$NetBSD: auth.c,v 1.20 2017/10/07 19:39:19 christos Exp $	*/
2 /* $OpenBSD: auth.c,v 1.124 2017/09/12 06:32:07 djm Exp $ */
3 /*
4  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "includes.h"
28 __RCSID("$NetBSD: auth.c,v 1.20 2017/10/07 19:39:19 christos Exp $");
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/socket.h>
32 
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <login_cap.h>
36 #include <paths.h>
37 #include <pwd.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <limits.h>
43 #include <netdb.h>
44 
45 #include "xmalloc.h"
46 #include "match.h"
47 #include "groupaccess.h"
48 #include "log.h"
49 #include "buffer.h"
50 #include "misc.h"
51 #include "servconf.h"
52 #include "key.h"
53 #include "hostfile.h"
54 #include "auth.h"
55 #include "auth-options.h"
56 #include "canohost.h"
57 #include "uidswap.h"
58 #include "packet.h"
59 #ifdef GSSAPI
60 #include "ssh-gss.h"
61 #endif
62 #include "authfile.h"
63 #include "monitor_wrap.h"
64 #include "authfile.h"
65 #include "ssherr.h"
66 #include "compat.h"
67 #include "pfilter.h"
68 
69 #ifdef HAVE_LOGIN_CAP
70 #include <login_cap.h>
71 #endif
72 
73 /* import */
74 extern ServerOptions options;
75 extern int use_privsep;
76 
77 /* Debugging messages */
78 Buffer auth_debug;
79 int auth_debug_init;
80 
81 #ifndef HOST_ONLY
82 /*
83  * Check if the user is allowed to log in via ssh. If user is listed
84  * in DenyUsers or one of user's groups is listed in DenyGroups, false
85  * will be returned. If AllowUsers isn't empty and user isn't listed
86  * there, or if AllowGroups isn't empty and one of user's groups isn't
87  * listed there, false will be returned.
88  * If the user's shell is not executable, false will be returned.
89  * Otherwise true is returned.
90  */
91 int
92 allowed_user(struct passwd * pw)
93 {
94 #ifdef HAVE_LOGIN_CAP
95 	extern login_cap_t *lc;
96 	int match_name, match_ip;
97 	char *cap_hlist, *hp;
98 #endif
99 	struct ssh *ssh = active_state; /* XXX */
100 	struct stat st;
101 	const char *hostname = NULL, *ipaddr = NULL;
102 	int r;
103 	u_int i;
104 
105 	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
106 	if (!pw || !pw->pw_name)
107 		return 0;
108 
109 #ifdef HAVE_LOGIN_CAP
110 	hostname = auth_get_canonical_hostname(ssh, options.use_dns);
111 	ipaddr = ssh_remote_ipaddr(ssh);
112 
113 	lc = login_getclass(pw->pw_class);
114 
115 	/*
116 	 * Check the deny list.
117 	 */
118 	cap_hlist = login_getcapstr(lc, "host.deny", NULL, NULL);
119 	if (cap_hlist != NULL) {
120 		hp = strtok(cap_hlist, ",");
121 		while (hp != NULL) {
122 			match_name = match_hostname(hostname, hp);
123 			match_ip = match_hostname(ipaddr, hp);
124 			/*
125 			 * Only a positive match here causes a "deny".
126 			 */
127 			if (match_name > 0 || match_ip > 0) {
128 				free(cap_hlist);
129 				login_close(lc);
130 				return 0;
131 			}
132 			hp = strtok(NULL, ",");
133 		}
134 		free(cap_hlist);
135 	}
136 
137 	/*
138 	 * Check the allow list.  If the allow list exists, and the
139 	 * remote host is not in it, the user is implicitly denied.
140 	 */
141 	cap_hlist = login_getcapstr(lc, "host.allow", NULL, NULL);
142 	if (cap_hlist != NULL) {
143 		hp = strtok(cap_hlist, ",");
144 		if (hp == NULL) {
145 			/* Just in case there's an empty string... */
146 			free(cap_hlist);
147 			login_close(lc);
148 			return 0;
149 		}
150 		while (hp != NULL) {
151 			match_name = match_hostname(hostname, hp);
152 			match_ip = match_hostname(ipaddr, hp);
153 			/*
154 			 * Negative match causes an immediate "deny".
155 			 * Positive match causes us to break out
156 			 * of the loop (allowing a fallthrough).
157 			 */
158 			if (match_name < 0 || match_ip < 0) {
159 				free(cap_hlist);
160 				login_close(lc);
161 				return 0;
162 			}
163 			if (match_name > 0 || match_ip > 0)
164 				break;
165 			hp = strtok(NULL, ",");
166 		}
167 		free(cap_hlist);
168 		if (hp == NULL) {
169 			login_close(lc);
170 			return 0;
171 		}
172 	}
173 
174 	login_close(lc);
175 #endif
176 
177 #ifdef USE_PAM
178 	if (!options.use_pam) {
179 #endif
180 	/*
181 	 * password/account expiration.
182 	 */
183 	if (pw->pw_change || pw->pw_expire) {
184 		struct timeval tv;
185 
186 		(void)gettimeofday(&tv, (struct timezone *)NULL);
187 		if (pw->pw_expire) {
188 			if (tv.tv_sec >= pw->pw_expire) {
189 				logit("User %.100s not allowed because account has expired",
190 				    pw->pw_name);
191 				return 0;	/* expired */
192 			}
193 		}
194 #ifdef _PASSWORD_CHGNOW
195 		if (pw->pw_change == _PASSWORD_CHGNOW) {
196 			logit("User %.100s not allowed because password needs to be changed",
197 			    pw->pw_name);
198 
199 			return 0;	/* can't force password change (yet) */
200 		}
201 #endif
202 		if (pw->pw_change) {
203 			if (tv.tv_sec >= pw->pw_change) {
204 				logit("User %.100s not allowed because password has expired",
205 				    pw->pw_name);
206 				return 0;	/* expired */
207 			}
208 		}
209 	}
210 #ifdef USE_PAM
211 	}
212 #endif
213 
214 	/*
215 	 * Deny if shell does not exist or is not executable unless we
216 	 * are chrooting.
217 	 */
218 	/*
219 	 * XXX Should check to see if it is executable by the
220 	 * XXX requesting user.  --thorpej
221 	 */
222 	if (options.chroot_directory == NULL ||
223 	    strcasecmp(options.chroot_directory, "none") == 0) {
224 		char *shell = xstrdup((pw->pw_shell[0] == '\0') ?
225 		    _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */
226 
227 		if (stat(shell, &st) != 0) {
228 			logit("User %.100s not allowed because shell %.100s "
229 			    "does not exist", pw->pw_name, shell);
230 			free(shell);
231 			return 0;
232 		}
233 		if (S_ISREG(st.st_mode) == 0 ||
234 		    (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
235 			logit("User %.100s not allowed because shell %.100s "
236 			    "is not executable", pw->pw_name, shell);
237 			free(shell);
238 			return 0;
239 		}
240 		free(shell);
241 	}
242 	/*
243 	 * XXX Consider nuking {Allow,Deny}{Users,Groups}.  We have the
244 	 * XXX login_cap(3) mechanism which covers all other types of
245 	 * XXX logins, too.
246 	 */
247 
248 	if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
249 	    options.num_deny_groups > 0 || options.num_allow_groups > 0) {
250 		hostname = auth_get_canonical_hostname(ssh, options.use_dns);
251 		ipaddr = ssh_remote_ipaddr(ssh);
252 	}
253 
254 	/* Return false if user is listed in DenyUsers */
255 	if (options.num_deny_users > 0) {
256 		for (i = 0; i < options.num_deny_users; i++) {
257 			r = match_user(pw->pw_name, hostname, ipaddr,
258 			    options.deny_users[i]);
259 			if (r < 0) {
260 				fatal("Invalid DenyUsers pattern \"%.100s\"",
261 				    options.deny_users[i]);
262 			} else if (r != 0) {
263 				logit("User %.100s from %.100s not allowed "
264 				    "because listed in DenyUsers",
265 				    pw->pw_name, hostname);
266 				return 0;
267 			}
268 		}
269 	}
270 	/* Return false if AllowUsers isn't empty and user isn't listed there */
271 	if (options.num_allow_users > 0) {
272 		for (i = 0; i < options.num_allow_users; i++) {
273 			r = match_user(pw->pw_name, hostname, ipaddr,
274 			    options.allow_users[i]);
275 			if (r < 0) {
276 				fatal("Invalid AllowUsers pattern \"%.100s\"",
277 				    options.allow_users[i]);
278 			} else if (r == 1)
279 				break;
280 		}
281 		/* i < options.num_allow_users iff we break for loop */
282 		if (i >= options.num_allow_users) {
283 			logit("User %.100s from %.100s not allowed because "
284 			    "not listed in AllowUsers", pw->pw_name, hostname);
285 			return 0;
286 		}
287 	}
288 	if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
289 		/* Get the user's group access list (primary and supplementary) */
290 		if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
291 			logit("User %.100s from %.100s not allowed because "
292 			    "not in any group", pw->pw_name, hostname);
293 			return 0;
294 		}
295 
296 		/* Return false if one of user's groups is listed in DenyGroups */
297 		if (options.num_deny_groups > 0)
298 			if (ga_match(options.deny_groups,
299 			    options.num_deny_groups)) {
300 				ga_free();
301 				logit("User %.100s from %.100s not allowed "
302 				    "because a group is listed in DenyGroups",
303 				    pw->pw_name, hostname);
304 				return 0;
305 			}
306 		/*
307 		 * Return false if AllowGroups isn't empty and one of user's groups
308 		 * isn't listed there
309 		 */
310 		if (options.num_allow_groups > 0)
311 			if (!ga_match(options.allow_groups,
312 			    options.num_allow_groups)) {
313 				ga_free();
314 				logit("User %.100s from %.100s not allowed "
315 				    "because none of user's groups are listed "
316 				    "in AllowGroups", pw->pw_name, hostname);
317 				return 0;
318 			}
319 		ga_free();
320 	}
321 	/* We found no reason not to let this user try to log on... */
322 	return 1;
323 }
324 
325 /*
326  * Formats any key left in authctxt->auth_method_key for inclusion in
327  * auth_log()'s message. Also includes authxtct->auth_method_info if present.
328  */
329 static char *
330 format_method_key(Authctxt *authctxt)
331 {
332 	const struct sshkey *key = authctxt->auth_method_key;
333 	const char *methinfo = authctxt->auth_method_info;
334 	char *fp, *ret = NULL;
335 
336 	if (key == NULL)
337 		return NULL;
338 
339 	if (key_is_cert(key)) {
340 		fp = sshkey_fingerprint(key->cert->signature_key,
341 		    options.fingerprint_hash, SSH_FP_DEFAULT);
342 		xasprintf(&ret, "%s ID %s (serial %llu) CA %s %s%s%s",
343 		    sshkey_type(key), key->cert->key_id,
344 		    (unsigned long long)key->cert->serial,
345 		    sshkey_type(key->cert->signature_key),
346 		    fp == NULL ? "(null)" : fp,
347 		    methinfo == NULL ? "" : ", ",
348 		    methinfo == NULL ? "" : methinfo);
349 		free(fp);
350 	} else {
351 		fp = sshkey_fingerprint(key, options.fingerprint_hash,
352 		    SSH_FP_DEFAULT);
353 		xasprintf(&ret, "%s %s%s%s", sshkey_type(key),
354 		    fp == NULL ? "(null)" : fp,
355 		    methinfo == NULL ? "" : ", ",
356 		    methinfo == NULL ? "" : methinfo);
357 		free(fp);
358 	}
359 	return ret;
360 }
361 
362 void
363 auth_log(Authctxt *authctxt, int authenticated, int partial,
364     const char *method, const char *submethod)
365 {
366 	struct ssh *ssh = active_state; /* XXX */
367 	void (*authlog) (const char *fmt,...) = verbose;
368 	const char *authmsg;
369 	char *extra = NULL;
370 
371 	if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
372 		return;
373 
374 	/* Raise logging level */
375 	if (authenticated == 1 ||
376 	    !authctxt->valid ||
377 	    authctxt->failures >= options.max_authtries / 2 ||
378 	    strcmp(method, "password") == 0)
379 		authlog = logit;
380 
381 	if (authctxt->postponed)
382 		authmsg = "Postponed";
383 	else if (partial)
384 		authmsg = "Partial";
385 	else
386 		authmsg = authenticated ? "Accepted" : "Failed";
387 
388 	if ((extra = format_method_key(authctxt)) == NULL) {
389 		if (authctxt->auth_method_info != NULL)
390 			extra = xstrdup(authctxt->auth_method_info);
391 	}
392 
393 	authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
394 	    authmsg,
395 	    method,
396 	    submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
397 	    authctxt->valid ? "" : "invalid user ",
398 	    authctxt->user,
399 	    ssh_remote_ipaddr(ssh),
400 	    ssh_remote_port(ssh),
401 	    extra != NULL ? ": " : "",
402 	    extra != NULL ? extra : "");
403 
404 	free(extra);
405 	if (!authctxt->postponed)
406 		pfilter_notify(!authenticated);
407 }
408 
409 void
410 auth_maxtries_exceeded(Authctxt *authctxt)
411 {
412 	struct ssh *ssh = active_state; /* XXX */
413 
414 	error("maximum authentication attempts exceeded for "
415 	    "%s%.100s from %.200s port %d ssh2",
416 	    authctxt->valid ? "" : "invalid user ",
417 	    authctxt->user,
418 	    ssh_remote_ipaddr(ssh),
419 	    ssh_remote_port(ssh));
420 	packet_disconnect("Too many authentication failures");
421 	/* NOTREACHED */
422 }
423 
424 /*
425  * Check whether root logins are disallowed.
426  */
427 int
428 auth_root_allowed(const char *method)
429 {
430 	struct ssh *ssh = active_state; /* XXX */
431 
432 	switch (options.permit_root_login) {
433 	case PERMIT_YES:
434 		return 1;
435 	case PERMIT_NO_PASSWD:
436 		if (strcmp(method, "publickey") == 0 ||
437 		    strcmp(method, "hostbased") == 0 ||
438 		    strcmp(method, "gssapi-with-mic") == 0)
439 			return 1;
440 		break;
441 	case PERMIT_FORCED_ONLY:
442 		if (forced_command) {
443 			logit("Root login accepted for forced command.");
444 			return 1;
445 		}
446 		break;
447 	}
448 	logit("ROOT LOGIN REFUSED FROM %.200s port %d",
449 	    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
450 	return 0;
451 }
452 
453 
454 /*
455  * Given a template and a passwd structure, build a filename
456  * by substituting % tokenised options. Currently, %% becomes '%',
457  * %h becomes the home directory and %u the username.
458  *
459  * This returns a buffer allocated by xmalloc.
460  */
461 char *
462 expand_authorized_keys(const char *filename, struct passwd *pw)
463 {
464 	char *file, ret[PATH_MAX];
465 	int i;
466 
467 	file = percent_expand(filename, "h", pw->pw_dir,
468 	    "u", pw->pw_name, (char *)NULL);
469 
470 	/*
471 	 * Ensure that filename starts anchored. If not, be backward
472 	 * compatible and prepend the '%h/'
473 	 */
474 	if (*file == '/')
475 		return (file);
476 
477 	i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
478 	if (i < 0 || (size_t)i >= sizeof(ret))
479 		fatal("expand_authorized_keys: path too long");
480 	free(file);
481 	return (xstrdup(ret));
482 }
483 
484 char *
485 authorized_principals_file(struct passwd *pw)
486 {
487 	if (options.authorized_principals_file == NULL)
488 		return NULL;
489 	return expand_authorized_keys(options.authorized_principals_file, pw);
490 }
491 
492 /* return ok if key exists in sysfile or userfile */
493 HostStatus
494 check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
495     const char *sysfile, const char *userfile)
496 {
497 	char *user_hostfile;
498 	struct stat st;
499 	HostStatus host_status;
500 	struct hostkeys *hostkeys;
501 	const struct hostkey_entry *found;
502 
503 	hostkeys = init_hostkeys();
504 	load_hostkeys(hostkeys, host, sysfile);
505 	if (userfile != NULL) {
506 		user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
507 		if (options.strict_modes &&
508 		    (stat(user_hostfile, &st) == 0) &&
509 		    ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
510 		    (st.st_mode & 022) != 0)) {
511 			logit("Authentication refused for %.100s: "
512 			    "bad owner or modes for %.200s",
513 			    pw->pw_name, user_hostfile);
514 			auth_debug_add("Ignored %.200s: bad ownership or modes",
515 			    user_hostfile);
516 		} else {
517 			temporarily_use_uid(pw);
518 			load_hostkeys(hostkeys, host, user_hostfile);
519 			restore_uid();
520 		}
521 		free(user_hostfile);
522 	}
523 	host_status = check_key_in_hostkeys(hostkeys, key, &found);
524 	if (host_status == HOST_REVOKED)
525 		error("WARNING: revoked key for %s attempted authentication",
526 		    found->host);
527 	else if (host_status == HOST_OK)
528 		debug("%s: key for %s found at %s:%ld", __func__,
529 		    found->host, found->file, found->line);
530 	else
531 		debug("%s: key for host %s not found", __func__, host);
532 
533 	free_hostkeys(hostkeys);
534 
535 	return host_status;
536 }
537 
538 static FILE *
539 auth_openfile(const char *file, struct passwd *pw, int strict_modes,
540     int log_missing, const char *file_type)
541 {
542 	char line[1024];
543 	struct stat st;
544 	int fd;
545 	FILE *f;
546 
547 	if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
548 		if (log_missing || errno != ENOENT)
549 			debug("Could not open %s '%s': %s", file_type, file,
550 			   strerror(errno));
551 		return NULL;
552 	}
553 
554 	if (fstat(fd, &st) < 0) {
555 		close(fd);
556 		return NULL;
557 	}
558 	if (!S_ISREG(st.st_mode)) {
559 		logit("User %s %s %s is not a regular file",
560 		    pw->pw_name, file_type, file);
561 		close(fd);
562 		return NULL;
563 	}
564 	unset_nonblock(fd);
565 	if ((f = fdopen(fd, "r")) == NULL) {
566 		close(fd);
567 		return NULL;
568 	}
569 	if (strict_modes &&
570 	    safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) {
571 		fclose(f);
572 		logit("Authentication refused: %s", line);
573 		auth_debug_add("Ignored %s: %s", file_type, line);
574 		return NULL;
575 	}
576 
577 	return f;
578 }
579 
580 
581 FILE *
582 auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
583 {
584 	return auth_openfile(file, pw, strict_modes, 1, "authorized keys");
585 }
586 
587 FILE *
588 auth_openprincipals(const char *file, struct passwd *pw, int strict_modes)
589 {
590 	return auth_openfile(file, pw, strict_modes, 0,
591 	    "authorized principals");
592 }
593 
594 struct passwd *
595 getpwnamallow(const char *user)
596 {
597 #ifdef HAVE_LOGIN_CAP
598  	extern login_cap_t *lc;
599 #ifdef BSD_AUTH
600  	auth_session_t *as;
601 #endif
602 #endif
603 	struct ssh *ssh = active_state; /* XXX */
604 	struct passwd *pw;
605 	struct connection_info *ci = get_connection_info(1, options.use_dns);
606 
607 	ci->user = user;
608 	parse_server_match_config(&options, ci);
609 	log_change_level(options.log_level);
610 	process_permitopen(ssh, &options);
611 
612 	pw = getpwnam(user);
613 	if (pw == NULL) {
614 		pfilter_notify(1);
615 		logit("Invalid user %.100s from %.100s port %d",
616 		    user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
617 		return (NULL);
618 	}
619 	if (!allowed_user(pw))
620 		return (NULL);
621 #ifdef HAVE_LOGIN_CAP
622 	if ((lc = login_getclass(pw->pw_class)) == NULL) {
623 		debug("unable to get login class: %s", user);
624 		return (NULL);
625 	}
626 #ifdef BSD_AUTH
627 	if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
628 	    auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
629 		debug("Approval failure for %s", user);
630 		pw = NULL;
631 	}
632 	if (as != NULL)
633 		auth_close(as);
634 #endif
635 #endif
636 	if (pw != NULL)
637 		return (pwcopy(pw));
638 	return (NULL);
639 }
640 
641 /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
642 int
643 auth_key_is_revoked(struct sshkey *key)
644 {
645 	char *fp = NULL;
646 	int r;
647 
648 	if (options.revoked_keys_file == NULL)
649 		return 0;
650 	if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
651 	    SSH_FP_DEFAULT)) == NULL) {
652 		r = SSH_ERR_ALLOC_FAIL;
653 		error("%s: fingerprint key: %s", __func__, ssh_err(r));
654 		goto out;
655 	}
656 
657 	r = sshkey_check_revoked(key, options.revoked_keys_file);
658 	switch (r) {
659 	case 0:
660 		break; /* not revoked */
661 	case SSH_ERR_KEY_REVOKED:
662 		error("Authentication key %s %s revoked by file %s",
663 		    sshkey_type(key), fp, options.revoked_keys_file);
664 		goto out;
665 	default:
666 		error("Error checking authentication key %s %s in "
667 		    "revoked keys file %s: %s", sshkey_type(key), fp,
668 		    options.revoked_keys_file, ssh_err(r));
669 		goto out;
670 	}
671 
672 	/* Success */
673 	r = 0;
674 
675  out:
676 	free(fp);
677 	return r == 0 ? 0 : 1;
678 }
679 
680 void
681 auth_debug_add(const char *fmt,...)
682 {
683 	char buf[1024];
684 	va_list args;
685 
686 	if (!auth_debug_init)
687 		return;
688 
689 	va_start(args, fmt);
690 	vsnprintf(buf, sizeof(buf), fmt, args);
691 	va_end(args);
692 	buffer_put_cstring(&auth_debug, buf);
693 }
694 
695 void
696 auth_debug_send(void)
697 {
698 	char *msg;
699 
700 	if (!auth_debug_init)
701 		return;
702 	while (buffer_len(&auth_debug)) {
703 		msg = buffer_get_string(&auth_debug, NULL);
704 		packet_send_debug("%s", msg);
705 		free(msg);
706 	}
707 }
708 
709 void
710 auth_debug_reset(void)
711 {
712 	if (auth_debug_init)
713 		buffer_clear(&auth_debug);
714 	else {
715 		buffer_init(&auth_debug);
716 		auth_debug_init = 1;
717 	}
718 }
719 
720 struct passwd *
721 fakepw(void)
722 {
723 	static struct passwd fake;
724 	static char nouser[] = "NOUSER";
725 	static char nonexist[] = "/nonexist";
726 
727 	memset(&fake, 0, sizeof(fake));
728 	fake.pw_name = nouser;
729 	fake.pw_passwd = __UNCONST(
730 	    "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK");
731 	fake.pw_gecos = nouser;
732 	fake.pw_uid = (uid_t)-1;
733 	fake.pw_gid = (gid_t)-1;
734 	fake.pw_class = __UNCONST("");
735 	fake.pw_dir = nonexist;
736 	fake.pw_shell = nonexist;
737 
738 	return (&fake);
739 }
740 #endif
741 
742 /*
743  * Returns the remote DNS hostname as a string. The returned string must not
744  * be freed. NB. this will usually trigger a DNS query the first time it is
745  * called.
746  * This function does additional checks on the hostname to mitigate some
747  * attacks on legacy rhosts-style authentication.
748  * XXX is RhostsRSAAuthentication vulnerable to these?
749  * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
750  */
751 
752 static char *
753 remote_hostname(struct ssh *ssh)
754 {
755 	struct sockaddr_storage from;
756 	socklen_t fromlen;
757 	struct addrinfo hints, *ai, *aitop;
758 	char name[NI_MAXHOST], ntop2[NI_MAXHOST];
759 	const char *ntop = ssh_remote_ipaddr(ssh);
760 
761 	/* Get IP address of client. */
762 	fromlen = sizeof(from);
763 	memset(&from, 0, sizeof(from));
764 	if (getpeername(ssh_packet_get_connection_in(ssh),
765 	    (struct sockaddr *)&from, &fromlen) < 0) {
766 		debug("getpeername failed: %.100s", strerror(errno));
767 		return strdup(ntop);
768 	}
769 
770 	debug3("Trying to reverse map address %.100s.", ntop);
771 	/* Map the IP address to a host name. */
772 	if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
773 	    NULL, 0, NI_NAMEREQD) != 0) {
774 		/* Host name not found.  Use ip address. */
775 		return strdup(ntop);
776 	}
777 
778 	/*
779 	 * if reverse lookup result looks like a numeric hostname,
780 	 * someone is trying to trick us by PTR record like following:
781 	 *	1.1.1.10.in-addr.arpa.	IN PTR	2.3.4.5
782 	 */
783 	memset(&hints, 0, sizeof(hints));
784 	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
785 	hints.ai_flags = AI_NUMERICHOST;
786 	if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
787 		logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
788 		    name, ntop);
789 		freeaddrinfo(ai);
790 		return strdup(ntop);
791 	}
792 
793 	/* Names are stored in lowercase. */
794 	lowercase(name);
795 
796 	/*
797 	 * Map it back to an IP address and check that the given
798 	 * address actually is an address of this host.  This is
799 	 * necessary because anyone with access to a name server can
800 	 * define arbitrary names for an IP address. Mapping from
801 	 * name to IP address can be trusted better (but can still be
802 	 * fooled if the intruder has access to the name server of
803 	 * the domain).
804 	 */
805 	memset(&hints, 0, sizeof(hints));
806 	hints.ai_family = from.ss_family;
807 	hints.ai_socktype = SOCK_STREAM;
808 	if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
809 		logit("reverse mapping checking getaddrinfo for %.700s "
810 		    "[%s] failed.", name, ntop);
811 		return strdup(ntop);
812 	}
813 	/* Look for the address from the list of addresses. */
814 	for (ai = aitop; ai; ai = ai->ai_next) {
815 		if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
816 		    sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
817 		    (strcmp(ntop, ntop2) == 0))
818 				break;
819 	}
820 	freeaddrinfo(aitop);
821 	/* If we reached the end of the list, the address was not there. */
822 	if (ai == NULL) {
823 		/* Address not found for the host name. */
824 		logit("Address %.100s maps to %.600s, but this does not "
825 		    "map back to the address.", ntop, name);
826 		return strdup(ntop);
827 	}
828 	return strdup(name);
829 }
830 
831 /*
832  * Return the canonical name of the host in the other side of the current
833  * connection.  The host name is cached, so it is efficient to call this
834  * several times.
835  */
836 
837 const char *
838 auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
839 {
840 	static char *dnsname;
841 
842 	if (!use_dns)
843 		return ssh_remote_ipaddr(ssh);
844 	else if (dnsname != NULL)
845 		return dnsname;
846 	else {
847 		dnsname = remote_hostname(ssh);
848 		return dnsname;
849 	}
850 }
851