1 /* $OpenBSD: auth.c,v 1.158 2022/06/03 04:47:21 djm 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"
81 extern ServerOptions options
;
82 extern struct include_list includes
;
83 extern int use_privsep
;
84 extern struct sshbuf
*loginmsg
;
85 extern struct passwd
*privsep_pw
;
86 extern struct sshauthopt
*auth_opts
;
88 /* Debugging messages */
89 static struct sshbuf
*auth_debug
;
92 * Check if the user is allowed to log in via ssh. If user is listed
93 * in DenyUsers or one of user's groups is listed in DenyGroups, false
94 * will be returned. If AllowUsers isn't empty and user isn't listed
95 * there, or if AllowGroups isn't empty and one of user's groups isn't
96 * listed there, false will be returned.
97 * If the user's shell is not executable, false will be returned.
98 * Otherwise true is returned.
101 allowed_user(struct ssh
*ssh
, struct passwd
* pw
)
104 const char *hostname
= NULL
, *ipaddr
= NULL
;
108 /* Shouldn't be called if pw is NULL, but better safe than sorry... */
109 if (!pw
|| !pw
->pw_name
)
112 if (!options
.use_pam
&& platform_locked_account(pw
)) {
113 logit("User %.100s not allowed because account is locked",
119 * Deny if shell does not exist or is not executable unless we
122 if (options
.chroot_directory
== NULL
||
123 strcasecmp(options
.chroot_directory
, "none") == 0) {
124 char *shell
= xstrdup((pw
->pw_shell
[0] == '\0') ?
125 _PATH_BSHELL
: pw
->pw_shell
); /* empty = /bin/sh */
127 if (stat(shell
, &st
) == -1) {
128 logit("User %.100s not allowed because shell %.100s "
129 "does not exist", pw
->pw_name
, shell
);
133 if (S_ISREG(st
.st_mode
) == 0 ||
134 (st
.st_mode
& (S_IXOTH
|S_IXUSR
|S_IXGRP
)) == 0) {
135 logit("User %.100s not allowed because shell %.100s "
136 "is not executable", pw
->pw_name
, shell
);
143 if (options
.num_deny_users
> 0 || options
.num_allow_users
> 0 ||
144 options
.num_deny_groups
> 0 || options
.num_allow_groups
> 0) {
145 hostname
= auth_get_canonical_hostname(ssh
, options
.use_dns
);
146 ipaddr
= ssh_remote_ipaddr(ssh
);
149 /* Return false if user is listed in DenyUsers */
150 if (options
.num_deny_users
> 0) {
151 for (i
= 0; i
< options
.num_deny_users
; i
++) {
152 r
= match_user(pw
->pw_name
, hostname
, ipaddr
,
153 options
.deny_users
[i
]);
155 fatal("Invalid DenyUsers pattern \"%.100s\"",
156 options
.deny_users
[i
]);
158 logit("User %.100s from %.100s not allowed "
159 "because listed in DenyUsers",
160 pw
->pw_name
, hostname
);
165 /* Return false if AllowUsers isn't empty and user isn't listed there */
166 if (options
.num_allow_users
> 0) {
167 for (i
= 0; i
< options
.num_allow_users
; i
++) {
168 r
= match_user(pw
->pw_name
, hostname
, ipaddr
,
169 options
.allow_users
[i
]);
171 fatal("Invalid AllowUsers pattern \"%.100s\"",
172 options
.allow_users
[i
]);
176 /* i < options.num_allow_users iff we break for loop */
177 if (i
>= options
.num_allow_users
) {
178 logit("User %.100s from %.100s not allowed because "
179 "not listed in AllowUsers", pw
->pw_name
, hostname
);
183 if (options
.num_deny_groups
> 0 || options
.num_allow_groups
> 0) {
184 /* Get the user's group access list (primary and supplementary) */
185 if (ga_init(pw
->pw_name
, pw
->pw_gid
) == 0) {
186 logit("User %.100s from %.100s not allowed because "
187 "not in any group", pw
->pw_name
, hostname
);
191 /* Return false if one of user's groups is listed in DenyGroups */
192 if (options
.num_deny_groups
> 0)
193 if (ga_match(options
.deny_groups
,
194 options
.num_deny_groups
)) {
196 logit("User %.100s from %.100s not allowed "
197 "because a group is listed in DenyGroups",
198 pw
->pw_name
, hostname
);
202 * Return false if AllowGroups isn't empty and one of user's groups
205 if (options
.num_allow_groups
> 0)
206 if (!ga_match(options
.allow_groups
,
207 options
.num_allow_groups
)) {
209 logit("User %.100s from %.100s not allowed "
210 "because none of user's groups are listed "
211 "in AllowGroups", pw
->pw_name
, hostname
);
217 #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
218 if (!sys_auth_allowed_user(pw
, loginmsg
))
222 /* We found no reason not to let this user try to log on... */
227 * Formats any key left in authctxt->auth_method_key for inclusion in
228 * auth_log()'s message. Also includes authxtct->auth_method_info if present.
231 format_method_key(Authctxt
*authctxt
)
233 const struct sshkey
*key
= authctxt
->auth_method_key
;
234 const char *methinfo
= authctxt
->auth_method_info
;
235 char *fp
, *cafp
, *ret
= NULL
;
240 if (sshkey_is_cert(key
)) {
241 fp
= sshkey_fingerprint(key
,
242 options
.fingerprint_hash
, SSH_FP_DEFAULT
);
243 cafp
= sshkey_fingerprint(key
->cert
->signature_key
,
244 options
.fingerprint_hash
, SSH_FP_DEFAULT
);
245 xasprintf(&ret
, "%s %s ID %s (serial %llu) CA %s %s%s%s",
246 sshkey_type(key
), fp
== NULL
? "(null)" : fp
,
248 (unsigned long long)key
->cert
->serial
,
249 sshkey_type(key
->cert
->signature_key
),
250 cafp
== NULL
? "(null)" : cafp
,
251 methinfo
== NULL
? "" : ", ",
252 methinfo
== NULL
? "" : methinfo
);
256 fp
= sshkey_fingerprint(key
, options
.fingerprint_hash
,
258 xasprintf(&ret
, "%s %s%s%s", sshkey_type(key
),
259 fp
== NULL
? "(null)" : fp
,
260 methinfo
== NULL
? "" : ", ",
261 methinfo
== NULL
? "" : methinfo
);
268 auth_log(struct ssh
*ssh
, int authenticated
, int partial
,
269 const char *method
, const char *submethod
)
271 Authctxt
*authctxt
= (Authctxt
*)ssh
->authctxt
;
272 int level
= SYSLOG_LEVEL_VERBOSE
;
276 if (use_privsep
&& !mm_is_monitor() && !authctxt
->postponed
)
279 /* Raise logging level */
280 if (authenticated
== 1 ||
282 authctxt
->failures
>= options
.max_authtries
/ 2 ||
283 strcmp(method
, "password") == 0)
284 level
= SYSLOG_LEVEL_INFO
;
286 if (authctxt
->postponed
)
287 authmsg
= "Postponed";
291 authmsg
= authenticated
? "Accepted" : "Failed";
293 if ((extra
= format_method_key(authctxt
)) == NULL
) {
294 if (authctxt
->auth_method_info
!= NULL
)
295 extra
= xstrdup(authctxt
->auth_method_info
);
298 do_log2(level
, "%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
301 submethod
!= NULL
? "/" : "", submethod
== NULL
? "" : submethod
,
302 authctxt
->valid
? "" : "invalid user ",
304 ssh_remote_ipaddr(ssh
),
305 ssh_remote_port(ssh
),
306 extra
!= NULL
? ": " : "",
307 extra
!= NULL
? extra
: "");
311 #if defined(CUSTOM_FAILED_LOGIN) || defined(SSH_AUDIT_EVENTS)
312 if (authenticated
== 0 && !(authctxt
->postponed
|| partial
)) {
313 /* Log failed login attempt */
314 # ifdef CUSTOM_FAILED_LOGIN
315 if (strcmp(method
, "password") == 0 ||
316 strncmp(method
, "keyboard-interactive", 20) == 0 ||
317 strcmp(method
, "challenge-response") == 0)
318 record_failed_login(ssh
, authctxt
->user
,
319 auth_get_canonical_hostname(ssh
, options
.use_dns
), "ssh");
321 # ifdef SSH_AUDIT_EVENTS
322 audit_event(ssh
, audit_classify_auth(method
));
326 #if defined(CUSTOM_FAILED_LOGIN) && defined(WITH_AIXAUTHENTICATE)
328 sys_auth_record_login(authctxt
->user
,
329 auth_get_canonical_hostname(ssh
, options
.use_dns
), "ssh",
335 auth_maxtries_exceeded(struct ssh
*ssh
)
337 Authctxt
*authctxt
= (Authctxt
*)ssh
->authctxt
;
339 error("maximum authentication attempts exceeded for "
340 "%s%.100s from %.200s port %d ssh2",
341 authctxt
->valid
? "" : "invalid user ",
343 ssh_remote_ipaddr(ssh
),
344 ssh_remote_port(ssh
));
345 ssh_packet_disconnect(ssh
, "Too many authentication failures");
350 * Check whether root logins are disallowed.
353 auth_root_allowed(struct ssh
*ssh
, const char *method
)
355 switch (options
.permit_root_login
) {
358 case PERMIT_NO_PASSWD
:
359 if (strcmp(method
, "publickey") == 0 ||
360 strcmp(method
, "hostbased") == 0 ||
361 strcmp(method
, "gssapi-with-mic") == 0)
364 case PERMIT_FORCED_ONLY
:
365 if (auth_opts
->force_command
!= NULL
) {
366 logit("Root login accepted for forced command.");
371 logit("ROOT LOGIN REFUSED FROM %.200s port %d",
372 ssh_remote_ipaddr(ssh
), ssh_remote_port(ssh
));
378 * Given a template and a passwd structure, build a filename
379 * by substituting % tokenised options. Currently, %% becomes '%',
380 * %h becomes the home directory and %u the username.
382 * This returns a buffer allocated by xmalloc.
385 expand_authorized_keys(const char *filename
, struct passwd
*pw
)
387 char *file
, uidstr
[32], ret
[PATH_MAX
];
390 snprintf(uidstr
, sizeof(uidstr
), "%llu",
391 (unsigned long long)pw
->pw_uid
);
392 file
= percent_expand(filename
, "h", pw
->pw_dir
,
393 "u", pw
->pw_name
, "U", uidstr
, (char *)NULL
);
396 * Ensure that filename starts anchored. If not, be backward
397 * compatible and prepend the '%h/'
399 if (path_absolute(file
))
402 i
= snprintf(ret
, sizeof(ret
), "%s/%s", pw
->pw_dir
, file
);
403 if (i
< 0 || (size_t)i
>= sizeof(ret
))
404 fatal("expand_authorized_keys: path too long");
406 return (xstrdup(ret
));
410 authorized_principals_file(struct passwd
*pw
)
412 if (options
.authorized_principals_file
== NULL
)
414 return expand_authorized_keys(options
.authorized_principals_file
, pw
);
417 /* return ok if key exists in sysfile or userfile */
419 check_key_in_hostfiles(struct passwd
*pw
, struct sshkey
*key
, const char *host
,
420 const char *sysfile
, const char *userfile
)
424 HostStatus host_status
;
425 struct hostkeys
*hostkeys
;
426 const struct hostkey_entry
*found
;
428 hostkeys
= init_hostkeys();
429 load_hostkeys(hostkeys
, host
, sysfile
, 0);
430 if (userfile
!= NULL
) {
431 user_hostfile
= tilde_expand_filename(userfile
, pw
->pw_uid
);
432 if (options
.strict_modes
&&
433 (stat(user_hostfile
, &st
) == 0) &&
434 ((st
.st_uid
!= 0 && st
.st_uid
!= pw
->pw_uid
) ||
435 (st
.st_mode
& 022) != 0)) {
436 logit("Authentication refused for %.100s: "
437 "bad owner or modes for %.200s",
438 pw
->pw_name
, user_hostfile
);
439 auth_debug_add("Ignored %.200s: bad ownership or modes",
442 temporarily_use_uid(pw
);
443 load_hostkeys(hostkeys
, host
, user_hostfile
, 0);
448 host_status
= check_key_in_hostkeys(hostkeys
, key
, &found
);
449 if (host_status
== HOST_REVOKED
)
450 error("WARNING: revoked key for %s attempted authentication",
452 else if (host_status
== HOST_OK
)
453 debug_f("key for %s found at %s:%ld",
454 found
->host
, found
->file
, found
->line
);
456 debug_f("key for host %s not found", host
);
458 free_hostkeys(hostkeys
);
464 getpwnamallow(struct ssh
*ssh
, const char *user
)
466 #ifdef HAVE_LOGIN_CAP
467 extern login_cap_t
*lc
;
473 struct connection_info
*ci
;
476 ci
= get_connection_info(ssh
, 1, options
.use_dns
);
478 parse_server_match_config(&options
, &includes
, ci
);
479 log_change_level(options
.log_level
);
481 for (i
= 0; i
< options
.num_log_verbose
; i
++)
482 log_verbose_add(options
.log_verbose
[i
]);
483 process_permitopen(ssh
, &options
);
485 #if defined(_AIX) && defined(HAVE_SETAUTHDB)
491 #if defined(_AIX) && defined(HAVE_SETAUTHDB)
495 logit("Invalid user %.100s from %.100s port %d",
496 user
, ssh_remote_ipaddr(ssh
), ssh_remote_port(ssh
));
497 #ifdef CUSTOM_FAILED_LOGIN
498 record_failed_login(ssh
, user
,
499 auth_get_canonical_hostname(ssh
, options
.use_dns
), "ssh");
501 #ifdef SSH_AUDIT_EVENTS
502 audit_event(ssh
, SSH_INVALID_USER
);
503 #endif /* SSH_AUDIT_EVENTS */
506 if (!allowed_user(ssh
, pw
))
508 #ifdef HAVE_LOGIN_CAP
509 if ((lc
= login_getpwclass(pw
)) == NULL
) {
510 debug("unable to get login class: %s", user
);
514 if ((as
= auth_open()) == NULL
|| auth_setpwd(as
, pw
) != 0 ||
515 auth_approval(as
, lc
, pw
->pw_name
, "ssh") <= 0) {
516 debug("Approval failure for %s", user
);
528 /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
530 auth_key_is_revoked(struct sshkey
*key
)
535 if (options
.revoked_keys_file
== NULL
)
537 if ((fp
= sshkey_fingerprint(key
, options
.fingerprint_hash
,
538 SSH_FP_DEFAULT
)) == NULL
) {
539 r
= SSH_ERR_ALLOC_FAIL
;
540 error_fr(r
, "fingerprint key");
544 r
= sshkey_check_revoked(key
, options
.revoked_keys_file
);
547 break; /* not revoked */
548 case SSH_ERR_KEY_REVOKED
:
549 error("Authentication key %s %s revoked by file %s",
550 sshkey_type(key
), fp
, options
.revoked_keys_file
);
553 error_r(r
, "Error checking authentication key %s %s in "
554 "revoked keys file %s", sshkey_type(key
), fp
,
555 options
.revoked_keys_file
);
564 return r
== 0 ? 0 : 1;
568 auth_debug_add(const char *fmt
,...)
574 if (auth_debug
== NULL
)
578 vsnprintf(buf
, sizeof(buf
), fmt
, args
);
580 if ((r
= sshbuf_put_cstring(auth_debug
, buf
)) != 0)
581 fatal_fr(r
, "sshbuf_put_cstring");
585 auth_debug_send(struct ssh
*ssh
)
590 if (auth_debug
== NULL
)
592 while (sshbuf_len(auth_debug
) != 0) {
593 if ((r
= sshbuf_get_cstring(auth_debug
, &msg
, NULL
)) != 0)
594 fatal_fr(r
, "sshbuf_get_cstring");
595 ssh_packet_send_debug(ssh
, "%s", msg
);
601 auth_debug_reset(void)
603 if (auth_debug
!= NULL
)
604 sshbuf_reset(auth_debug
);
605 else if ((auth_debug
= sshbuf_new()) == NULL
)
606 fatal_f("sshbuf_new failed");
613 static struct passwd fake
;
614 const char hashchars
[] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZ"
615 "abcdefghijklmnopqrstuvwxyz0123456789"; /* from bcrypt.c */
621 memset(&fake
, 0, sizeof(fake
));
622 fake
.pw_name
= "NOUSER";
623 fake
.pw_passwd
= xstrdup("$2a$10$"
624 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
625 for (cp
= fake
.pw_passwd
+ 7; *cp
!= '\0'; cp
++)
626 *cp
= hashchars
[arc4random_uniform(sizeof(hashchars
) - 1)];
627 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
628 fake
.pw_gecos
= "NOUSER";
630 fake
.pw_uid
= privsep_pw
== NULL
? (uid_t
)-1 : privsep_pw
->pw_uid
;
631 fake
.pw_gid
= privsep_pw
== NULL
? (gid_t
)-1 : privsep_pw
->pw_gid
;
632 #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
635 fake
.pw_dir
= "/nonexist";
636 fake
.pw_shell
= "/nonexist";
643 * Returns the remote DNS hostname as a string. The returned string must not
644 * be freed. NB. this will usually trigger a DNS query the first time it is
646 * This function does additional checks on the hostname to mitigate some
647 * attacks on based on conflation of hostnames and IP addresses.
651 remote_hostname(struct ssh
*ssh
)
653 struct sockaddr_storage from
;
655 struct addrinfo hints
, *ai
, *aitop
;
656 char name
[NI_MAXHOST
], ntop2
[NI_MAXHOST
];
657 const char *ntop
= ssh_remote_ipaddr(ssh
);
659 /* Get IP address of client. */
660 fromlen
= sizeof(from
);
661 memset(&from
, 0, sizeof(from
));
662 if (getpeername(ssh_packet_get_connection_in(ssh
),
663 (struct sockaddr
*)&from
, &fromlen
) == -1) {
664 debug("getpeername failed: %.100s", strerror(errno
));
665 return xstrdup(ntop
);
668 ipv64_normalise_mapped(&from
, &fromlen
);
669 if (from
.ss_family
== AF_INET6
)
670 fromlen
= sizeof(struct sockaddr_in6
);
672 debug3("Trying to reverse map address %.100s.", ntop
);
673 /* Map the IP address to a host name. */
674 if (getnameinfo((struct sockaddr
*)&from
, fromlen
, name
, sizeof(name
),
675 NULL
, 0, NI_NAMEREQD
) != 0) {
676 /* Host name not found. Use ip address. */
677 return xstrdup(ntop
);
681 * if reverse lookup result looks like a numeric hostname,
682 * someone is trying to trick us by PTR record like following:
683 * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
685 memset(&hints
, 0, sizeof(hints
));
686 hints
.ai_socktype
= SOCK_DGRAM
; /*dummy*/
687 hints
.ai_flags
= AI_NUMERICHOST
;
688 if (getaddrinfo(name
, NULL
, &hints
, &ai
) == 0) {
689 logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
692 return xstrdup(ntop
);
695 /* Names are stored in lowercase. */
699 * Map it back to an IP address and check that the given
700 * address actually is an address of this host. This is
701 * necessary because anyone with access to a name server can
702 * define arbitrary names for an IP address. Mapping from
703 * name to IP address can be trusted better (but can still be
704 * fooled if the intruder has access to the name server of
707 memset(&hints
, 0, sizeof(hints
));
708 hints
.ai_family
= from
.ss_family
;
709 hints
.ai_socktype
= SOCK_STREAM
;
710 if (getaddrinfo(name
, NULL
, &hints
, &aitop
) != 0) {
711 logit("reverse mapping checking getaddrinfo for %.700s "
712 "[%s] failed.", name
, ntop
);
713 return xstrdup(ntop
);
715 /* Look for the address from the list of addresses. */
716 for (ai
= aitop
; ai
; ai
= ai
->ai_next
) {
717 if (getnameinfo(ai
->ai_addr
, ai
->ai_addrlen
, ntop2
,
718 sizeof(ntop2
), NULL
, 0, NI_NUMERICHOST
) == 0 &&
719 (strcmp(ntop
, ntop2
) == 0))
723 /* If we reached the end of the list, the address was not there. */
725 /* Address not found for the host name. */
726 logit("Address %.100s maps to %.600s, but this does not "
727 "map back to the address.", ntop
, name
);
728 return xstrdup(ntop
);
730 return xstrdup(name
);
734 * Return the canonical name of the host in the other side of the current
735 * connection. The host name is cached, so it is efficient to call this
740 auth_get_canonical_hostname(struct ssh
*ssh
, int use_dns
)
742 static char *dnsname
;
745 return ssh_remote_ipaddr(ssh
);
746 else if (dnsname
!= NULL
)
749 dnsname
= remote_hostname(ssh
);
754 /* These functions link key/cert options to the auth framework */
756 /* Log sshauthopt options locally and (optionally) for remote transmission */
758 auth_log_authopts(const char *loc
, const struct sshauthopt
*opts
, int do_remote
)
760 int do_env
= options
.permit_user_env
&& opts
->nenv
> 0;
761 int do_permitopen
= opts
->npermitopen
> 0 &&
762 (options
.allow_tcp_forwarding
& FORWARD_LOCAL
) != 0;
763 int do_permitlisten
= opts
->npermitlisten
> 0 &&
764 (options
.allow_tcp_forwarding
& FORWARD_REMOTE
) != 0;
766 char msg
[1024], buf
[64];
768 snprintf(buf
, sizeof(buf
), "%d", opts
->force_tun_device
);
769 /* Try to keep this alphabetically sorted */
770 snprintf(msg
, sizeof(msg
), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
771 opts
->permit_agent_forwarding_flag
? " agent-forwarding" : "",
772 opts
->force_command
== NULL
? "" : " command",
773 do_env
? " environment" : "",
774 opts
->valid_before
== 0 ? "" : "expires",
775 opts
->no_require_user_presence
? " no-touch-required" : "",
776 do_permitopen
? " permitopen" : "",
777 do_permitlisten
? " permitlisten" : "",
778 opts
->permit_port_forwarding_flag
? " port-forwarding" : "",
779 opts
->cert_principals
== NULL
? "" : " principals",
780 opts
->permit_pty_flag
? " pty" : "",
781 opts
->require_verify
? " uv" : "",
782 opts
->force_tun_device
== -1 ? "" : " tun=",
783 opts
->force_tun_device
== -1 ? "" : buf
,
784 opts
->permit_user_rc
? " user-rc" : "",
785 opts
->permit_x11_forwarding_flag
? " x11-forwarding" : "");
787 debug("%s: %s", loc
, msg
);
789 auth_debug_add("%s: %s", loc
, msg
);
791 if (options
.permit_user_env
) {
792 for (i
= 0; i
< opts
->nenv
; i
++) {
793 debug("%s: environment: %s", loc
, opts
->env
[i
]);
795 auth_debug_add("%s: environment: %s",
801 /* Go into a little more details for the local logs. */
802 if (opts
->valid_before
!= 0) {
803 format_absolute_time(opts
->valid_before
, buf
, sizeof(buf
));
804 debug("%s: expires at %s", loc
, buf
);
806 if (opts
->cert_principals
!= NULL
) {
807 debug("%s: authorized principals: \"%s\"",
808 loc
, opts
->cert_principals
);
810 if (opts
->force_command
!= NULL
)
811 debug("%s: forced command: \"%s\"", loc
, opts
->force_command
);
813 for (i
= 0; i
< opts
->npermitopen
; i
++) {
814 debug("%s: permitted open: %s",
815 loc
, opts
->permitopen
[i
]);
818 if (do_permitlisten
) {
819 for (i
= 0; i
< opts
->npermitlisten
; i
++) {
820 debug("%s: permitted listen: %s",
821 loc
, opts
->permitlisten
[i
]);
826 /* Activate a new set of key/cert options; merging with what is there. */
828 auth_activate_options(struct ssh
*ssh
, struct sshauthopt
*opts
)
830 struct sshauthopt
*old
= auth_opts
;
831 const char *emsg
= NULL
;
833 debug_f("setting new authentication options");
834 if ((auth_opts
= sshauthopt_merge(old
, opts
, &emsg
)) == NULL
) {
835 error("Inconsistent authentication options: %s", emsg
);
841 /* Disable forwarding, etc for the session */
843 auth_restrict_session(struct ssh
*ssh
)
845 struct sshauthopt
*restricted
;
847 debug_f("restricting session");
849 /* A blank sshauthopt defaults to permitting nothing */
850 if ((restricted
= sshauthopt_new()) == NULL
)
851 fatal_f("sshauthopt_new failed");
852 restricted
->permit_pty_flag
= 1;
853 restricted
->restricted
= 1;
855 if (auth_activate_options(ssh
, restricted
) != 0)
856 fatal_f("failed to restrict session");
857 sshauthopt_free(restricted
);