1 /* $OpenBSD: auth.c,v 1.160 2023/03/05 05:34:09 dtucker Exp $ */
3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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.
28 #include <sys/types.h>
30 #include <sys/socket.h>
33 #include <netinet/in.h>
58 #include "groupaccess.h"
66 #include "auth-options.h"
75 #include "monitor_wrap.h"
80 extern ServerOptions options
;
81 extern struct include_list includes
;
82 extern int use_privsep
;
83 extern struct sshbuf
*loginmsg
;
84 extern struct passwd
*privsep_pw
;
85 extern struct sshauthopt
*auth_opts
;
87 /* Debugging messages */
88 static struct sshbuf
*auth_debug
;
91 * Check if the user is allowed to log in via ssh. If user is listed
92 * in DenyUsers or one of user's groups is listed in DenyGroups, false
93 * will be returned. If AllowUsers isn't empty and user isn't listed
94 * there, or if AllowGroups isn't empty and one of user's groups isn't
95 * listed there, false will be returned.
96 * If the user's shell is not executable, false will be returned.
97 * Otherwise true is returned.
100 allowed_user(struct ssh
*ssh
, struct passwd
* pw
)
103 const char *hostname
= NULL
, *ipaddr
= NULL
;
107 /* Shouldn't be called if pw is NULL, but better safe than sorry... */
108 if (!pw
|| !pw
->pw_name
)
111 if (!options
.use_pam
&& platform_locked_account(pw
)) {
112 logit("User %.100s not allowed because account is locked",
118 * Deny if shell does not exist or is not executable unless we
121 if (options
.chroot_directory
== NULL
||
122 strcasecmp(options
.chroot_directory
, "none") == 0) {
123 char *shell
= xstrdup((pw
->pw_shell
[0] == '\0') ?
124 _PATH_BSHELL
: pw
->pw_shell
); /* empty = /bin/sh */
126 if (stat(shell
, &st
) == -1) {
127 logit("User %.100s not allowed because shell %.100s "
128 "does not exist", pw
->pw_name
, shell
);
132 if (S_ISREG(st
.st_mode
) == 0 ||
133 (st
.st_mode
& (S_IXOTH
|S_IXUSR
|S_IXGRP
)) == 0) {
134 logit("User %.100s not allowed because shell %.100s "
135 "is not executable", pw
->pw_name
, shell
);
142 if (options
.num_deny_users
> 0 || options
.num_allow_users
> 0 ||
143 options
.num_deny_groups
> 0 || options
.num_allow_groups
> 0) {
144 hostname
= auth_get_canonical_hostname(ssh
, options
.use_dns
);
145 ipaddr
= ssh_remote_ipaddr(ssh
);
148 /* Return false if user is listed in DenyUsers */
149 if (options
.num_deny_users
> 0) {
150 for (i
= 0; i
< options
.num_deny_users
; i
++) {
151 r
= match_user(pw
->pw_name
, hostname
, ipaddr
,
152 options
.deny_users
[i
]);
154 fatal("Invalid DenyUsers pattern \"%.100s\"",
155 options
.deny_users
[i
]);
157 logit("User %.100s from %.100s not allowed "
158 "because listed in DenyUsers",
159 pw
->pw_name
, hostname
);
164 /* Return false if AllowUsers isn't empty and user isn't listed there */
165 if (options
.num_allow_users
> 0) {
166 for (i
= 0; i
< options
.num_allow_users
; i
++) {
167 r
= match_user(pw
->pw_name
, hostname
, ipaddr
,
168 options
.allow_users
[i
]);
170 fatal("Invalid AllowUsers pattern \"%.100s\"",
171 options
.allow_users
[i
]);
175 /* i < options.num_allow_users iff we break for loop */
176 if (i
>= options
.num_allow_users
) {
177 logit("User %.100s from %.100s not allowed because "
178 "not listed in AllowUsers", pw
->pw_name
, hostname
);
182 if (options
.num_deny_groups
> 0 || options
.num_allow_groups
> 0) {
183 /* Get the user's group access list (primary and supplementary) */
184 if (ga_init(pw
->pw_name
, pw
->pw_gid
) == 0) {
185 logit("User %.100s from %.100s not allowed because "
186 "not in any group", pw
->pw_name
, hostname
);
190 /* Return false if one of user's groups is listed in DenyGroups */
191 if (options
.num_deny_groups
> 0)
192 if (ga_match(options
.deny_groups
,
193 options
.num_deny_groups
)) {
195 logit("User %.100s from %.100s not allowed "
196 "because a group is listed in DenyGroups",
197 pw
->pw_name
, hostname
);
201 * Return false if AllowGroups isn't empty and one of user's groups
204 if (options
.num_allow_groups
> 0)
205 if (!ga_match(options
.allow_groups
,
206 options
.num_allow_groups
)) {
208 logit("User %.100s from %.100s not allowed "
209 "because none of user's groups are listed "
210 "in AllowGroups", pw
->pw_name
, hostname
);
216 #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
217 if (!sys_auth_allowed_user(pw
, loginmsg
))
221 /* We found no reason not to let this user try to log on... */
226 * Formats any key left in authctxt->auth_method_key for inclusion in
227 * auth_log()'s message. Also includes authxtct->auth_method_info if present.
230 format_method_key(Authctxt
*authctxt
)
232 const struct sshkey
*key
= authctxt
->auth_method_key
;
233 const char *methinfo
= authctxt
->auth_method_info
;
234 char *fp
, *cafp
, *ret
= NULL
;
239 if (sshkey_is_cert(key
)) {
240 fp
= sshkey_fingerprint(key
,
241 options
.fingerprint_hash
, SSH_FP_DEFAULT
);
242 cafp
= sshkey_fingerprint(key
->cert
->signature_key
,
243 options
.fingerprint_hash
, SSH_FP_DEFAULT
);
244 xasprintf(&ret
, "%s %s ID %s (serial %llu) CA %s %s%s%s",
245 sshkey_type(key
), fp
== NULL
? "(null)" : fp
,
247 (unsigned long long)key
->cert
->serial
,
248 sshkey_type(key
->cert
->signature_key
),
249 cafp
== NULL
? "(null)" : cafp
,
250 methinfo
== NULL
? "" : ", ",
251 methinfo
== NULL
? "" : methinfo
);
255 fp
= sshkey_fingerprint(key
, options
.fingerprint_hash
,
257 xasprintf(&ret
, "%s %s%s%s", sshkey_type(key
),
258 fp
== NULL
? "(null)" : fp
,
259 methinfo
== NULL
? "" : ", ",
260 methinfo
== NULL
? "" : methinfo
);
267 auth_log(struct ssh
*ssh
, int authenticated
, int partial
,
268 const char *method
, const char *submethod
)
270 Authctxt
*authctxt
= (Authctxt
*)ssh
->authctxt
;
271 int level
= SYSLOG_LEVEL_VERBOSE
;
275 if (use_privsep
&& !mm_is_monitor() && !authctxt
->postponed
)
278 /* Raise logging level */
279 if (authenticated
== 1 ||
281 authctxt
->failures
>= options
.max_authtries
/ 2 ||
282 strcmp(method
, "password") == 0)
283 level
= SYSLOG_LEVEL_INFO
;
285 if (authctxt
->postponed
)
286 authmsg
= "Postponed";
290 authmsg
= authenticated
? "Accepted" : "Failed";
292 if ((extra
= format_method_key(authctxt
)) == NULL
) {
293 if (authctxt
->auth_method_info
!= NULL
)
294 extra
= xstrdup(authctxt
->auth_method_info
);
297 do_log2(level
, "%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
300 submethod
!= NULL
? "/" : "", submethod
== NULL
? "" : submethod
,
301 authctxt
->valid
? "" : "invalid user ",
303 ssh_remote_ipaddr(ssh
),
304 ssh_remote_port(ssh
),
305 extra
!= NULL
? ": " : "",
306 extra
!= NULL
? extra
: "");
310 #if defined(CUSTOM_FAILED_LOGIN) || defined(SSH_AUDIT_EVENTS)
311 if (authenticated
== 0 && !(authctxt
->postponed
|| partial
)) {
312 /* Log failed login attempt */
313 # ifdef CUSTOM_FAILED_LOGIN
314 if (strcmp(method
, "password") == 0 ||
315 strncmp(method
, "keyboard-interactive", 20) == 0 ||
316 strcmp(method
, "challenge-response") == 0)
317 record_failed_login(ssh
, authctxt
->user
,
318 auth_get_canonical_hostname(ssh
, options
.use_dns
), "ssh");
320 # ifdef SSH_AUDIT_EVENTS
321 audit_event(ssh
, audit_classify_auth(method
));
325 #if defined(CUSTOM_FAILED_LOGIN) && defined(WITH_AIXAUTHENTICATE)
327 sys_auth_record_login(authctxt
->user
,
328 auth_get_canonical_hostname(ssh
, options
.use_dns
), "ssh",
334 auth_maxtries_exceeded(struct ssh
*ssh
)
336 Authctxt
*authctxt
= (Authctxt
*)ssh
->authctxt
;
338 error("maximum authentication attempts exceeded for "
339 "%s%.100s from %.200s port %d ssh2",
340 authctxt
->valid
? "" : "invalid user ",
342 ssh_remote_ipaddr(ssh
),
343 ssh_remote_port(ssh
));
344 ssh_packet_disconnect(ssh
, "Too many authentication failures");
349 * Check whether root logins are disallowed.
352 auth_root_allowed(struct ssh
*ssh
, const char *method
)
354 switch (options
.permit_root_login
) {
357 case PERMIT_NO_PASSWD
:
358 if (strcmp(method
, "publickey") == 0 ||
359 strcmp(method
, "hostbased") == 0 ||
360 strcmp(method
, "gssapi-with-mic") == 0)
363 case PERMIT_FORCED_ONLY
:
364 if (auth_opts
->force_command
!= NULL
) {
365 logit("Root login accepted for forced command.");
370 logit("ROOT LOGIN REFUSED FROM %.200s port %d",
371 ssh_remote_ipaddr(ssh
), ssh_remote_port(ssh
));
377 * Given a template and a passwd structure, build a filename
378 * by substituting % tokenised options. Currently, %% becomes '%',
379 * %h becomes the home directory and %u the username.
381 * This returns a buffer allocated by xmalloc.
384 expand_authorized_keys(const char *filename
, struct passwd
*pw
)
386 char *file
, uidstr
[32], ret
[PATH_MAX
];
389 snprintf(uidstr
, sizeof(uidstr
), "%llu",
390 (unsigned long long)pw
->pw_uid
);
391 file
= percent_expand(filename
, "h", pw
->pw_dir
,
392 "u", pw
->pw_name
, "U", uidstr
, (char *)NULL
);
395 * Ensure that filename starts anchored. If not, be backward
396 * compatible and prepend the '%h/'
398 if (path_absolute(file
))
401 i
= snprintf(ret
, sizeof(ret
), "%s/%s", pw
->pw_dir
, file
);
402 if (i
< 0 || (size_t)i
>= sizeof(ret
))
403 fatal("expand_authorized_keys: path too long");
405 return (xstrdup(ret
));
409 authorized_principals_file(struct passwd
*pw
)
411 if (options
.authorized_principals_file
== NULL
)
413 return expand_authorized_keys(options
.authorized_principals_file
, pw
);
416 /* return ok if key exists in sysfile or userfile */
418 check_key_in_hostfiles(struct passwd
*pw
, struct sshkey
*key
, const char *host
,
419 const char *sysfile
, const char *userfile
)
423 HostStatus host_status
;
424 struct hostkeys
*hostkeys
;
425 const struct hostkey_entry
*found
;
427 hostkeys
= init_hostkeys();
428 load_hostkeys(hostkeys
, host
, sysfile
, 0);
429 if (userfile
!= NULL
) {
430 user_hostfile
= tilde_expand_filename(userfile
, pw
->pw_uid
);
431 if (options
.strict_modes
&&
432 (stat(user_hostfile
, &st
) == 0) &&
433 ((st
.st_uid
!= 0 && st
.st_uid
!= pw
->pw_uid
) ||
434 (st
.st_mode
& 022) != 0)) {
435 logit("Authentication refused for %.100s: "
436 "bad owner or modes for %.200s",
437 pw
->pw_name
, user_hostfile
);
438 auth_debug_add("Ignored %.200s: bad ownership or modes",
441 temporarily_use_uid(pw
);
442 load_hostkeys(hostkeys
, host
, user_hostfile
, 0);
447 host_status
= check_key_in_hostkeys(hostkeys
, key
, &found
);
448 if (host_status
== HOST_REVOKED
)
449 error("WARNING: revoked key for %s attempted authentication",
451 else if (host_status
== HOST_OK
)
452 debug_f("key for %s found at %s:%ld",
453 found
->host
, found
->file
, found
->line
);
455 debug_f("key for host %s not found", host
);
457 free_hostkeys(hostkeys
);
463 getpwnamallow(struct ssh
*ssh
, const char *user
)
465 #ifdef HAVE_LOGIN_CAP
466 extern login_cap_t
*lc
;
472 struct connection_info
*ci
;
475 ci
= get_connection_info(ssh
, 1, options
.use_dns
);
477 parse_server_match_config(&options
, &includes
, ci
);
478 log_change_level(options
.log_level
);
480 for (i
= 0; i
< options
.num_log_verbose
; i
++)
481 log_verbose_add(options
.log_verbose
[i
]);
482 process_permitopen(ssh
, &options
);
484 #if defined(_AIX) && defined(HAVE_SETAUTHDB)
490 #if defined(_AIX) && defined(HAVE_SETAUTHDB)
494 logit("Invalid user %.100s from %.100s port %d",
495 user
, ssh_remote_ipaddr(ssh
), ssh_remote_port(ssh
));
496 #ifdef CUSTOM_FAILED_LOGIN
497 record_failed_login(ssh
, user
,
498 auth_get_canonical_hostname(ssh
, options
.use_dns
), "ssh");
500 #ifdef SSH_AUDIT_EVENTS
501 audit_event(ssh
, SSH_INVALID_USER
);
502 #endif /* SSH_AUDIT_EVENTS */
505 if (!allowed_user(ssh
, pw
))
507 #ifdef HAVE_LOGIN_CAP
508 if ((lc
= login_getpwclass(pw
)) == NULL
) {
509 debug("unable to get login class: %s", user
);
513 if ((as
= auth_open()) == NULL
|| auth_setpwd(as
, pw
) != 0 ||
514 auth_approval(as
, lc
, pw
->pw_name
, "ssh") <= 0) {
515 debug("Approval failure for %s", user
);
527 /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
529 auth_key_is_revoked(struct sshkey
*key
)
534 if (options
.revoked_keys_file
== NULL
)
536 if ((fp
= sshkey_fingerprint(key
, options
.fingerprint_hash
,
537 SSH_FP_DEFAULT
)) == NULL
) {
538 r
= SSH_ERR_ALLOC_FAIL
;
539 error_fr(r
, "fingerprint key");
543 r
= sshkey_check_revoked(key
, options
.revoked_keys_file
);
546 break; /* not revoked */
547 case SSH_ERR_KEY_REVOKED
:
548 error("Authentication key %s %s revoked by file %s",
549 sshkey_type(key
), fp
, options
.revoked_keys_file
);
552 error_r(r
, "Error checking authentication key %s %s in "
553 "revoked keys file %s", sshkey_type(key
), fp
,
554 options
.revoked_keys_file
);
563 return r
== 0 ? 0 : 1;
567 auth_debug_add(const char *fmt
,...)
574 vsnprintf(buf
, sizeof(buf
), fmt
, args
);
577 if (auth_debug
!= NULL
)
578 if ((r
= sshbuf_put_cstring(auth_debug
, buf
)) != 0)
579 fatal_fr(r
, "sshbuf_put_cstring");
583 auth_debug_send(struct ssh
*ssh
)
588 if (auth_debug
== NULL
)
590 while (sshbuf_len(auth_debug
) != 0) {
591 if ((r
= sshbuf_get_cstring(auth_debug
, &msg
, NULL
)) != 0)
592 fatal_fr(r
, "sshbuf_get_cstring");
593 ssh_packet_send_debug(ssh
, "%s", msg
);
599 auth_debug_reset(void)
601 if (auth_debug
!= NULL
)
602 sshbuf_reset(auth_debug
);
603 else if ((auth_debug
= sshbuf_new()) == NULL
)
604 fatal_f("sshbuf_new failed");
611 static struct passwd fake
;
612 const char hashchars
[] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZ"
613 "abcdefghijklmnopqrstuvwxyz0123456789"; /* from bcrypt.c */
619 memset(&fake
, 0, sizeof(fake
));
620 fake
.pw_name
= "NOUSER";
621 fake
.pw_passwd
= xstrdup("$2a$10$"
622 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
623 for (cp
= fake
.pw_passwd
+ 7; *cp
!= '\0'; cp
++)
624 *cp
= hashchars
[arc4random_uniform(sizeof(hashchars
) - 1)];
625 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
626 fake
.pw_gecos
= "NOUSER";
628 fake
.pw_uid
= privsep_pw
== NULL
? (uid_t
)-1 : privsep_pw
->pw_uid
;
629 fake
.pw_gid
= privsep_pw
== NULL
? (gid_t
)-1 : privsep_pw
->pw_gid
;
630 #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
633 fake
.pw_dir
= "/nonexist";
634 fake
.pw_shell
= "/nonexist";
641 * Returns the remote DNS hostname as a string. The returned string must not
642 * be freed. NB. this will usually trigger a DNS query the first time it is
644 * This function does additional checks on the hostname to mitigate some
645 * attacks on based on conflation of hostnames and IP addresses.
649 remote_hostname(struct ssh
*ssh
)
651 struct sockaddr_storage from
;
653 struct addrinfo hints
, *ai
, *aitop
;
654 char name
[NI_MAXHOST
], ntop2
[NI_MAXHOST
];
655 const char *ntop
= ssh_remote_ipaddr(ssh
);
657 /* Get IP address of client. */
658 fromlen
= sizeof(from
);
659 memset(&from
, 0, sizeof(from
));
660 if (getpeername(ssh_packet_get_connection_in(ssh
),
661 (struct sockaddr
*)&from
, &fromlen
) == -1) {
662 debug("getpeername failed: %.100s", strerror(errno
));
663 return xstrdup(ntop
);
666 ipv64_normalise_mapped(&from
, &fromlen
);
667 if (from
.ss_family
== AF_INET6
)
668 fromlen
= sizeof(struct sockaddr_in6
);
670 debug3("Trying to reverse map address %.100s.", ntop
);
671 /* Map the IP address to a host name. */
672 if (getnameinfo((struct sockaddr
*)&from
, fromlen
, name
, sizeof(name
),
673 NULL
, 0, NI_NAMEREQD
) != 0) {
674 /* Host name not found. Use ip address. */
675 return xstrdup(ntop
);
679 * if reverse lookup result looks like a numeric hostname,
680 * someone is trying to trick us by PTR record like following:
681 * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
683 memset(&hints
, 0, sizeof(hints
));
684 hints
.ai_socktype
= SOCK_DGRAM
; /*dummy*/
685 hints
.ai_flags
= AI_NUMERICHOST
;
686 if (getaddrinfo(name
, NULL
, &hints
, &ai
) == 0) {
687 logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
690 return xstrdup(ntop
);
693 /* Names are stored in lowercase. */
697 * Map it back to an IP address and check that the given
698 * address actually is an address of this host. This is
699 * necessary because anyone with access to a name server can
700 * define arbitrary names for an IP address. Mapping from
701 * name to IP address can be trusted better (but can still be
702 * fooled if the intruder has access to the name server of
705 memset(&hints
, 0, sizeof(hints
));
706 hints
.ai_family
= from
.ss_family
;
707 hints
.ai_socktype
= SOCK_STREAM
;
708 if (getaddrinfo(name
, NULL
, &hints
, &aitop
) != 0) {
709 logit("reverse mapping checking getaddrinfo for %.700s "
710 "[%s] failed.", name
, ntop
);
711 return xstrdup(ntop
);
713 /* Look for the address from the list of addresses. */
714 for (ai
= aitop
; ai
; ai
= ai
->ai_next
) {
715 if (getnameinfo(ai
->ai_addr
, ai
->ai_addrlen
, ntop2
,
716 sizeof(ntop2
), NULL
, 0, NI_NUMERICHOST
) == 0 &&
717 (strcmp(ntop
, ntop2
) == 0))
721 /* If we reached the end of the list, the address was not there. */
723 /* Address not found for the host name. */
724 logit("Address %.100s maps to %.600s, but this does not "
725 "map back to the address.", ntop
, name
);
726 return xstrdup(ntop
);
728 return xstrdup(name
);
732 * Return the canonical name of the host in the other side of the current
733 * connection. The host name is cached, so it is efficient to call this
738 auth_get_canonical_hostname(struct ssh
*ssh
, int use_dns
)
740 static char *dnsname
;
743 return ssh_remote_ipaddr(ssh
);
744 else if (dnsname
!= NULL
)
747 dnsname
= remote_hostname(ssh
);
752 /* These functions link key/cert options to the auth framework */
754 /* Log sshauthopt options locally and (optionally) for remote transmission */
756 auth_log_authopts(const char *loc
, const struct sshauthopt
*opts
, int do_remote
)
758 int do_env
= options
.permit_user_env
&& opts
->nenv
> 0;
759 int do_permitopen
= opts
->npermitopen
> 0 &&
760 (options
.allow_tcp_forwarding
& FORWARD_LOCAL
) != 0;
761 int do_permitlisten
= opts
->npermitlisten
> 0 &&
762 (options
.allow_tcp_forwarding
& FORWARD_REMOTE
) != 0;
764 char msg
[1024], buf
[64];
766 snprintf(buf
, sizeof(buf
), "%d", opts
->force_tun_device
);
767 /* Try to keep this alphabetically sorted */
768 snprintf(msg
, sizeof(msg
), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
769 opts
->permit_agent_forwarding_flag
? " agent-forwarding" : "",
770 opts
->force_command
== NULL
? "" : " command",
771 do_env
? " environment" : "",
772 opts
->valid_before
== 0 ? "" : "expires",
773 opts
->no_require_user_presence
? " no-touch-required" : "",
774 do_permitopen
? " permitopen" : "",
775 do_permitlisten
? " permitlisten" : "",
776 opts
->permit_port_forwarding_flag
? " port-forwarding" : "",
777 opts
->cert_principals
== NULL
? "" : " principals",
778 opts
->permit_pty_flag
? " pty" : "",
779 opts
->require_verify
? " uv" : "",
780 opts
->force_tun_device
== -1 ? "" : " tun=",
781 opts
->force_tun_device
== -1 ? "" : buf
,
782 opts
->permit_user_rc
? " user-rc" : "",
783 opts
->permit_x11_forwarding_flag
? " x11-forwarding" : "");
785 debug("%s: %s", loc
, msg
);
787 auth_debug_add("%s: %s", loc
, msg
);
789 if (options
.permit_user_env
) {
790 for (i
= 0; i
< opts
->nenv
; i
++) {
791 debug("%s: environment: %s", loc
, opts
->env
[i
]);
793 auth_debug_add("%s: environment: %s",
799 /* Go into a little more details for the local logs. */
800 if (opts
->valid_before
!= 0) {
801 format_absolute_time(opts
->valid_before
, buf
, sizeof(buf
));
802 debug("%s: expires at %s", loc
, buf
);
804 if (opts
->cert_principals
!= NULL
) {
805 debug("%s: authorized principals: \"%s\"",
806 loc
, opts
->cert_principals
);
808 if (opts
->force_command
!= NULL
)
809 debug("%s: forced command: \"%s\"", loc
, opts
->force_command
);
811 for (i
= 0; i
< opts
->npermitopen
; i
++) {
812 debug("%s: permitted open: %s",
813 loc
, opts
->permitopen
[i
]);
816 if (do_permitlisten
) {
817 for (i
= 0; i
< opts
->npermitlisten
; i
++) {
818 debug("%s: permitted listen: %s",
819 loc
, opts
->permitlisten
[i
]);
824 /* Activate a new set of key/cert options; merging with what is there. */
826 auth_activate_options(struct ssh
*ssh
, struct sshauthopt
*opts
)
828 struct sshauthopt
*old
= auth_opts
;
829 const char *emsg
= NULL
;
831 debug_f("setting new authentication options");
832 if ((auth_opts
= sshauthopt_merge(old
, opts
, &emsg
)) == NULL
) {
833 error("Inconsistent authentication options: %s", emsg
);
839 /* Disable forwarding, etc for the session */
841 auth_restrict_session(struct ssh
*ssh
)
843 struct sshauthopt
*restricted
;
845 debug_f("restricting session");
847 /* A blank sshauthopt defaults to permitting nothing */
848 if ((restricted
= sshauthopt_new()) == NULL
)
849 fatal_f("sshauthopt_new failed");
850 restricted
->permit_pty_flag
= 1;
851 restricted
->restricted
= 1;
853 if (auth_activate_options(ssh
, restricted
) != 0)
854 fatal_f("failed to restrict session");
855 sshauthopt_free(restricted
);