Changeset View
Changeset View
Standalone View
Standalone View
auth.c
/* $OpenBSD: auth.c,v 1.138 2019/01/19 21:41:18 djm Exp $ */ | /* $OpenBSD: auth.c,v 1.147 2020/08/27 01:07:09 djm Exp $ */ | ||||
/* | /* | ||||
* Copyright (c) 2000 Markus Friedl. All rights reserved. | * Copyright (c) 2000 Markus Friedl. All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
Show All 17 Lines | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <stdlib.h> | |||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#ifdef HAVE_PATHS_H | #ifdef HAVE_PATHS_H | ||||
# include <paths.h> | # include <paths.h> | ||||
#endif | #endif | ||||
#include <pwd.h> | #include <pwd.h> | ||||
#ifdef HAVE_LOGIN_H | #ifdef HAVE_LOGIN_H | ||||
#include <login.h> | #include <login.h> | ||||
Show All 24 Lines | |||||
#include "uidswap.h" | #include "uidswap.h" | ||||
#include "packet.h" | #include "packet.h" | ||||
#include "loginrec.h" | #include "loginrec.h" | ||||
#ifdef GSSAPI | #ifdef GSSAPI | ||||
#include "ssh-gss.h" | #include "ssh-gss.h" | ||||
#endif | #endif | ||||
#include "authfile.h" | #include "authfile.h" | ||||
#include "monitor_wrap.h" | #include "monitor_wrap.h" | ||||
#include "authfile.h" | |||||
#include "ssherr.h" | #include "ssherr.h" | ||||
#include "compat.h" | #include "compat.h" | ||||
#include "channels.h" | #include "channels.h" | ||||
/* import */ | /* import */ | ||||
extern ServerOptions options; | extern ServerOptions options; | ||||
extern struct include_list includes; | |||||
extern int use_privsep; | extern int use_privsep; | ||||
extern struct sshbuf *loginmsg; | extern struct sshbuf *loginmsg; | ||||
extern struct passwd *privsep_pw; | extern struct passwd *privsep_pw; | ||||
extern struct sshauthopt *auth_opts; | extern struct sshauthopt *auth_opts; | ||||
/* Debugging messages */ | /* Debugging messages */ | ||||
static struct sshbuf *auth_debug; | static struct sshbuf *auth_debug; | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | #endif /* USE_LIBIAF */ | ||||
* Deny if shell does not exist or is not executable unless we | * Deny if shell does not exist or is not executable unless we | ||||
* are chrooting. | * are chrooting. | ||||
*/ | */ | ||||
if (options.chroot_directory == NULL || | if (options.chroot_directory == NULL || | ||||
strcasecmp(options.chroot_directory, "none") == 0) { | strcasecmp(options.chroot_directory, "none") == 0) { | ||||
char *shell = xstrdup((pw->pw_shell[0] == '\0') ? | char *shell = xstrdup((pw->pw_shell[0] == '\0') ? | ||||
_PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ | _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ | ||||
if (stat(shell, &st) != 0) { | if (stat(shell, &st) == -1) { | ||||
logit("User %.100s not allowed because shell %.100s " | logit("User %.100s not allowed because shell %.100s " | ||||
"does not exist", pw->pw_name, shell); | "does not exist", pw->pw_name, shell); | ||||
free(shell); | free(shell); | ||||
return 0; | return 0; | ||||
} | } | ||||
if (S_ISREG(st.st_mode) == 0 || | if (S_ISREG(st.st_mode) == 0 || | ||||
(st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { | (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { | ||||
logit("User %.100s not allowed because shell %.100s " | logit("User %.100s not allowed because shell %.100s " | ||||
▲ Show 20 Lines • Show All 305 Lines • ▼ Show 20 Lines | if (options.strict_modes && | ||||
load_hostkeys(hostkeys, host, user_hostfile); | load_hostkeys(hostkeys, host, user_hostfile); | ||||
restore_uid(); | restore_uid(); | ||||
} | } | ||||
free(user_hostfile); | free(user_hostfile); | ||||
} | } | ||||
host_status = check_key_in_hostkeys(hostkeys, key, &found); | host_status = check_key_in_hostkeys(hostkeys, key, &found); | ||||
if (host_status == HOST_REVOKED) | if (host_status == HOST_REVOKED) | ||||
error("WARNING: revoked key for %s attempted authentication", | error("WARNING: revoked key for %s attempted authentication", | ||||
found->host); | host); | ||||
else if (host_status == HOST_OK) | else if (host_status == HOST_OK) | ||||
debug("%s: key for %s found at %s:%ld", __func__, | debug("%s: key for %s found at %s:%ld", __func__, | ||||
found->host, found->file, found->line); | found->host, found->file, found->line); | ||||
else | else | ||||
debug("%s: key for host %s not found", __func__, host); | debug("%s: key for host %s not found", __func__, host); | ||||
free_hostkeys(hostkeys); | free_hostkeys(hostkeys); | ||||
Show All 11 Lines | auth_openfile(const char *file, struct passwd *pw, int strict_modes, | ||||
if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { | if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { | ||||
if (log_missing || errno != ENOENT) | if (log_missing || errno != ENOENT) | ||||
debug("Could not open %s '%s': %s", file_type, file, | debug("Could not open %s '%s': %s", file_type, file, | ||||
strerror(errno)); | strerror(errno)); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if (fstat(fd, &st) < 0) { | if (fstat(fd, &st) == -1) { | ||||
close(fd); | close(fd); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if (!S_ISREG(st.st_mode)) { | if (!S_ISREG(st.st_mode)) { | ||||
logit("User %s %s %s is not a regular file", | logit("User %s %s %s is not a regular file", | ||||
pw->pw_name, file_type, file); | pw->pw_name, file_type, file); | ||||
close(fd); | close(fd); | ||||
return NULL; | return NULL; | ||||
Show All 37 Lines | #ifdef BSD_AUTH | ||||
auth_session_t *as; | auth_session_t *as; | ||||
#endif | #endif | ||||
#endif | #endif | ||||
struct passwd *pw; | struct passwd *pw; | ||||
struct connection_info *ci; | struct connection_info *ci; | ||||
ci = get_connection_info(ssh, 1, options.use_dns); | ci = get_connection_info(ssh, 1, options.use_dns); | ||||
ci->user = user; | ci->user = user; | ||||
parse_server_match_config(&options, ci); | parse_server_match_config(&options, &includes, ci); | ||||
log_change_level(options.log_level); | log_change_level(options.log_level); | ||||
process_permitopen(ssh, &options); | process_permitopen(ssh, &options); | ||||
#if defined(_AIX) && defined(HAVE_SETAUTHDB) | #if defined(_AIX) && defined(HAVE_SETAUTHDB) | ||||
aix_setauthdb(user); | aix_setauthdb(user); | ||||
#endif | #endif | ||||
pw = getpwnam(user); | pw = getpwnam(user); | ||||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | remote_hostname(struct ssh *ssh) | ||||
struct addrinfo hints, *ai, *aitop; | struct addrinfo hints, *ai, *aitop; | ||||
char name[NI_MAXHOST], ntop2[NI_MAXHOST]; | char name[NI_MAXHOST], ntop2[NI_MAXHOST]; | ||||
const char *ntop = ssh_remote_ipaddr(ssh); | const char *ntop = ssh_remote_ipaddr(ssh); | ||||
/* Get IP address of client. */ | /* Get IP address of client. */ | ||||
fromlen = sizeof(from); | fromlen = sizeof(from); | ||||
memset(&from, 0, sizeof(from)); | memset(&from, 0, sizeof(from)); | ||||
if (getpeername(ssh_packet_get_connection_in(ssh), | if (getpeername(ssh_packet_get_connection_in(ssh), | ||||
(struct sockaddr *)&from, &fromlen) < 0) { | (struct sockaddr *)&from, &fromlen) == -1) { | ||||
debug("getpeername failed: %.100s", strerror(errno)); | debug("getpeername failed: %.100s", strerror(errno)); | ||||
return strdup(ntop); | return xstrdup(ntop); | ||||
} | } | ||||
ipv64_normalise_mapped(&from, &fromlen); | ipv64_normalise_mapped(&from, &fromlen); | ||||
if (from.ss_family == AF_INET6) | if (from.ss_family == AF_INET6) | ||||
fromlen = sizeof(struct sockaddr_in6); | fromlen = sizeof(struct sockaddr_in6); | ||||
debug3("Trying to reverse map address %.100s.", ntop); | debug3("Trying to reverse map address %.100s.", ntop); | ||||
/* Map the IP address to a host name. */ | /* Map the IP address to a host name. */ | ||||
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), | if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), | ||||
NULL, 0, NI_NAMEREQD) != 0) { | NULL, 0, NI_NAMEREQD) != 0) { | ||||
/* Host name not found. Use ip address. */ | /* Host name not found. Use ip address. */ | ||||
return strdup(ntop); | return xstrdup(ntop); | ||||
} | } | ||||
/* | /* | ||||
* if reverse lookup result looks like a numeric hostname, | * if reverse lookup result looks like a numeric hostname, | ||||
* someone is trying to trick us by PTR record like following: | * someone is trying to trick us by PTR record like following: | ||||
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 | * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 | ||||
*/ | */ | ||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | ||||
hints.ai_flags = AI_NUMERICHOST; | hints.ai_flags = AI_NUMERICHOST; | ||||
if (getaddrinfo(name, NULL, &hints, &ai) == 0) { | if (getaddrinfo(name, NULL, &hints, &ai) == 0) { | ||||
logit("Nasty PTR record \"%s\" is set up for %s, ignoring", | logit("Nasty PTR record \"%s\" is set up for %s, ignoring", | ||||
name, ntop); | name, ntop); | ||||
freeaddrinfo(ai); | freeaddrinfo(ai); | ||||
return strdup(ntop); | return xstrdup(ntop); | ||||
} | } | ||||
/* Names are stored in lowercase. */ | /* Names are stored in lowercase. */ | ||||
lowercase(name); | lowercase(name); | ||||
/* | /* | ||||
* Map it back to an IP address and check that the given | * Map it back to an IP address and check that the given | ||||
* address actually is an address of this host. This is | * address actually is an address of this host. This is | ||||
* necessary because anyone with access to a name server can | * necessary because anyone with access to a name server can | ||||
* define arbitrary names for an IP address. Mapping from | * define arbitrary names for an IP address. Mapping from | ||||
* name to IP address can be trusted better (but can still be | * name to IP address can be trusted better (but can still be | ||||
* fooled if the intruder has access to the name server of | * fooled if the intruder has access to the name server of | ||||
* the domain). | * the domain). | ||||
*/ | */ | ||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
hints.ai_family = from.ss_family; | hints.ai_family = from.ss_family; | ||||
hints.ai_socktype = SOCK_STREAM; | hints.ai_socktype = SOCK_STREAM; | ||||
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { | if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { | ||||
logit("reverse mapping checking getaddrinfo for %.700s " | logit("reverse mapping checking getaddrinfo for %.700s " | ||||
"[%s] failed.", name, ntop); | "[%s] failed.", name, ntop); | ||||
return strdup(ntop); | return xstrdup(ntop); | ||||
} | } | ||||
/* Look for the address from the list of addresses. */ | /* Look for the address from the list of addresses. */ | ||||
for (ai = aitop; ai; ai = ai->ai_next) { | for (ai = aitop; ai; ai = ai->ai_next) { | ||||
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, | if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, | ||||
sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && | sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && | ||||
(strcmp(ntop, ntop2) == 0)) | (strcmp(ntop, ntop2) == 0)) | ||||
break; | break; | ||||
} | } | ||||
freeaddrinfo(aitop); | freeaddrinfo(aitop); | ||||
/* If we reached the end of the list, the address was not there. */ | /* If we reached the end of the list, the address was not there. */ | ||||
if (ai == NULL) { | if (ai == NULL) { | ||||
/* Address not found for the host name. */ | /* Address not found for the host name. */ | ||||
logit("Address %.100s maps to %.600s, but this does not " | logit("Address %.100s maps to %.600s, but this does not " | ||||
"map back to the address.", ntop, name); | "map back to the address.", ntop, name); | ||||
return strdup(ntop); | return xstrdup(ntop); | ||||
} | } | ||||
return strdup(name); | return xstrdup(name); | ||||
} | } | ||||
/* | /* | ||||
* Return the canonical name of the host in the other side of the current | * Return the canonical name of the host in the other side of the current | ||||
* connection. The host name is cached, so it is efficient to call this | * connection. The host name is cached, so it is efficient to call this | ||||
* several times. | * several times. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | subprocess(const char *tag, struct passwd *pw, const char *command, | ||||
* If executing an explicit binary, then verify the it exists | * If executing an explicit binary, then verify the it exists | ||||
* and appears safe-ish to execute | * and appears safe-ish to execute | ||||
*/ | */ | ||||
if (!path_absolute(av[0])) { | if (!path_absolute(av[0])) { | ||||
error("%s path is not absolute", tag); | error("%s path is not absolute", tag); | ||||
return 0; | return 0; | ||||
} | } | ||||
temporarily_use_uid(pw); | temporarily_use_uid(pw); | ||||
if (stat(av[0], &st) < 0) { | if (stat(av[0], &st) == -1) { | ||||
error("Could not stat %s \"%s\": %s", tag, | error("Could not stat %s \"%s\": %s", tag, | ||||
av[0], strerror(errno)); | av[0], strerror(errno)); | ||||
restore_uid(); | restore_uid(); | ||||
return 0; | return 0; | ||||
} | } | ||||
if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { | if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { | ||||
error("Unsafe %s \"%s\": %s", tag, av[0], errmsg); | error("Unsafe %s \"%s\": %s", tag, av[0], errmsg); | ||||
restore_uid(); | restore_uid(); | ||||
return 0; | return 0; | ||||
} | } | ||||
/* Prepare to keep the child's stdout if requested */ | /* Prepare to keep the child's stdout if requested */ | ||||
if (pipe(p) != 0) { | if (pipe(p) == -1) { | ||||
error("%s: pipe: %s", tag, strerror(errno)); | error("%s: pipe: %s", tag, strerror(errno)); | ||||
restore_uid(); | restore_uid(); | ||||
return 0; | return 0; | ||||
} | } | ||||
restore_uid(); | restore_uid(); | ||||
switch ((pid = fork())) { | switch ((pid = fork())) { | ||||
case -1: /* error */ | case -1: /* error */ | ||||
error("%s: fork: %s", tag, strerror(errno)); | error("%s: fork: %s", tag, strerror(errno)); | ||||
close(p[0]); | close(p[0]); | ||||
close(p[1]); | close(p[1]); | ||||
return 0; | return 0; | ||||
case 0: /* child */ | case 0: /* child */ | ||||
/* Prepare a minimal environment for the child. */ | /* Prepare a minimal environment for the child. */ | ||||
envsize = 5; | envsize = 5; | ||||
child_env = xcalloc(sizeof(*child_env), envsize); | child_env = xcalloc(sizeof(*child_env), envsize); | ||||
child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH); | child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH); | ||||
child_set_env(&child_env, &envsize, "USER", pw->pw_name); | child_set_env(&child_env, &envsize, "USER", pw->pw_name); | ||||
child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name); | child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name); | ||||
child_set_env(&child_env, &envsize, "HOME", pw->pw_dir); | child_set_env(&child_env, &envsize, "HOME", pw->pw_dir); | ||||
if ((cp = getenv("LANG")) != NULL) | if ((cp = getenv("LANG")) != NULL) | ||||
child_set_env(&child_env, &envsize, "LANG", cp); | child_set_env(&child_env, &envsize, "LANG", cp); | ||||
for (i = 0; i < NSIG; i++) | for (i = 0; i < NSIG; i++) | ||||
signal(i, SIG_DFL); | ssh_signal(i, SIG_DFL); | ||||
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { | if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { | ||||
error("%s: open %s: %s", tag, _PATH_DEVNULL, | error("%s: open %s: %s", tag, _PATH_DEVNULL, | ||||
strerror(errno)); | strerror(errno)); | ||||
_exit(1); | _exit(1); | ||||
} | } | ||||
if (dup2(devnull, STDIN_FILENO) == -1) { | if (dup2(devnull, STDIN_FILENO) == -1) { | ||||
error("%s: dup2: %s", tag, strerror(errno)); | error("%s: dup2: %s", tag, strerror(errno)); | ||||
_exit(1); | _exit(1); | ||||
} | } | ||||
/* Set up stdout as requested; leave stderr in place for now. */ | /* Set up stdout as requested; leave stderr in place for now. */ | ||||
fd = -1; | fd = -1; | ||||
if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) | if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) | ||||
fd = p[1]; | fd = p[1]; | ||||
else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0) | else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0) | ||||
fd = devnull; | fd = devnull; | ||||
if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) { | if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) { | ||||
error("%s: dup2: %s", tag, strerror(errno)); | error("%s: dup2: %s", tag, strerror(errno)); | ||||
_exit(1); | _exit(1); | ||||
} | } | ||||
closefrom(STDERR_FILENO + 1); | closefrom(STDERR_FILENO + 1); | ||||
/* Don't use permanently_set_uid() here to avoid fatal() */ | /* Don't use permanently_set_uid() here to avoid fatal() */ | ||||
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { | if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { | ||||
error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, | error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, | ||||
strerror(errno)); | strerror(errno)); | ||||
_exit(1); | _exit(1); | ||||
} | } | ||||
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) { | if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) { | ||||
error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid, | error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid, | ||||
strerror(errno)); | strerror(errno)); | ||||
_exit(1); | _exit(1); | ||||
} | } | ||||
/* stdin is pointed to /dev/null at this point */ | /* stdin is pointed to /dev/null at this point */ | ||||
if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && | if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && | ||||
dup2(STDIN_FILENO, STDERR_FILENO) == -1) { | dup2(STDIN_FILENO, STDERR_FILENO) == -1) { | ||||
error("%s: dup2: %s", tag, strerror(errno)); | error("%s: dup2: %s", tag, strerror(errno)); | ||||
Show All 37 Lines | int do_permitopen = opts->npermitopen > 0 && | ||||
(options.allow_tcp_forwarding & FORWARD_LOCAL) != 0; | (options.allow_tcp_forwarding & FORWARD_LOCAL) != 0; | ||||
int do_permitlisten = opts->npermitlisten > 0 && | int do_permitlisten = opts->npermitlisten > 0 && | ||||
(options.allow_tcp_forwarding & FORWARD_REMOTE) != 0; | (options.allow_tcp_forwarding & FORWARD_REMOTE) != 0; | ||||
size_t i; | size_t i; | ||||
char msg[1024], buf[64]; | char msg[1024], buf[64]; | ||||
snprintf(buf, sizeof(buf), "%d", opts->force_tun_device); | snprintf(buf, sizeof(buf), "%d", opts->force_tun_device); | ||||
/* Try to keep this alphabetically sorted */ | /* Try to keep this alphabetically sorted */ | ||||
snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s", | snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", | ||||
opts->permit_agent_forwarding_flag ? " agent-forwarding" : "", | opts->permit_agent_forwarding_flag ? " agent-forwarding" : "", | ||||
opts->force_command == NULL ? "" : " command", | opts->force_command == NULL ? "" : " command", | ||||
do_env ? " environment" : "", | do_env ? " environment" : "", | ||||
opts->valid_before == 0 ? "" : "expires", | opts->valid_before == 0 ? "" : "expires", | ||||
opts->no_require_user_presence ? " no-touch-required" : "", | |||||
do_permitopen ? " permitopen" : "", | do_permitopen ? " permitopen" : "", | ||||
do_permitlisten ? " permitlisten" : "", | do_permitlisten ? " permitlisten" : "", | ||||
opts->permit_port_forwarding_flag ? " port-forwarding" : "", | opts->permit_port_forwarding_flag ? " port-forwarding" : "", | ||||
opts->cert_principals == NULL ? "" : " principals", | opts->cert_principals == NULL ? "" : " principals", | ||||
opts->permit_pty_flag ? " pty" : "", | opts->permit_pty_flag ? " pty" : "", | ||||
opts->require_verify ? " uv" : "", | |||||
opts->force_tun_device == -1 ? "" : " tun=", | opts->force_tun_device == -1 ? "" : " tun=", | ||||
opts->force_tun_device == -1 ? "" : buf, | opts->force_tun_device == -1 ? "" : buf, | ||||
opts->permit_user_rc ? " user-rc" : "", | opts->permit_user_rc ? " user-rc" : "", | ||||
opts->permit_x11_forwarding_flag ? " x11-forwarding" : ""); | opts->permit_x11_forwarding_flag ? " x11-forwarding" : ""); | ||||
debug("%s: %s", loc, msg); | debug("%s: %s", loc, msg); | ||||
if (do_remote) | if (do_remote) | ||||
auth_debug_add("%s: %s", loc, msg); | auth_debug_add("%s: %s", loc, msg); | ||||
▲ Show 20 Lines • Show All 163 Lines • Show Last 20 Lines |