Changeset View
Changeset View
Standalone View
Standalone View
crypto/openssh/sshd.c
Show First 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | |||||
#include "sk-api.h" | #include "sk-api.h" | ||||
#include "srclimit.h" | #include "srclimit.h" | ||||
#include "dh.h" | #include "dh.h" | ||||
#include "blacklist_client.h" | #include "blacklist_client.h" | ||||
#ifdef LIBWRAP | #ifdef LIBWRAP | ||||
#include <tcpd.h> | #include <tcpd.h> | ||||
#include <syslog.h> | #include <syslog.h> | ||||
int allow_severity; | extern int allow_severity; | ||||
int deny_severity; | extern int deny_severity; | ||||
#endif /* LIBWRAP */ | #endif /* LIBWRAP */ | ||||
/* Re-exec fds */ | /* Re-exec fds */ | ||||
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | ||||
#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | ||||
#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) | #define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) | ||||
#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) | #define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) | ||||
▲ Show 20 Lines • Show All 1,010 Lines • ▼ Show 20 Lines | server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | ||||
int ostartups = -1, startups = 0, listening = 0, lameduck = 0; | int ostartups = -1, startups = 0, listening = 0, lameduck = 0; | ||||
int startup_p[2] = { -1 , -1 }; | int startup_p[2] = { -1 , -1 }; | ||||
char c = 0; | char c = 0; | ||||
struct sockaddr_storage from; | struct sockaddr_storage from; | ||||
socklen_t fromlen; | socklen_t fromlen; | ||||
pid_t pid; | pid_t pid; | ||||
u_char rnd[256]; | u_char rnd[256]; | ||||
sigset_t nsigset, osigset; | sigset_t nsigset, osigset; | ||||
#ifdef LIBWRAP | |||||
struct request_info req; | |||||
request_init(&req, RQ_DAEMON, __progname, 0); | |||||
#endif | |||||
/* setup fd set for accept */ | /* setup fd set for accept */ | ||||
fdset = NULL; | fdset = NULL; | ||||
maxfd = 0; | maxfd = 0; | ||||
for (i = 0; i < num_listen_socks; i++) | for (i = 0; i < num_listen_socks; i++) | ||||
if (listen_socks[i] > maxfd) | if (listen_socks[i] > maxfd) | ||||
maxfd = listen_socks[i]; | maxfd = listen_socks[i]; | ||||
/* pipes connected to unauthenticated child sshd processes */ | /* pipes connected to unauthenticated child sshd processes */ | ||||
startup_pipes = xcalloc(options.max_startups, sizeof(int)); | startup_pipes = xcalloc(options.max_startups, sizeof(int)); | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | for (i = 0; i < num_listen_socks; i++) { | ||||
if (errno != EINTR && errno != EWOULDBLOCK && | if (errno != EINTR && errno != EWOULDBLOCK && | ||||
errno != ECONNABORTED && errno != EAGAIN) | errno != ECONNABORTED && errno != EAGAIN) | ||||
error("accept: %.100s", | error("accept: %.100s", | ||||
strerror(errno)); | strerror(errno)); | ||||
if (errno == EMFILE || errno == ENFILE) | if (errno == EMFILE || errno == ENFILE) | ||||
usleep(100 * 1000); | usleep(100 * 1000); | ||||
continue; | continue; | ||||
} | } | ||||
#ifdef LIBWRAP | |||||
/* Check whether logins are denied from this host. */ | |||||
request_set(&req, RQ_FILE, *newsock, | |||||
RQ_CLIENT_NAME, "", RQ_CLIENT_ADDR, "", 0); | |||||
sock_host(&req); | |||||
if (!hosts_access(&req)) { | |||||
const struct linger l = { .l_onoff = 1, | |||||
.l_linger = 0 }; | |||||
(void )setsockopt(*newsock, SOL_SOCKET, | |||||
SO_LINGER, &l, sizeof(l)); | |||||
(void )close(*newsock); | |||||
/* | |||||
* Mimic message from libwrap's refuse() | |||||
* exactly. sshguard, and supposedly lots | |||||
* of custom made scripts rely on it. | |||||
*/ | |||||
syslog(deny_severity, | |||||
"refused connect from %s (%s)", | |||||
eval_client(&req), | |||||
eval_hostaddr(req.client)); | |||||
debug("Connection refused by tcp wrapper"); | |||||
continue; | |||||
} | |||||
#endif /* LIBWRAP */ | |||||
if (unset_nonblock(*newsock) == -1 || | if (unset_nonblock(*newsock) == -1 || | ||||
pipe(startup_p) == -1) | pipe(startup_p) == -1) | ||||
continue; | continue; | ||||
if (drop_connection(*newsock, startups, startup_p[0])) { | if (drop_connection(*newsock, startups, startup_p[0])) { | ||||
close(*newsock); | close(*newsock); | ||||
close(startup_p[0]); | close(startup_p[0]); | ||||
close(startup_p[1]); | close(startup_p[1]); | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 753 Lines • ▼ Show 20 Lines | if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) { | ||||
if (daemon(0, 0) == -1) | if (daemon(0, 0) == -1) | ||||
fatal("daemon() failed: %.200s", strerror(errno)); | fatal("daemon() failed: %.200s", strerror(errno)); | ||||
disconnect_controlling_tty(); | disconnect_controlling_tty(); | ||||
} | } | ||||
/* Reinitialize the log (because of the fork above). */ | /* Reinitialize the log (because of the fork above). */ | ||||
log_init(__progname, options.log_level, options.log_facility, log_stderr); | log_init(__progname, options.log_level, options.log_facility, log_stderr); | ||||
#ifdef LIBWRAP | |||||
/* | |||||
* We log refusals ourselves. However, libwrap will report | |||||
* syntax errors in hosts.allow via syslog(3). | |||||
*/ | |||||
allow_severity = options.log_facility|LOG_INFO; | |||||
deny_severity = options.log_facility|LOG_WARNING; | |||||
#endif | |||||
/* Avoid killing the process in high-pressure swapping environments. */ | /* Avoid killing the process in high-pressure swapping environments. */ | ||||
if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0) | if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0) | ||||
debug("madvise(): %.200s", strerror(errno)); | debug("madvise(): %.200s", strerror(errno)); | ||||
/* | /* | ||||
* Chdir to the root directory so that the current disk can be | * Chdir to the root directory so that the current disk can be | ||||
* unmounted if desired. | * unmounted if desired. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | |||||
#ifdef HAVE_LOGIN_CAP | #ifdef HAVE_LOGIN_CAP | ||||
/* Also caches remote hostname for sandboxed child. */ | /* Also caches remote hostname for sandboxed child. */ | ||||
auth_get_canonical_hostname(ssh, options.use_dns); | auth_get_canonical_hostname(ssh, options.use_dns); | ||||
#endif | #endif | ||||
#ifdef SSH_AUDIT_EVENTS | #ifdef SSH_AUDIT_EVENTS | ||||
audit_connection_from(remote_ip, remote_port); | audit_connection_from(remote_ip, remote_port); | ||||
#endif | #endif | ||||
#ifdef LIBWRAP | |||||
allow_severity = options.log_facility|LOG_INFO; | |||||
deny_severity = options.log_facility|LOG_WARNING; | |||||
/* Check whether logins are denied from this host. */ | |||||
if (ssh_packet_connection_is_on_socket(ssh)) { | |||||
struct request_info req; | |||||
request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); | |||||
fromhost(&req); | |||||
if (!hosts_access(&req)) { | |||||
debug("Connection refused by tcp wrapper"); | |||||
refuse(&req); | |||||
/* NOTREACHED */ | |||||
fatal("libwrap refuse returns"); | |||||
} | |||||
} | |||||
#endif /* LIBWRAP */ | |||||
rdomain = ssh_packet_rdomain_in(ssh); | rdomain = ssh_packet_rdomain_in(ssh); | ||||
/* Log the connection. */ | /* Log the connection. */ | ||||
laddr = get_local_ipaddr(sock_in); | laddr = get_local_ipaddr(sock_in); | ||||
verbose("Connection from %s port %d on %s port %d%s%s%s", | verbose("Connection from %s port %d on %s port %d%s%s%s", | ||||
remote_ip, remote_port, laddr, ssh_local_port(ssh), | remote_ip, remote_port, laddr, ssh_local_port(ssh), | ||||
rdomain == NULL ? "" : " rdomain \"", | rdomain == NULL ? "" : " rdomain \"", | ||||
▲ Show 20 Lines • Show All 263 Lines • Show Last 20 Lines |