2024-09-15 01:11:26 +00:00
|
|
|
/* $OpenBSD: sshd.c,v 1.612 2024/09/15 01:11:26 djm Exp $ */
|
1999-10-27 03:42:43 +00:00
|
|
|
/*
|
2002-03-22 02:30:41 +00:00
|
|
|
* Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
|
|
|
* Copyright (c) 2002 Niels Provos. All rights reserved.
|
2000-09-16 02:29:08 +00:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
1999-11-24 13:26:21 +00:00
|
|
|
*/
|
1999-10-27 03:42:43 +00:00
|
|
|
|
|
|
|
#include "includes.h"
|
2006-03-15 00:28:34 +00:00
|
|
|
|
2006-03-15 00:29:24 +00:00
|
|
|
#include <sys/types.h>
|
2006-08-05 02:39:39 +00:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/socket.h>
|
2006-03-15 00:45:54 +00:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
# include <sys/stat.h>
|
|
|
|
#endif
|
2006-08-05 00:57:45 +00:00
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
# include <sys/time.h>
|
|
|
|
#endif
|
2006-08-05 02:39:39 +00:00
|
|
|
#include "openbsd-compat/sys-tree.h"
|
2008-05-19 05:05:07 +00:00
|
|
|
#include "openbsd-compat/sys-queue.h"
|
2006-03-15 00:29:24 +00:00
|
|
|
#include <sys/wait.h>
|
2006-03-15 00:16:59 +00:00
|
|
|
|
2006-07-12 12:22:46 +00:00
|
|
|
#include <errno.h>
|
2006-07-10 11:13:46 +00:00
|
|
|
#include <fcntl.h>
|
2006-07-24 04:51:00 +00:00
|
|
|
#include <netdb.h>
|
2006-03-15 03:42:54 +00:00
|
|
|
#ifdef HAVE_PATHS_H
|
2006-03-15 00:16:59 +00:00
|
|
|
#include <paths.h>
|
2006-03-15 03:42:54 +00:00
|
|
|
#endif
|
2006-07-10 11:33:04 +00:00
|
|
|
#include <grp.h>
|
2021-11-18 12:05:34 +00:00
|
|
|
#ifdef HAVE_POLL_H
|
2021-11-14 18:47:43 +00:00
|
|
|
#include <poll.h>
|
2021-11-18 12:05:34 +00:00
|
|
|
#endif
|
2006-07-10 10:53:08 +00:00
|
|
|
#include <pwd.h>
|
2006-03-15 00:52:09 +00:00
|
|
|
#include <signal.h>
|
2006-09-01 05:38:36 +00:00
|
|
|
#include <stdarg.h>
|
2006-08-05 01:37:59 +00:00
|
|
|
#include <stdio.h>
|
2006-08-05 01:34:19 +00:00
|
|
|
#include <stdlib.h>
|
2006-07-24 04:13:33 +00:00
|
|
|
#include <string.h>
|
2006-08-05 04:07:20 +00:00
|
|
|
#include <unistd.h>
|
2015-01-20 23:14:00 +00:00
|
|
|
#include <limits.h>
|
1999-10-27 03:42:43 +00:00
|
|
|
|
2014-05-15 04:24:09 +00:00
|
|
|
#ifdef WITH_OPENSSL
|
2024-05-17 00:30:23 +00:00
|
|
|
#include <openssl/evp.h>
|
2002-03-22 02:30:41 +00:00
|
|
|
#include <openssl/rand.h>
|
2008-02-28 08:13:52 +00:00
|
|
|
#include "openbsd-compat/openssl-compat.h"
|
2014-05-15 04:24:09 +00:00
|
|
|
#endif
|
2008-02-28 08:13:52 +00:00
|
|
|
|
2002-04-25 18:17:04 +00:00
|
|
|
#ifdef HAVE_SECUREWARE
|
|
|
|
#include <sys/security.h>
|
|
|
|
#include <prot.h>
|
|
|
|
#endif
|
2001-01-22 05:34:40 +00:00
|
|
|
|
2006-08-05 02:39:39 +00:00
|
|
|
#include "xmalloc.h"
|
2001-01-22 05:34:40 +00:00
|
|
|
#include "ssh.h"
|
2001-02-18 19:13:33 +00:00
|
|
|
#include "sshpty.h"
|
2001-01-22 05:34:40 +00:00
|
|
|
#include "log.h"
|
2018-07-09 21:29:36 +00:00
|
|
|
#include "sshbuf.h"
|
2014-07-18 04:11:24 +00:00
|
|
|
#include "misc.h"
|
1999-10-27 03:42:43 +00:00
|
|
|
#include "servconf.h"
|
|
|
|
#include "compat.h"
|
2014-02-04 00:03:36 +00:00
|
|
|
#include "digest.h"
|
2018-07-11 18:53:29 +00:00
|
|
|
#include "sshkey.h"
|
2000-04-29 13:57:08 +00:00
|
|
|
#include "authfile.h"
|
2001-01-22 05:34:40 +00:00
|
|
|
#include "pathnames.h"
|
|
|
|
#include "canohost.h"
|
2006-08-05 02:39:39 +00:00
|
|
|
#include "hostfile.h"
|
2001-01-22 05:34:40 +00:00
|
|
|
#include "auth.h"
|
2013-07-20 03:21:52 +00:00
|
|
|
#include "authfd.h"
|
2004-06-25 03:33:20 +00:00
|
|
|
#include "msg.h"
|
2006-07-10 10:23:39 +00:00
|
|
|
#include "version.h"
|
2015-01-14 20:05:27 +00:00
|
|
|
#include "ssherr.h"
|
2019-12-15 18:57:30 +00:00
|
|
|
#include "sk-api.h"
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
#include "addr.h"
|
2021-01-09 12:10:02 +00:00
|
|
|
#include "srclimit.h"
|
1999-10-27 03:42:43 +00:00
|
|
|
|
2004-06-25 22:16:31 +00:00
|
|
|
/* Re-exec fds */
|
|
|
|
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
|
|
|
|
#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2)
|
|
|
|
#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3)
|
|
|
|
#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4)
|
|
|
|
|
2000-11-17 03:47:20 +00:00
|
|
|
extern char *__progname;
|
|
|
|
|
1999-10-27 03:42:43 +00:00
|
|
|
/* Server configuration options. */
|
|
|
|
ServerOptions options;
|
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/*
|
|
|
|
* Debug mode flag. This can be set on the command line. If debug
|
|
|
|
* mode is enabled, extra debugging output will be sent to the system
|
|
|
|
* log, the daemon will not go to background, and will exit after processing
|
|
|
|
* the first connection.
|
|
|
|
*/
|
1999-10-27 03:42:43 +00:00
|
|
|
int debug_flag = 0;
|
|
|
|
|
|
|
|
/* Saved arguments to main(). */
|
2019-01-17 01:50:24 +00:00
|
|
|
static char **saved_argv;
|
|
|
|
static int saved_argc;
|
1999-10-27 03:42:43 +00:00
|
|
|
|
1999-11-25 00:54:57 +00:00
|
|
|
/*
|
2000-01-14 04:45:46 +00:00
|
|
|
* The sockets that the server is listening; this is used in the SIGHUP
|
|
|
|
* signal handler.
|
1999-11-25 00:54:57 +00:00
|
|
|
*/
|
2000-01-14 04:45:46 +00:00
|
|
|
#define MAX_LISTEN_SOCKS 16
|
2019-01-17 01:50:24 +00:00
|
|
|
static int listen_socks[MAX_LISTEN_SOCKS];
|
|
|
|
static int num_listen_socks = 0;
|
1999-10-27 03:42:43 +00:00
|
|
|
|
1999-11-25 00:54:57 +00:00
|
|
|
/*
|
|
|
|
* Any really sensitive data in the application is contained in this
|
|
|
|
* structure. The idea is that this structure could be locked into memory so
|
|
|
|
* that the pages do not get written into swap. However, there are some
|
|
|
|
* problems. The private key contains BIGNUMs, and we do not (in principle)
|
|
|
|
* have access to the internals of them, and locking just the structure is
|
|
|
|
* not very useful. Currently, memory locking is not implemented.
|
|
|
|
*/
|
1999-11-24 13:26:21 +00:00
|
|
|
struct {
|
2017-05-30 08:52:19 +00:00
|
|
|
struct sshkey **host_keys; /* all private host keys */
|
|
|
|
struct sshkey **host_pubkeys; /* all public host keys */
|
|
|
|
struct sshkey **host_certificates; /* all public host certificates */
|
|
|
|
int have_ssh2_key;
|
1999-10-27 03:42:43 +00:00
|
|
|
} sensitive_data;
|
|
|
|
|
2001-06-09 01:27:31 +00:00
|
|
|
/* This is set to true when a signal is received. */
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
static volatile sig_atomic_t received_siginfo = 0;
|
|
|
|
static volatile sig_atomic_t received_sigchld = 0;
|
2001-12-06 16:48:14 +00:00
|
|
|
static volatile sig_atomic_t received_sighup = 0;
|
|
|
|
static volatile sig_atomic_t received_sigterm = 0;
|
1999-10-27 03:42:43 +00:00
|
|
|
|
2000-08-18 03:59:06 +00:00
|
|
|
/* record remote hostname or ip */
|
2015-01-20 23:14:00 +00:00
|
|
|
u_int utmp_len = HOST_NAME_MAX+1;
|
2000-08-18 03:59:06 +00:00
|
|
|
|
2019-03-01 02:32:39 +00:00
|
|
|
/*
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
* The early_child/children array below is used for tracking children of the
|
|
|
|
* listening sshd process early in their lifespans, before they have
|
|
|
|
* completed authentication. This tracking is needed for four things:
|
2019-03-01 02:32:39 +00:00
|
|
|
*
|
|
|
|
* 1) Implementing the MaxStartups limit of concurrent unauthenticated
|
|
|
|
* connections.
|
|
|
|
* 2) Avoiding a race condition for SIGHUP processing, where child processes
|
|
|
|
* may have listen_socks open that could collide with main listener process
|
|
|
|
* after it restarts.
|
|
|
|
* 3) Ensuring that rexec'd sshd processes have received their initial state
|
|
|
|
* from the parent listen process before handling SIGHUP.
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
* 4) Tracking and logging unsuccessful exits from the preauth sshd monitor,
|
|
|
|
* including and especially those for LoginGraceTime timeouts.
|
2019-03-01 02:32:39 +00:00
|
|
|
*
|
|
|
|
* Child processes signal that they have completed closure of the listen_socks
|
|
|
|
* and (if applicable) received their rexec state by sending a char over their
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
* sock.
|
|
|
|
*
|
|
|
|
* Child processes signal that authentication has completed by sending a
|
|
|
|
* second char over the socket before closing it, otherwise the listener will
|
|
|
|
* continue tracking the child (and using up a MaxStartups slot) until the
|
|
|
|
* preauth subprocess exits, whereupon the listener will log its exit status.
|
|
|
|
* preauth processes will exit with a status of EXIT_LOGIN_GRACE to indicate
|
|
|
|
* they did not authenticate before the LoginGraceTime alarm fired.
|
2019-03-01 02:32:39 +00:00
|
|
|
*/
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
struct early_child {
|
|
|
|
int pipefd;
|
|
|
|
int early; /* Indicates child closed listener */
|
|
|
|
char *id; /* human readable connection identifier */
|
|
|
|
pid_t pid;
|
|
|
|
struct xaddr addr;
|
|
|
|
int have_addr;
|
|
|
|
int status, have_status;
|
|
|
|
};
|
|
|
|
static struct early_child *children;
|
|
|
|
static int children_active;
|
2019-03-01 02:32:39 +00:00
|
|
|
static int startup_pipe = -1; /* in child */
|
2001-12-06 16:35:40 +00:00
|
|
|
|
2006-07-12 12:34:17 +00:00
|
|
|
/* sshd_config buffer */
|
2018-07-09 21:29:36 +00:00
|
|
|
struct sshbuf *cfg;
|
2006-07-12 12:34:17 +00:00
|
|
|
|
2020-01-31 22:42:45 +00:00
|
|
|
/* Included files from the configuration file */
|
|
|
|
struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
|
|
|
|
|
2004-07-17 07:05:14 +00:00
|
|
|
/* message to be displayed after login */
|
2018-07-09 21:26:02 +00:00
|
|
|
struct sshbuf *loginmsg;
|
2004-07-17 07:05:14 +00:00
|
|
|
|
2006-09-07 00:36:43 +00:00
|
|
|
/* Unprivileged user */
|
|
|
|
struct passwd *privsep_pw = NULL;
|
|
|
|
|
2020-01-24 23:56:01 +00:00
|
|
|
static char *listener_proctitle;
|
|
|
|
|
2000-01-14 04:45:46 +00:00
|
|
|
/*
|
|
|
|
* Close all listening sockets
|
|
|
|
*/
|
2001-06-25 05:01:22 +00:00
|
|
|
static void
|
2000-01-14 04:45:46 +00:00
|
|
|
close_listen_socks(void)
|
|
|
|
{
|
|
|
|
int i;
|
2002-06-23 21:38:49 +00:00
|
|
|
|
2000-01-14 04:45:46 +00:00
|
|
|
for (i = 0; i < num_listen_socks; i++)
|
|
|
|
close(listen_socks[i]);
|
2021-11-17 21:06:39 +00:00
|
|
|
num_listen_socks = 0;
|
2000-01-14 04:45:46 +00:00
|
|
|
}
|
|
|
|
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
/* Allocate and initialise the children array */
|
|
|
|
static void
|
|
|
|
child_alloc(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
children = xcalloc(options.max_startups, sizeof(*children));
|
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
|
|
|
children[i].pipefd = -1;
|
|
|
|
children[i].pid = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Register a new connection in the children array; child pid comes later */
|
|
|
|
static struct early_child *
|
|
|
|
child_register(int pipefd, int sockfd)
|
|
|
|
{
|
|
|
|
int i, lport, rport;
|
|
|
|
char *laddr = NULL, *raddr = NULL;
|
|
|
|
struct early_child *child = NULL;
|
|
|
|
struct sockaddr_storage addr;
|
|
|
|
socklen_t addrlen = sizeof(addr);
|
|
|
|
struct sockaddr *sa = (struct sockaddr *)&addr;
|
|
|
|
|
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
|
|
|
if (children[i].pipefd != -1 || children[i].pid > 0)
|
|
|
|
continue;
|
|
|
|
child = &(children[i]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (child == NULL) {
|
|
|
|
fatal_f("error: accepted connection when all %d child "
|
|
|
|
" slots full", options.max_startups);
|
|
|
|
}
|
|
|
|
child->pipefd = pipefd;
|
|
|
|
child->early = 1;
|
|
|
|
/* record peer address, if available */
|
|
|
|
if (getpeername(sockfd, sa, &addrlen) == 0 &&
|
|
|
|
addr_sa_to_xaddr(sa, addrlen, &child->addr) == 0)
|
|
|
|
child->have_addr = 1;
|
|
|
|
/* format peer address string for logs */
|
|
|
|
if ((lport = get_local_port(sockfd)) == 0 ||
|
|
|
|
(rport = get_peer_port(sockfd)) == 0) {
|
|
|
|
/* Not a TCP socket */
|
|
|
|
raddr = get_peer_ipaddr(sockfd);
|
|
|
|
xasprintf(&child->id, "connection from %s", raddr);
|
|
|
|
} else {
|
|
|
|
laddr = get_local_ipaddr(sockfd);
|
|
|
|
raddr = get_peer_ipaddr(sockfd);
|
2024-08-17 08:09:50 +00:00
|
|
|
xasprintf(&child->id, "connection from %s to %s", raddr, laddr);
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
}
|
|
|
|
free(laddr);
|
|
|
|
free(raddr);
|
|
|
|
if (++children_active > options.max_startups)
|
|
|
|
fatal_f("internal error: more children than max_startups");
|
|
|
|
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Finally free a child entry. Don't call this directly.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
child_finish(struct early_child *child)
|
|
|
|
{
|
|
|
|
if (children_active == 0)
|
|
|
|
fatal_f("internal error: children_active underflow");
|
|
|
|
if (child->pipefd != -1)
|
|
|
|
close(child->pipefd);
|
|
|
|
free(child->id);
|
|
|
|
memset(child, '\0', sizeof(*child));
|
|
|
|
child->pipefd = -1;
|
|
|
|
child->pid = -1;
|
|
|
|
children_active--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Close a child's pipe. This will not stop tracking the child immediately
|
|
|
|
* (it will still be tracked for waitpid()) unless force_final is set, or
|
|
|
|
* child has already exited.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
child_close(struct early_child *child, int force_final, int quiet)
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
debug_f("enter%s", force_final ? " (forcing)" : "");
|
|
|
|
if (child->pipefd != -1) {
|
|
|
|
close(child->pipefd);
|
|
|
|
child->pipefd = -1;
|
|
|
|
}
|
|
|
|
if (child->pid == -1 || force_final)
|
|
|
|
child_finish(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Record a child exit. Safe to call from signal handlers */
|
|
|
|
static void
|
|
|
|
child_exit(pid_t pid, int status)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (children == NULL || pid <= 0)
|
|
|
|
return;
|
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
|
|
|
if (children[i].pid == pid) {
|
|
|
|
children[i].have_status = 1;
|
|
|
|
children[i].status = status;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reap a child entry that has exited, as previously flagged
|
|
|
|
* using child_exit().
|
|
|
|
* Handles logging of exit condition and will finalise the child if its pipe
|
|
|
|
* had already been closed.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
child_reap(struct early_child *child)
|
|
|
|
{
|
|
|
|
LogLevel level = SYSLOG_LEVEL_DEBUG1;
|
|
|
|
int was_crash, penalty_type = SRCLIMIT_PENALTY_NONE;
|
|
|
|
|
|
|
|
/* Log exit information */
|
|
|
|
if (WIFSIGNALED(child->status)) {
|
|
|
|
/*
|
|
|
|
* Increase logging for signals potentially associated
|
|
|
|
* with serious conditions.
|
|
|
|
*/
|
|
|
|
if ((was_crash = signal_is_crash(WTERMSIG(child->status))))
|
|
|
|
level = SYSLOG_LEVEL_ERROR;
|
|
|
|
do_log2(level, "session process %ld for %s killed by "
|
|
|
|
"signal %d%s", (long)child->pid, child->id,
|
|
|
|
WTERMSIG(child->status), child->early ? " (early)" : "");
|
|
|
|
if (was_crash)
|
|
|
|
penalty_type = SRCLIMIT_PENALTY_CRASH;
|
|
|
|
} else if (!WIFEXITED(child->status)) {
|
|
|
|
penalty_type = SRCLIMIT_PENALTY_CRASH;
|
|
|
|
error("session process %ld for %s terminated abnormally, "
|
|
|
|
"status=0x%x%s", (long)child->pid, child->id, child->status,
|
|
|
|
child->early ? " (early)" : "");
|
|
|
|
} else {
|
|
|
|
/* Normal exit. We care about the status */
|
|
|
|
switch (WEXITSTATUS(child->status)) {
|
|
|
|
case 0:
|
|
|
|
debug3_f("preauth child %ld for %s completed "
|
|
|
|
"normally %s", (long)child->pid, child->id,
|
|
|
|
child->early ? " (early)" : "");
|
|
|
|
break;
|
|
|
|
case EXIT_LOGIN_GRACE:
|
|
|
|
penalty_type = SRCLIMIT_PENALTY_GRACE_EXCEEDED;
|
|
|
|
logit("Timeout before authentication for %s, "
|
|
|
|
"pid = %ld%s", child->id, (long)child->pid,
|
|
|
|
child->early ? " (early)" : "");
|
|
|
|
break;
|
|
|
|
case EXIT_CHILD_CRASH:
|
|
|
|
penalty_type = SRCLIMIT_PENALTY_CRASH;
|
|
|
|
logit("Session process %ld unpriv child crash for %s%s",
|
|
|
|
(long)child->pid, child->id,
|
|
|
|
child->early ? " (early)" : "");
|
|
|
|
break;
|
|
|
|
case EXIT_AUTH_ATTEMPTED:
|
|
|
|
penalty_type = SRCLIMIT_PENALTY_AUTHFAIL;
|
|
|
|
debug_f("preauth child %ld for %s exited "
|
|
|
|
"after unsuccessful auth attempt %s",
|
|
|
|
(long)child->pid, child->id,
|
|
|
|
child->early ? " (early)" : "");
|
|
|
|
break;
|
2024-09-15 01:11:26 +00:00
|
|
|
case EXIT_CONFIG_REFUSED:
|
|
|
|
penalty_type = SRCLIMIT_PENALTY_REFUSECONNECTION;
|
|
|
|
debug_f("preauth child %ld for %s prohibited by"
|
|
|
|
"RefuseConnection %s",
|
|
|
|
(long)child->pid, child->id,
|
|
|
|
child->early ? " (early)" : "");
|
|
|
|
break;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
default:
|
|
|
|
penalty_type = SRCLIMIT_PENALTY_NOAUTH;
|
|
|
|
debug_f("preauth child %ld for %s exited "
|
|
|
|
"with status %d%s", (long)child->pid, child->id,
|
|
|
|
WEXITSTATUS(child->status),
|
|
|
|
child->early ? " (early)" : "");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-06-27 23:01:15 +00:00
|
|
|
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (child->have_addr)
|
|
|
|
srclimit_penalise(&child->addr, penalty_type);
|
|
|
|
|
|
|
|
child->pid = -1;
|
|
|
|
child->have_status = 0;
|
|
|
|
if (child->pipefd == -1)
|
|
|
|
child_finish(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reap all children that have exited; called after SIGCHLD */
|
|
|
|
static void
|
|
|
|
child_reap_all_exited(void)
|
|
|
|
{
|
|
|
|
int i;
|
2024-06-26 23:47:46 +00:00
|
|
|
pid_t pid;
|
|
|
|
int status;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
|
|
|
|
if (children == NULL)
|
|
|
|
return;
|
2024-06-26 23:47:46 +00:00
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
if ((pid = waitpid(-1, &status, WNOHANG)) == 0)
|
|
|
|
break;
|
|
|
|
else if (pid == -1) {
|
|
|
|
if (errno == EINTR || errno == EAGAIN)
|
|
|
|
continue;
|
|
|
|
if (errno != ECHILD)
|
|
|
|
error_f("waitpid: %s", strerror(errno));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
child_exit(pid, status);
|
|
|
|
}
|
|
|
|
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
|
|
|
if (!children[i].have_status)
|
|
|
|
continue;
|
|
|
|
child_reap(&(children[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-12-06 16:35:40 +00:00
|
|
|
static void
|
|
|
|
close_startup_pipes(void)
|
|
|
|
{
|
|
|
|
int i;
|
2002-06-23 21:38:49 +00:00
|
|
|
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (children == NULL)
|
|
|
|
return;
|
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
|
|
|
if (children[i].pipefd != -1)
|
|
|
|
child_close(&(children[i]), 1, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Called after SIGINFO */
|
|
|
|
static void
|
|
|
|
show_info(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* XXX print listening sockets here too */
|
|
|
|
if (children == NULL)
|
|
|
|
return;
|
|
|
|
logit("%d active startups", children_active);
|
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
|
|
|
if (children[i].pipefd == -1 && children[i].pid <= 0)
|
|
|
|
continue;
|
|
|
|
logit("child %d: fd=%d pid=%ld %s%s", i, children[i].pipefd,
|
|
|
|
(long)children[i].pid, children[i].id,
|
|
|
|
children[i].early ? " (early)" : "");
|
|
|
|
}
|
|
|
|
srclimit_penalty_info();
|
2001-12-06 16:35:40 +00:00
|
|
|
}
|
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/*
|
|
|
|
* Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP;
|
|
|
|
* the effect is to reread the configuration file (and to regenerate
|
|
|
|
* the server key).
|
|
|
|
*/
|
2006-03-26 02:59:20 +00:00
|
|
|
|
2001-06-25 05:01:22 +00:00
|
|
|
static void
|
1999-11-24 13:26:21 +00:00
|
|
|
sighup_handler(int sig)
|
1999-10-27 03:42:43 +00:00
|
|
|
{
|
1999-11-24 13:26:21 +00:00
|
|
|
received_sighup = 1;
|
1999-10-27 03:42:43 +00:00
|
|
|
}
|
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/*
|
|
|
|
* Called from the main program after receiving SIGHUP.
|
|
|
|
* Restarts the server.
|
|
|
|
*/
|
2001-06-25 05:01:22 +00:00
|
|
|
static void
|
2001-02-09 02:11:24 +00:00
|
|
|
sighup_restart(void)
|
1999-10-27 03:42:43 +00:00
|
|
|
{
|
2003-04-09 10:59:48 +00:00
|
|
|
logit("Received SIGHUP; restarting.");
|
2016-12-04 22:27:25 +00:00
|
|
|
if (options.pid_file != NULL)
|
|
|
|
unlink(options.pid_file);
|
2013-09-22 09:02:40 +00:00
|
|
|
platform_pre_restart();
|
2000-01-14 04:45:46 +00:00
|
|
|
close_listen_socks();
|
2001-12-06 16:35:40 +00:00
|
|
|
close_startup_pipes();
|
2020-01-23 07:10:22 +00:00
|
|
|
ssh_signal(SIGHUP, SIG_IGN); /* will be restored after exec */
|
1999-11-24 13:26:21 +00:00
|
|
|
execv(saved_argv[0], saved_argv);
|
2003-04-09 10:59:48 +00:00
|
|
|
logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
|
2002-06-23 21:38:49 +00:00
|
|
|
strerror(errno));
|
1999-11-24 13:26:21 +00:00
|
|
|
exit(1);
|
1999-10-27 03:42:43 +00:00
|
|
|
}
|
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/*
|
|
|
|
* Generic signal handler for terminating signals in the master daemon.
|
|
|
|
*/
|
2001-06-25 05:01:22 +00:00
|
|
|
static void
|
1999-11-24 13:26:21 +00:00
|
|
|
sigterm_handler(int sig)
|
1999-10-27 03:42:43 +00:00
|
|
|
{
|
2001-06-09 01:27:31 +00:00
|
|
|
received_sigterm = sig;
|
1999-10-27 03:42:43 +00:00
|
|
|
}
|
|
|
|
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
#ifdef SIGINFO
|
|
|
|
static void
|
|
|
|
siginfo_handler(int sig)
|
|
|
|
{
|
|
|
|
received_siginfo = 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-06-25 05:01:22 +00:00
|
|
|
static void
|
1999-11-24 13:26:21 +00:00
|
|
|
main_sigchld_handler(int sig)
|
1999-10-27 03:42:43 +00:00
|
|
|
{
|
2024-06-26 23:47:46 +00:00
|
|
|
received_sigchld = 1;
|
1999-10-27 03:42:43 +00:00
|
|
|
}
|
|
|
|
|
2000-08-18 03:59:06 +00:00
|
|
|
/*
|
|
|
|
* returns 1 if connection should be dropped, 0 otherwise.
|
|
|
|
* dropping starts at connection #max_startups_begin with a probability
|
|
|
|
* of (max_startups_rate/100). the probability increases linearly until
|
|
|
|
* all connections are dropped for startups > max_startups
|
|
|
|
*/
|
2001-06-25 05:01:22 +00:00
|
|
|
static int
|
2020-05-26 01:09:05 +00:00
|
|
|
should_drop_connection(int startups)
|
2000-08-18 03:59:06 +00:00
|
|
|
{
|
2004-11-05 09:09:09 +00:00
|
|
|
int p, r;
|
2000-08-18 03:59:06 +00:00
|
|
|
|
|
|
|
if (startups < options.max_startups_begin)
|
|
|
|
return 0;
|
|
|
|
if (startups >= options.max_startups)
|
|
|
|
return 1;
|
|
|
|
if (options.max_startups_rate == 100)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
p = 100 - options.max_startups_rate;
|
|
|
|
p *= startups - options.max_startups_begin;
|
2004-11-05 09:09:09 +00:00
|
|
|
p /= options.max_startups - options.max_startups_begin;
|
2000-08-18 03:59:06 +00:00
|
|
|
p += options.max_startups_rate;
|
2008-05-19 04:50:00 +00:00
|
|
|
r = arc4random_uniform(100);
|
2000-08-18 03:59:06 +00:00
|
|
|
|
2020-10-18 11:32:01 +00:00
|
|
|
debug_f("p %d, r %d", p, r);
|
2000-08-18 03:59:06 +00:00
|
|
|
return (r < p) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
2020-05-26 01:09:05 +00:00
|
|
|
/*
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
* Check whether connection should be accepted by MaxStartups or for penalty.
|
2020-05-26 01:09:05 +00:00
|
|
|
* Returns 0 if the connection is accepted. If the connection is refused,
|
|
|
|
* returns 1 and attempts to send notification to client.
|
|
|
|
* Logs when the MaxStartups condition is entered or exited, and periodically
|
|
|
|
* while in that state.
|
|
|
|
*/
|
|
|
|
static int
|
2021-01-09 12:10:02 +00:00
|
|
|
drop_connection(int sock, int startups, int notify_pipe)
|
2020-05-26 01:09:05 +00:00
|
|
|
{
|
|
|
|
char *laddr, *raddr;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
const char *reason = NULL, msg[] = "Not allowed at this time\r\n";
|
2020-05-26 01:09:05 +00:00
|
|
|
static time_t last_drop, first_drop;
|
|
|
|
static u_int ndropped;
|
|
|
|
LogLevel drop_level = SYSLOG_LEVEL_VERBOSE;
|
|
|
|
time_t now;
|
|
|
|
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (!srclimit_penalty_check_allow(sock, &reason)) {
|
|
|
|
drop_level = SYSLOG_LEVEL_INFO;
|
|
|
|
goto handle;
|
|
|
|
}
|
|
|
|
|
2020-05-26 01:09:05 +00:00
|
|
|
now = monotime();
|
2021-01-09 12:10:02 +00:00
|
|
|
if (!should_drop_connection(startups) &&
|
|
|
|
srclimit_check_allow(sock, notify_pipe) == 1) {
|
2020-05-26 01:09:05 +00:00
|
|
|
if (last_drop != 0 &&
|
|
|
|
startups < options.max_startups_begin - 1) {
|
|
|
|
/* XXX maybe need better hysteresis here */
|
|
|
|
logit("exited MaxStartups throttling after %s, "
|
|
|
|
"%u connections dropped",
|
|
|
|
fmt_timeframe(now - first_drop), ndropped);
|
|
|
|
last_drop = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60)
|
|
|
|
if (last_drop == 0) {
|
|
|
|
error("beginning MaxStartups throttling");
|
|
|
|
drop_level = SYSLOG_LEVEL_INFO;
|
|
|
|
first_drop = now;
|
|
|
|
ndropped = 0;
|
|
|
|
} else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) {
|
|
|
|
/* Periodic logs */
|
|
|
|
error("in MaxStartups throttling for %s, "
|
|
|
|
"%u connections dropped",
|
|
|
|
fmt_timeframe(now - first_drop), ndropped + 1);
|
|
|
|
drop_level = SYSLOG_LEVEL_INFO;
|
|
|
|
}
|
|
|
|
last_drop = now;
|
|
|
|
ndropped++;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
reason = "past Maxstartups";
|
2020-05-26 01:09:05 +00:00
|
|
|
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
handle:
|
2020-05-26 01:09:05 +00:00
|
|
|
laddr = get_local_ipaddr(sock);
|
|
|
|
raddr = get_peer_ipaddr(sock);
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d %s",
|
|
|
|
startups,
|
|
|
|
raddr, get_peer_port(sock),
|
|
|
|
laddr, get_local_port(sock),
|
|
|
|
reason);
|
2020-05-26 01:09:05 +00:00
|
|
|
free(laddr);
|
|
|
|
free(raddr);
|
|
|
|
/* best-effort notification to client */
|
|
|
|
(void)write(sock, msg, sizeof(msg) - 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2001-12-06 18:22:17 +00:00
|
|
|
static void
|
|
|
|
usage(void)
|
|
|
|
{
|
2020-11-08 11:46:12 +00:00
|
|
|
fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSH_OPENSSL_VERSION);
|
2004-03-21 22:35:21 +00:00
|
|
|
fprintf(stderr,
|
2023-02-10 04:47:19 +00:00
|
|
|
"usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n"
|
2013-04-23 05:21:06 +00:00
|
|
|
" [-E log_file] [-f config_file] [-g login_grace_time]\n"
|
2016-08-15 12:27:56 +00:00
|
|
|
" [-h host_key_file] [-o option] [-p port] [-u len]\n"
|
2004-03-21 22:35:21 +00:00
|
|
|
);
|
2001-12-06 18:22:17 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
static struct sshbuf *
|
|
|
|
pack_hostkeys(void)
|
|
|
|
{
|
|
|
|
struct sshbuf *keybuf = NULL, *hostkeys = NULL;
|
|
|
|
int r;
|
|
|
|
u_int i;
|
|
|
|
|
|
|
|
if ((keybuf = sshbuf_new()) == NULL ||
|
|
|
|
(hostkeys = sshbuf_new()) == NULL)
|
|
|
|
fatal_f("sshbuf_new failed");
|
|
|
|
|
|
|
|
/* pack hostkeys into a string. Empty key slots get empty strings */
|
|
|
|
for (i = 0; i < options.num_host_key_files; i++) {
|
|
|
|
/* private key */
|
|
|
|
sshbuf_reset(keybuf);
|
|
|
|
if (sensitive_data.host_keys[i] != NULL &&
|
|
|
|
(r = sshkey_private_serialize(sensitive_data.host_keys[i],
|
|
|
|
keybuf)) != 0)
|
|
|
|
fatal_fr(r, "serialize hostkey private");
|
|
|
|
if ((r = sshbuf_put_stringb(hostkeys, keybuf)) != 0)
|
|
|
|
fatal_fr(r, "compose hostkey private");
|
|
|
|
/* public key */
|
|
|
|
if (sensitive_data.host_pubkeys[i] != NULL) {
|
|
|
|
if ((r = sshkey_puts(sensitive_data.host_pubkeys[i],
|
|
|
|
hostkeys)) != 0)
|
|
|
|
fatal_fr(r, "compose hostkey public");
|
|
|
|
} else {
|
|
|
|
if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0)
|
|
|
|
fatal_fr(r, "compose hostkey empty public");
|
|
|
|
}
|
|
|
|
/* cert */
|
|
|
|
if (sensitive_data.host_certificates[i] != NULL) {
|
|
|
|
if ((r = sshkey_puts(
|
|
|
|
sensitive_data.host_certificates[i],
|
|
|
|
hostkeys)) != 0)
|
|
|
|
fatal_fr(r, "compose host cert");
|
|
|
|
} else {
|
|
|
|
if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0)
|
|
|
|
fatal_fr(r, "compose host cert empty");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sshbuf_free(keybuf);
|
|
|
|
return hostkeys;
|
|
|
|
}
|
|
|
|
|
2004-06-25 03:33:20 +00:00
|
|
|
static void
|
2016-05-02 08:49:03 +00:00
|
|
|
send_rexec_state(int fd, struct sshbuf *conf)
|
2004-06-25 03:33:20 +00:00
|
|
|
{
|
2024-05-17 00:30:23 +00:00
|
|
|
struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL;
|
2020-01-31 22:42:45 +00:00
|
|
|
struct include_item *item = NULL;
|
2024-05-17 00:30:23 +00:00
|
|
|
int r, sz;
|
2004-06-25 03:33:20 +00:00
|
|
|
|
2020-10-18 11:32:01 +00:00
|
|
|
debug3_f("entering fd = %d config len %zu", fd,
|
2016-05-02 08:49:03 +00:00
|
|
|
sshbuf_len(conf));
|
2004-06-25 03:33:20 +00:00
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
if ((m = sshbuf_new()) == NULL ||
|
|
|
|
(inc = sshbuf_new()) == NULL)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_f("sshbuf_new failed");
|
2020-01-31 22:42:45 +00:00
|
|
|
|
|
|
|
/* pack includes into a string */
|
|
|
|
TAILQ_FOREACH(item, &includes, entry) {
|
|
|
|
if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 ||
|
|
|
|
(r = sshbuf_put_cstring(inc, item->filename)) != 0 ||
|
|
|
|
(r = sshbuf_put_stringb(inc, item->contents)) != 0)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_fr(r, "compose includes");
|
2020-01-31 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
hostkeys = pack_hostkeys();
|
|
|
|
|
2004-06-25 03:33:20 +00:00
|
|
|
/*
|
|
|
|
* Protocol from reexec master to child:
|
|
|
|
* string configuration
|
2024-05-17 00:30:23 +00:00
|
|
|
* uint64 timing_secret
|
|
|
|
* string host_keys[] {
|
|
|
|
* string private_key
|
|
|
|
* string public_key
|
|
|
|
* string certificate
|
|
|
|
* }
|
2020-01-31 22:42:45 +00:00
|
|
|
* string included_files[] {
|
|
|
|
* string selector
|
|
|
|
* string filename
|
|
|
|
* string contents
|
|
|
|
* }
|
2004-06-25 03:33:20 +00:00
|
|
|
*/
|
2020-01-31 22:42:45 +00:00
|
|
|
if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
|
2024-05-17 00:30:23 +00:00
|
|
|
(r = sshbuf_put_u64(m, options.timing_secret)) != 0 ||
|
|
|
|
(r = sshbuf_put_stringb(m, hostkeys)) != 0 ||
|
2020-01-31 22:42:45 +00:00
|
|
|
(r = sshbuf_put_stringb(m, inc)) != 0)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_fr(r, "compose config");
|
2024-05-17 00:30:23 +00:00
|
|
|
|
|
|
|
/* We need to fit the entire message inside the socket send buffer */
|
|
|
|
sz = ROUNDUP(sshbuf_len(m) + 5, 16*1024);
|
|
|
|
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1)
|
|
|
|
fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno));
|
|
|
|
|
2016-05-02 08:49:03 +00:00
|
|
|
if (ssh_msg_send(fd, 0, m) == -1)
|
2020-10-18 11:32:01 +00:00
|
|
|
error_f("ssh_msg_send failed");
|
2004-06-25 03:33:20 +00:00
|
|
|
|
2016-05-02 08:49:03 +00:00
|
|
|
sshbuf_free(m);
|
2020-01-31 22:42:45 +00:00
|
|
|
sshbuf_free(inc);
|
2024-05-17 00:30:23 +00:00
|
|
|
sshbuf_free(hostkeys);
|
2004-06-25 03:33:20 +00:00
|
|
|
|
2020-10-18 11:32:01 +00:00
|
|
|
debug3_f("done");
|
2004-06-25 03:33:20 +00:00
|
|
|
}
|
|
|
|
|
2006-08-18 14:31:39 +00:00
|
|
|
/*
|
|
|
|
* Listen for TCP connections
|
|
|
|
*/
|
|
|
|
static void
|
2017-10-25 00:15:35 +00:00
|
|
|
listen_on_addrs(struct listenaddr *la)
|
2006-08-18 14:31:39 +00:00
|
|
|
{
|
2017-10-25 00:15:35 +00:00
|
|
|
int ret, listen_sock;
|
2006-08-18 14:31:39 +00:00
|
|
|
struct addrinfo *ai;
|
|
|
|
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
|
|
|
|
|
2017-10-25 00:15:35 +00:00
|
|
|
for (ai = la->addrs; ai; ai = ai->ai_next) {
|
2006-08-18 14:31:39 +00:00
|
|
|
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
|
|
|
continue;
|
|
|
|
if (num_listen_socks >= MAX_LISTEN_SOCKS)
|
|
|
|
fatal("Too many listen sockets. "
|
|
|
|
"Enlarge MAX_LISTEN_SOCKS");
|
|
|
|
if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
|
|
|
|
ntop, sizeof(ntop), strport, sizeof(strport),
|
|
|
|
NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
|
|
|
|
error("getnameinfo failed: %.100s",
|
2007-12-28 15:43:51 +00:00
|
|
|
ssh_gai_strerror(ret));
|
2006-08-18 14:31:39 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* Create socket for listening. */
|
2010-01-09 23:31:12 +00:00
|
|
|
listen_sock = socket(ai->ai_family, ai->ai_socktype,
|
|
|
|
ai->ai_protocol);
|
2019-06-28 13:35:04 +00:00
|
|
|
if (listen_sock == -1) {
|
2006-08-18 14:31:39 +00:00
|
|
|
/* kernel may not support ipv6 */
|
|
|
|
verbose("socket: %.100s", strerror(errno));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (set_nonblock(listen_sock) == -1) {
|
|
|
|
close(listen_sock);
|
|
|
|
continue;
|
|
|
|
}
|
2017-02-24 03:16:34 +00:00
|
|
|
if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) == -1) {
|
|
|
|
verbose("socket: CLOEXEC: %s", strerror(errno));
|
|
|
|
close(listen_sock);
|
|
|
|
continue;
|
|
|
|
}
|
2017-10-25 00:15:35 +00:00
|
|
|
/* Socket options */
|
|
|
|
set_reuseaddr(listen_sock);
|
|
|
|
if (la->rdomain != NULL &&
|
|
|
|
set_rdomain(listen_sock, la->rdomain) == -1) {
|
|
|
|
close(listen_sock);
|
|
|
|
continue;
|
|
|
|
}
|
2006-08-18 14:31:39 +00:00
|
|
|
|
2008-01-19 21:56:00 +00:00
|
|
|
/* Only communicate in IPv6 over AF_INET6 sockets. */
|
2009-11-18 06:48:30 +00:00
|
|
|
if (ai->ai_family == AF_INET6)
|
|
|
|
sock_set_v6only(listen_sock);
|
2008-01-19 21:56:00 +00:00
|
|
|
|
2006-08-18 14:31:39 +00:00
|
|
|
debug("Bind to port %s on %s.", strport, ntop);
|
|
|
|
|
|
|
|
/* Bind the socket to the desired port. */
|
2019-06-28 13:35:04 +00:00
|
|
|
if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) {
|
2006-08-18 14:31:39 +00:00
|
|
|
error("Bind to port %s on %s failed: %.200s.",
|
|
|
|
strport, ntop, strerror(errno));
|
|
|
|
close(listen_sock);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
listen_socks[num_listen_socks] = listen_sock;
|
|
|
|
num_listen_socks++;
|
|
|
|
|
|
|
|
/* Start listening on the port. */
|
2019-06-28 13:35:04 +00:00
|
|
|
if (listen(listen_sock, SSH_LISTEN_BACKLOG) == -1)
|
2006-08-18 14:31:39 +00:00
|
|
|
fatal("listen on [%s]:%s: %.100s",
|
|
|
|
ntop, strport, strerror(errno));
|
2017-10-25 00:15:35 +00:00
|
|
|
logit("Server listening on %s port %s%s%s.",
|
|
|
|
ntop, strport,
|
|
|
|
la->rdomain == NULL ? "" : " rdomain ",
|
|
|
|
la->rdomain == NULL ? "" : la->rdomain);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
server_listen(void)
|
|
|
|
{
|
|
|
|
u_int i;
|
|
|
|
|
2021-01-09 12:10:02 +00:00
|
|
|
/* Initialise per-source limit tracking. */
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
srclimit_init(options.max_startups,
|
|
|
|
options.per_source_max_startups,
|
|
|
|
options.per_source_masklen_ipv4,
|
|
|
|
options.per_source_masklen_ipv6,
|
|
|
|
&options.per_source_penalty,
|
|
|
|
options.per_source_penalty_exempt);
|
2021-01-09 12:10:02 +00:00
|
|
|
|
2017-10-25 00:15:35 +00:00
|
|
|
for (i = 0; i < options.num_listen_addrs; i++) {
|
|
|
|
listen_on_addrs(&options.listen_addrs[i]);
|
|
|
|
freeaddrinfo(options.listen_addrs[i].addrs);
|
|
|
|
free(options.listen_addrs[i].rdomain);
|
|
|
|
memset(&options.listen_addrs[i], 0,
|
|
|
|
sizeof(options.listen_addrs[i]));
|
2006-08-18 14:31:39 +00:00
|
|
|
}
|
2017-10-25 00:15:35 +00:00
|
|
|
free(options.listen_addrs);
|
|
|
|
options.listen_addrs = NULL;
|
|
|
|
options.num_listen_addrs = 0;
|
2006-08-18 14:31:39 +00:00
|
|
|
|
|
|
|
if (!num_listen_socks)
|
|
|
|
fatal("Cannot bind any address.");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The main TCP accept loop. Note that, for the non-debug case, returns
|
|
|
|
* from this function are in a forked subprocess.
|
|
|
|
*/
|
|
|
|
static void
|
2024-05-17 00:30:23 +00:00
|
|
|
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
|
|
|
|
int log_stderr)
|
2006-08-18 14:31:39 +00:00
|
|
|
{
|
2021-11-14 18:47:43 +00:00
|
|
|
struct pollfd *pfd = NULL;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
int i, ret, npfd;
|
|
|
|
int oactive = -1, listening = 0, lameduck = 0;
|
2022-03-01 01:59:19 +00:00
|
|
|
int startup_p[2] = { -1 , -1 }, *startup_pollfd;
|
2019-03-01 02:32:39 +00:00
|
|
|
char c = 0;
|
2006-08-18 14:31:39 +00:00
|
|
|
struct sockaddr_storage from;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
struct early_child *child;
|
2006-08-18 14:31:39 +00:00
|
|
|
socklen_t fromlen;
|
2013-09-13 23:44:37 +00:00
|
|
|
u_char rnd[256];
|
2021-06-04 05:09:08 +00:00
|
|
|
sigset_t nsigset, osigset;
|
2006-08-18 14:31:39 +00:00
|
|
|
|
2020-03-13 03:17:07 +00:00
|
|
|
/* pipes connected to unauthenticated child sshd processes */
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
child_alloc();
|
2022-03-01 01:59:19 +00:00
|
|
|
startup_pollfd = xcalloc(options.max_startups, sizeof(int));
|
2006-08-18 14:31:39 +00:00
|
|
|
|
2021-06-04 05:09:08 +00:00
|
|
|
/*
|
|
|
|
* Prepare signal mask that we use to block signals that might set
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
* received_sigterm/hup/chld/info, so that we are guaranteed
|
2021-11-14 18:47:43 +00:00
|
|
|
* to immediately wake up the ppoll if a signal is received after
|
2021-06-04 05:09:08 +00:00
|
|
|
* the flag is checked.
|
|
|
|
*/
|
|
|
|
sigemptyset(&nsigset);
|
|
|
|
sigaddset(&nsigset, SIGHUP);
|
|
|
|
sigaddset(&nsigset, SIGCHLD);
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
#ifdef SIGINFO
|
|
|
|
sigaddset(&nsigset, SIGINFO);
|
|
|
|
#endif
|
2021-06-04 05:09:08 +00:00
|
|
|
sigaddset(&nsigset, SIGTERM);
|
|
|
|
sigaddset(&nsigset, SIGQUIT);
|
|
|
|
|
2022-03-01 01:59:19 +00:00
|
|
|
/* sized for worst-case */
|
2021-11-14 18:47:43 +00:00
|
|
|
pfd = xcalloc(num_listen_socks + options.max_startups,
|
|
|
|
sizeof(struct pollfd));
|
|
|
|
|
2006-08-18 14:31:39 +00:00
|
|
|
/*
|
|
|
|
* Stay listening for connections until the system crashes or
|
|
|
|
* the daemon is killed with a signal.
|
|
|
|
*/
|
|
|
|
for (;;) {
|
2021-06-04 05:09:08 +00:00
|
|
|
sigprocmask(SIG_BLOCK, &nsigset, &osigset);
|
|
|
|
if (received_sigterm) {
|
|
|
|
logit("Received signal %d; terminating.",
|
|
|
|
(int) received_sigterm);
|
|
|
|
close_listen_socks();
|
|
|
|
if (options.pid_file != NULL)
|
|
|
|
unlink(options.pid_file);
|
|
|
|
exit(received_sigterm == SIGTERM ? 0 : 255);
|
|
|
|
}
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (received_sigchld) {
|
|
|
|
child_reap_all_exited();
|
|
|
|
received_sigchld = 0;
|
|
|
|
}
|
|
|
|
if (received_siginfo) {
|
|
|
|
show_info();
|
|
|
|
received_siginfo = 0;
|
|
|
|
}
|
|
|
|
if (oactive != children_active) {
|
2020-01-24 23:56:01 +00:00
|
|
|
setproctitle("%s [listener] %d of %d-%d startups",
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
listener_proctitle, children_active,
|
2020-01-24 23:56:01 +00:00
|
|
|
options.max_startups_begin, options.max_startups);
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
oactive = children_active;
|
2020-01-21 22:39:57 +00:00
|
|
|
}
|
2019-03-01 02:32:39 +00:00
|
|
|
if (received_sighup) {
|
|
|
|
if (!lameduck) {
|
|
|
|
debug("Received SIGHUP; waiting for children");
|
|
|
|
close_listen_socks();
|
|
|
|
lameduck = 1;
|
|
|
|
}
|
2021-06-04 05:09:08 +00:00
|
|
|
if (listening <= 0) {
|
|
|
|
sigprocmask(SIG_SETMASK, &osigset, NULL);
|
2019-03-01 02:32:39 +00:00
|
|
|
sighup_restart();
|
2021-06-04 05:09:08 +00:00
|
|
|
}
|
2019-03-01 02:32:39 +00:00
|
|
|
}
|
2006-08-18 14:31:39 +00:00
|
|
|
|
2021-11-14 18:47:43 +00:00
|
|
|
for (i = 0; i < num_listen_socks; i++) {
|
|
|
|
pfd[i].fd = listen_socks[i];
|
|
|
|
pfd[i].events = POLLIN;
|
|
|
|
}
|
2022-03-01 01:59:19 +00:00
|
|
|
npfd = num_listen_socks;
|
2021-11-14 18:47:43 +00:00
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
2022-03-01 01:59:19 +00:00
|
|
|
startup_pollfd[i] = -1;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (children[i].pipefd != -1) {
|
|
|
|
pfd[npfd].fd = children[i].pipefd;
|
2022-03-01 01:59:19 +00:00
|
|
|
pfd[npfd].events = POLLIN;
|
|
|
|
startup_pollfd[i] = npfd++;
|
|
|
|
}
|
2021-11-14 18:47:43 +00:00
|
|
|
}
|
2006-08-18 14:31:39 +00:00
|
|
|
|
2021-06-04 05:09:08 +00:00
|
|
|
/* Wait until a connection arrives or a child exits. */
|
2022-03-01 01:59:19 +00:00
|
|
|
ret = ppoll(pfd, npfd, NULL, &osigset);
|
|
|
|
if (ret == -1 && errno != EINTR) {
|
2021-11-14 18:47:43 +00:00
|
|
|
error("ppoll: %.100s", strerror(errno));
|
2022-03-01 01:59:19 +00:00
|
|
|
if (errno == EINVAL)
|
|
|
|
cleanup_exit(1); /* can't recover */
|
|
|
|
}
|
2021-06-04 05:09:08 +00:00
|
|
|
sigprocmask(SIG_SETMASK, &osigset, NULL);
|
2021-06-10 03:14:14 +00:00
|
|
|
if (ret == -1)
|
2006-08-18 14:31:39 +00:00
|
|
|
continue;
|
|
|
|
|
2019-03-01 02:32:39 +00:00
|
|
|
for (i = 0; i < options.max_startups; i++) {
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (children[i].pipefd == -1 ||
|
2022-03-01 01:59:19 +00:00
|
|
|
startup_pollfd[i] == -1 ||
|
|
|
|
!(pfd[startup_pollfd[i]].revents & (POLLIN|POLLHUP)))
|
2019-03-01 02:32:39 +00:00
|
|
|
continue;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
switch (read(children[i].pipefd, &c, sizeof(c))) {
|
2019-03-01 02:32:39 +00:00
|
|
|
case -1:
|
|
|
|
if (errno == EINTR || errno == EAGAIN)
|
|
|
|
continue;
|
|
|
|
if (errno != EPIPE) {
|
2020-10-18 11:32:01 +00:00
|
|
|
error_f("startup pipe %d (fd=%d): "
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
"read %s", i, children[i].pipefd,
|
2020-10-18 11:32:01 +00:00
|
|
|
strerror(errno));
|
2019-03-01 02:32:39 +00:00
|
|
|
}
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
case 0:
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
/* child exited preauth */
|
|
|
|
if (children[i].early)
|
2019-03-01 02:32:39 +00:00
|
|
|
listening--;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
srclimit_done(children[i].pipefd);
|
|
|
|
child_close(&(children[i]), 0, 0);
|
2019-03-01 02:32:39 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (children[i].early && c == '\0') {
|
|
|
|
/* child has finished preliminaries */
|
2019-03-01 02:32:39 +00:00
|
|
|
listening--;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
children[i].early = 0;
|
|
|
|
debug2_f("child %lu for %s received "
|
|
|
|
"config", (long)children[i].pid,
|
|
|
|
children[i].id);
|
|
|
|
} else if (!children[i].early && c == '\001') {
|
|
|
|
/* child has completed auth */
|
|
|
|
debug2_f("child %lu for %s auth done",
|
|
|
|
(long)children[i].pid,
|
|
|
|
children[i].id);
|
|
|
|
child_close(&(children[i]), 1, 0);
|
|
|
|
} else {
|
|
|
|
error_f("unexpected message 0x%02x "
|
|
|
|
"child %ld for %s in state %d",
|
|
|
|
(int)c, (long)children[i].pid,
|
|
|
|
children[i].id, children[i].early);
|
2019-03-01 02:32:39 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-08-18 14:31:39 +00:00
|
|
|
}
|
2019-03-01 02:32:39 +00:00
|
|
|
}
|
2006-08-18 14:31:39 +00:00
|
|
|
for (i = 0; i < num_listen_socks; i++) {
|
2021-11-14 18:47:43 +00:00
|
|
|
if (!(pfd[i].revents & POLLIN))
|
2006-08-18 14:31:39 +00:00
|
|
|
continue;
|
|
|
|
fromlen = sizeof(from);
|
|
|
|
*newsock = accept(listen_socks[i],
|
|
|
|
(struct sockaddr *)&from, &fromlen);
|
2019-06-28 13:35:04 +00:00
|
|
|
if (*newsock == -1) {
|
2013-04-23 05:20:43 +00:00
|
|
|
if (errno != EINTR && errno != EWOULDBLOCK &&
|
|
|
|
errno != ECONNABORTED && errno != EAGAIN)
|
2012-04-22 01:23:46 +00:00
|
|
|
error("accept: %.100s",
|
|
|
|
strerror(errno));
|
|
|
|
if (errno == EMFILE || errno == ENFILE)
|
|
|
|
usleep(100 * 1000);
|
2006-08-18 14:31:39 +00:00
|
|
|
continue;
|
|
|
|
}
|
2022-06-17 01:00:03 +00:00
|
|
|
if (unset_nonblock(*newsock) == -1) {
|
|
|
|
close(*newsock);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (pipe(startup_p) == -1) {
|
|
|
|
error_f("pipe(startup_p): %s", strerror(errno));
|
2021-11-18 03:07:59 +00:00
|
|
|
close(*newsock);
|
2021-01-09 12:10:02 +00:00
|
|
|
continue;
|
2021-11-18 03:07:59 +00:00
|
|
|
}
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
if (drop_connection(*newsock,
|
|
|
|
children_active, startup_p[0])) {
|
2006-08-18 14:31:39 +00:00
|
|
|
close(*newsock);
|
2021-01-09 12:10:02 +00:00
|
|
|
close(startup_p[0]);
|
|
|
|
close(startup_p[1]);
|
2006-08-18 14:31:39 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
if (socketpair(AF_UNIX,
|
2006-08-18 14:31:39 +00:00
|
|
|
SOCK_STREAM, 0, config_s) == -1) {
|
|
|
|
error("reexec socketpair: %s",
|
|
|
|
strerror(errno));
|
|
|
|
close(*newsock);
|
|
|
|
close(startup_p[0]);
|
|
|
|
close(startup_p[1]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Got connection. Fork a child to handle it, unless
|
|
|
|
* we are in debugging mode.
|
|
|
|
*/
|
|
|
|
if (debug_flag) {
|
|
|
|
/*
|
|
|
|
* In debugging mode. Close the listening
|
|
|
|
* socket, and start processing the
|
|
|
|
* connection without forking.
|
|
|
|
*/
|
|
|
|
debug("Server will not fork when running in debugging mode.");
|
|
|
|
close_listen_socks();
|
|
|
|
*sock_in = *newsock;
|
|
|
|
*sock_out = *newsock;
|
|
|
|
close(startup_p[0]);
|
|
|
|
close(startup_p[1]);
|
|
|
|
startup_pipe = -1;
|
2024-05-17 00:30:23 +00:00
|
|
|
send_rexec_state(config_s[0], cfg);
|
|
|
|
close(config_s[0]);
|
2021-11-14 18:47:43 +00:00
|
|
|
free(pfd);
|
2019-03-01 02:32:39 +00:00
|
|
|
return;
|
2006-08-18 14:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Normal production daemon. Fork, and have
|
|
|
|
* the child process the connection. The
|
|
|
|
* parent continues listening.
|
|
|
|
*/
|
2006-08-30 17:24:41 +00:00
|
|
|
platform_pre_fork();
|
2019-03-01 02:32:39 +00:00
|
|
|
listening++;
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
child = child_register(startup_p[0], *newsock);
|
|
|
|
if ((child->pid = fork()) == 0) {
|
2006-08-18 14:31:39 +00:00
|
|
|
/*
|
|
|
|
* Child. Close the listening and
|
|
|
|
* max_startup sockets. Start using
|
|
|
|
* the accepted socket. Reinitialize
|
|
|
|
* logging (since our pid has changed).
|
2019-03-01 02:32:39 +00:00
|
|
|
* We return from this function to handle
|
2006-08-18 14:31:39 +00:00
|
|
|
* the connection.
|
|
|
|
*/
|
2006-08-30 17:24:41 +00:00
|
|
|
platform_post_fork_child();
|
2006-08-18 14:31:39 +00:00
|
|
|
startup_pipe = startup_p[1];
|
|
|
|
close_startup_pipes();
|
|
|
|
close_listen_socks();
|
|
|
|
*sock_in = *newsock;
|
|
|
|
*sock_out = *newsock;
|
|
|
|
log_init(__progname,
|
|
|
|
options.log_level,
|
|
|
|
options.log_facility,
|
|
|
|
log_stderr);
|
2024-05-17 00:30:23 +00:00
|
|
|
close(config_s[0]);
|
2021-11-14 18:47:43 +00:00
|
|
|
free(pfd);
|
2019-03-01 02:32:39 +00:00
|
|
|
return;
|
2006-08-18 14:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Parent. Stay in the loop. */
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
platform_post_fork_parent(child->pid);
|
|
|
|
if (child->pid == -1)
|
2006-08-18 14:31:39 +00:00
|
|
|
error("fork: %.100s", strerror(errno));
|
|
|
|
else
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
debug("Forked child %ld.", (long)child->pid);
|
2006-08-18 14:31:39 +00:00
|
|
|
|
|
|
|
close(startup_p[1]);
|
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
close(config_s[1]);
|
|
|
|
send_rexec_state(config_s[0], cfg);
|
|
|
|
close(config_s[0]);
|
2006-08-18 14:31:39 +00:00
|
|
|
close(*newsock);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ensure that our random state differs
|
|
|
|
* from that of the child
|
|
|
|
*/
|
|
|
|
arc4random_stir();
|
2013-09-13 23:44:37 +00:00
|
|
|
arc4random_buf(rnd, sizeof(rnd));
|
2015-01-14 15:21:31 +00:00
|
|
|
#ifdef WITH_OPENSSL
|
2013-09-13 23:44:37 +00:00
|
|
|
RAND_seed(rnd, sizeof(rnd));
|
2015-11-14 07:44:49 +00:00
|
|
|
if ((RAND_bytes((u_char *)rnd, 1)) != 1)
|
|
|
|
fatal("%s: RAND_bytes failed", __func__);
|
2015-01-14 15:21:31 +00:00
|
|
|
#endif
|
2014-02-04 00:18:20 +00:00
|
|
|
explicit_bzero(rnd, sizeof(rnd));
|
2006-08-18 14:31:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-13 03:57:26 +00:00
|
|
|
static void
|
|
|
|
accumulate_host_timing_secret(struct sshbuf *server_cfg,
|
2019-06-21 04:21:04 +00:00
|
|
|
struct sshkey *key)
|
2018-04-13 03:57:26 +00:00
|
|
|
{
|
|
|
|
static struct ssh_digest_ctx *ctx;
|
|
|
|
u_char *hash;
|
|
|
|
size_t len;
|
|
|
|
struct sshbuf *buf;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
if (ctx == NULL && (ctx = ssh_digest_start(SSH_DIGEST_SHA512)) == NULL)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_f("ssh_digest_start");
|
2018-04-13 03:57:26 +00:00
|
|
|
if (key == NULL) { /* finalize */
|
|
|
|
/* add server config in case we are using agent for host keys */
|
|
|
|
if (ssh_digest_update(ctx, sshbuf_ptr(server_cfg),
|
|
|
|
sshbuf_len(server_cfg)) != 0)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_f("ssh_digest_update");
|
2018-04-13 03:57:26 +00:00
|
|
|
len = ssh_digest_bytes(SSH_DIGEST_SHA512);
|
|
|
|
hash = xmalloc(len);
|
|
|
|
if (ssh_digest_final(ctx, hash, len) != 0)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_f("ssh_digest_final");
|
2018-04-13 03:57:26 +00:00
|
|
|
options.timing_secret = PEEK_U64(hash);
|
|
|
|
freezero(hash, len);
|
|
|
|
ssh_digest_free(ctx);
|
|
|
|
ctx = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ((buf = sshbuf_new()) == NULL)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_f("could not allocate buffer");
|
2018-04-13 03:57:26 +00:00
|
|
|
if ((r = sshkey_private_serialize(key, buf)) != 0)
|
2022-10-28 00:44:17 +00:00
|
|
|
fatal_fr(r, "encode %s key", sshkey_ssh_name(key));
|
2018-04-13 03:57:26 +00:00
|
|
|
if (ssh_digest_update(ctx, sshbuf_ptr(buf), sshbuf_len(buf)) != 0)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_f("ssh_digest_update");
|
2018-04-13 03:57:26 +00:00
|
|
|
sshbuf_reset(buf);
|
|
|
|
sshbuf_free(buf);
|
|
|
|
}
|
|
|
|
|
2020-01-24 23:56:01 +00:00
|
|
|
static char *
|
|
|
|
prepare_proctitle(int ac, char **av)
|
|
|
|
{
|
|
|
|
char *ret = NULL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ac; i++)
|
|
|
|
xextendf(&ret, " ", "%s", av[i]);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2023-02-10 04:47:19 +00:00
|
|
|
static void
|
2024-05-17 00:30:23 +00:00
|
|
|
print_config(struct connection_info *connection_info)
|
2023-02-10 04:47:19 +00:00
|
|
|
{
|
|
|
|
connection_info->test = 1;
|
|
|
|
parse_server_match_config(&options, &includes, connection_info);
|
|
|
|
dump_config(&options);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/*
|
|
|
|
* Main program for the daemon.
|
|
|
|
*/
|
1999-10-27 03:42:43 +00:00
|
|
|
int
|
|
|
|
main(int ac, char **av)
|
|
|
|
{
|
1999-11-24 13:26:21 +00:00
|
|
|
extern char *optarg;
|
|
|
|
extern int optind;
|
2024-05-17 00:30:23 +00:00
|
|
|
int log_stderr = 0, inetd_flag = 0, test_flag = 0, no_daemon_flag = 0;
|
|
|
|
char *config_file_name = _PATH_SERVER_CONFIG_FILE;
|
|
|
|
int r, opt, do_dump_cfg = 0, keytype, already_daemon, have_agent = 0;
|
|
|
|
int sock_in = -1, sock_out = -1, newsock = -1, rexec_argc = 0;
|
2024-06-01 07:03:37 +00:00
|
|
|
int devnull, config_s[2] = { -1 , -1 }, have_connection_info = 0;
|
2024-05-31 09:11:14 +00:00
|
|
|
int need_chroot = 1;
|
2024-05-17 00:30:23 +00:00
|
|
|
char *fp, *line, *logfile = NULL, **rexec_argv = NULL;
|
|
|
|
struct stat sb;
|
2017-10-05 15:52:03 +00:00
|
|
|
u_int i, j;
|
2008-06-15 21:50:58 +00:00
|
|
|
mode_t new_umask;
|
2017-05-30 08:52:19 +00:00
|
|
|
struct sshkey *key;
|
|
|
|
struct sshkey *pubkey;
|
2024-05-17 00:30:23 +00:00
|
|
|
struct connection_info connection_info;
|
2022-12-16 06:56:47 +00:00
|
|
|
sigset_t sigmask;
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
memset(&connection_info, 0, sizeof(connection_info));
|
2002-04-25 18:17:04 +00:00
|
|
|
#ifdef HAVE_SECUREWARE
|
|
|
|
(void)set_auth_parameters(ac, av);
|
|
|
|
#endif
|
2003-08-21 23:34:41 +00:00
|
|
|
__progname = ssh_get_progname(av[0]);
|
2000-07-09 12:42:32 +00:00
|
|
|
|
2022-12-16 06:56:47 +00:00
|
|
|
sigemptyset(&sigmask);
|
|
|
|
sigprocmask(SIG_SETMASK, &sigmask, NULL);
|
|
|
|
|
2003-01-09 22:53:12 +00:00
|
|
|
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
|
2000-06-28 05:22:41 +00:00
|
|
|
saved_argc = ac;
|
2004-06-25 04:22:23 +00:00
|
|
|
rexec_argc = ac;
|
2006-05-04 06:24:34 +00:00
|
|
|
saved_argv = xcalloc(ac + 1, sizeof(*saved_argv));
|
2017-10-23 05:25:24 +00:00
|
|
|
for (i = 0; (int)i < ac; i++)
|
2003-01-09 22:53:12 +00:00
|
|
|
saved_argv[i] = xstrdup(av[i]);
|
2003-05-15 11:29:10 +00:00
|
|
|
saved_argv[i] = NULL;
|
2003-01-09 22:53:12 +00:00
|
|
|
|
|
|
|
#ifndef HAVE_SETPROCTITLE
|
|
|
|
/* Prepare for later setproctitle emulation */
|
|
|
|
compat_init_setproctitle(ac, av);
|
2003-06-02 02:15:54 +00:00
|
|
|
av = saved_argv;
|
2003-01-09 22:53:12 +00:00
|
|
|
#endif
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2004-03-21 22:29:57 +00:00
|
|
|
if (geteuid() == 0 && setgroups(0, NULL) == -1)
|
|
|
|
debug("setgroups(): %.200s", strerror(errno));
|
|
|
|
|
2005-10-03 08:11:24 +00:00
|
|
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
|
|
|
sanitise_stdfd();
|
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/* Initialize configuration options to their default values. */
|
|
|
|
initialize_server_options(&options);
|
|
|
|
|
|
|
|
/* Parse command-line arguments. */
|
2015-05-24 23:39:16 +00:00
|
|
|
while ((opt = getopt(ac, av,
|
2023-02-10 04:47:19 +00:00
|
|
|
"C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
|
1999-11-24 13:26:21 +00:00
|
|
|
switch (opt) {
|
2000-01-14 04:45:46 +00:00
|
|
|
case '4':
|
2005-01-19 23:57:56 +00:00
|
|
|
options.address_family = AF_INET;
|
2000-01-14 04:45:46 +00:00
|
|
|
break;
|
|
|
|
case '6':
|
2005-01-19 23:57:56 +00:00
|
|
|
options.address_family = AF_INET6;
|
2000-01-14 04:45:46 +00:00
|
|
|
break;
|
1999-11-24 13:26:21 +00:00
|
|
|
case 'f':
|
|
|
|
config_file_name = optarg;
|
|
|
|
break;
|
2010-02-26 20:55:05 +00:00
|
|
|
case 'c':
|
2017-10-05 15:52:03 +00:00
|
|
|
servconf_add_hostcert("[command-line]", 0,
|
|
|
|
&options, optarg);
|
2010-02-26 20:55:05 +00:00
|
|
|
break;
|
1999-11-24 13:26:21 +00:00
|
|
|
case 'd':
|
2003-07-19 09:54:31 +00:00
|
|
|
if (debug_flag == 0) {
|
2000-09-16 02:29:08 +00:00
|
|
|
debug_flag = 1;
|
|
|
|
options.log_level = SYSLOG_LEVEL_DEBUG1;
|
2003-07-19 09:54:31 +00:00
|
|
|
} else if (options.log_level < SYSLOG_LEVEL_DEBUG3)
|
2000-09-16 02:29:08 +00:00
|
|
|
options.log_level++;
|
1999-11-24 13:26:21 +00:00
|
|
|
break;
|
2000-12-02 19:03:54 +00:00
|
|
|
case 'D':
|
|
|
|
no_daemon_flag = 1;
|
|
|
|
break;
|
2023-02-10 04:47:19 +00:00
|
|
|
case 'G':
|
|
|
|
do_dump_cfg = 1;
|
|
|
|
break;
|
2013-04-23 05:21:06 +00:00
|
|
|
case 'E':
|
2015-09-04 08:21:47 +00:00
|
|
|
logfile = optarg;
|
2013-04-23 05:21:06 +00:00
|
|
|
/* FALLTHROUGH */
|
2001-04-11 23:10:09 +00:00
|
|
|
case 'e':
|
|
|
|
log_stderr = 1;
|
|
|
|
break;
|
1999-11-24 13:26:21 +00:00
|
|
|
case 'i':
|
|
|
|
inetd_flag = 1;
|
|
|
|
break;
|
2004-06-25 03:33:20 +00:00
|
|
|
case 'r':
|
2024-05-31 09:01:08 +00:00
|
|
|
logit("-r option is deprecated");
|
2004-06-25 03:33:20 +00:00
|
|
|
break;
|
|
|
|
case 'R':
|
2024-05-17 00:30:23 +00:00
|
|
|
fatal("-R not supported here");
|
2004-06-25 03:33:20 +00:00
|
|
|
break;
|
1999-11-24 13:26:21 +00:00
|
|
|
case 'Q':
|
2001-01-29 08:07:43 +00:00
|
|
|
/* ignored */
|
1999-11-24 13:26:21 +00:00
|
|
|
break;
|
|
|
|
case 'q':
|
|
|
|
options.log_level = SYSLOG_LEVEL_QUIET;
|
|
|
|
break;
|
|
|
|
case 'b':
|
2016-08-15 12:27:56 +00:00
|
|
|
/* protocol 1, ignored */
|
1999-11-24 13:26:21 +00:00
|
|
|
break;
|
|
|
|
case 'p':
|
2000-01-14 04:45:46 +00:00
|
|
|
options.ports_from_cmdline = 1;
|
2000-09-16 02:29:08 +00:00
|
|
|
if (options.num_ports >= MAX_PORTS) {
|
|
|
|
fprintf(stderr, "too many ports.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2001-04-12 23:39:26 +00:00
|
|
|
options.ports[options.num_ports++] = a2port(optarg);
|
2009-01-28 05:31:22 +00:00
|
|
|
if (options.ports[options.num_ports-1] <= 0) {
|
2001-04-12 23:39:26 +00:00
|
|
|
fprintf(stderr, "Bad port number.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
1999-11-24 13:26:21 +00:00
|
|
|
break;
|
|
|
|
case 'g':
|
2001-06-05 19:59:08 +00:00
|
|
|
if ((options.login_grace_time = convtime(optarg)) == -1) {
|
|
|
|
fprintf(stderr, "Invalid login grace time.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
1999-11-24 13:26:21 +00:00
|
|
|
break;
|
|
|
|
case 'k':
|
2016-08-15 12:27:56 +00:00
|
|
|
/* protocol 1, ignored */
|
1999-11-24 13:26:21 +00:00
|
|
|
break;
|
|
|
|
case 'h':
|
2017-10-05 15:52:03 +00:00
|
|
|
servconf_add_hostkey("[command-line]", 0,
|
2018-11-19 04:12:32 +00:00
|
|
|
&options, optarg, 1);
|
1999-11-24 13:26:21 +00:00
|
|
|
break;
|
2001-08-06 21:09:07 +00:00
|
|
|
case 't':
|
|
|
|
test_flag = 1;
|
|
|
|
break;
|
2008-06-10 13:01:51 +00:00
|
|
|
case 'T':
|
|
|
|
test_flag = 2;
|
|
|
|
break;
|
|
|
|
case 'C':
|
2024-05-17 00:30:23 +00:00
|
|
|
if (parse_server_match_testspec(&connection_info,
|
2012-05-19 09:37:01 +00:00
|
|
|
optarg) == -1)
|
|
|
|
exit(1);
|
2024-05-17 00:30:23 +00:00
|
|
|
have_connection_info = 1;
|
2008-06-10 13:01:51 +00:00
|
|
|
break;
|
2000-08-18 03:59:06 +00:00
|
|
|
case 'u':
|
2015-01-20 23:14:00 +00:00
|
|
|
utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL);
|
|
|
|
if (utmp_len > HOST_NAME_MAX+1) {
|
2002-07-23 21:15:13 +00:00
|
|
|
fprintf(stderr, "Invalid utmp length.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2000-08-18 03:59:06 +00:00
|
|
|
break;
|
2001-12-06 18:22:17 +00:00
|
|
|
case 'o':
|
2003-12-17 05:29:22 +00:00
|
|
|
line = xstrdup(optarg);
|
|
|
|
if (process_server_config_line(&options, line,
|
2020-01-31 22:42:45 +00:00
|
|
|
"command-line", 0, NULL, NULL, &includes) != 0)
|
2001-12-21 03:45:46 +00:00
|
|
|
exit(1);
|
2013-06-01 21:31:17 +00:00
|
|
|
free(line);
|
2001-12-06 18:22:17 +00:00
|
|
|
break;
|
2023-01-18 01:50:21 +00:00
|
|
|
case 'V':
|
|
|
|
fprintf(stderr, "%s, %s\n",
|
2023-08-25 04:48:02 +00:00
|
|
|
SSH_RELEASE, SSH_OPENSSL_VERSION);
|
2023-01-18 01:50:21 +00:00
|
|
|
exit(0);
|
1999-11-24 13:26:21 +00:00
|
|
|
default:
|
2001-12-06 18:22:17 +00:00
|
|
|
usage();
|
|
|
|
break;
|
1999-11-24 13:26:21 +00:00
|
|
|
}
|
|
|
|
}
|
2024-09-12 00:36:27 +00:00
|
|
|
if (!test_flag && !inetd_flag && !do_dump_cfg && !path_absolute(av[0]))
|
2024-05-17 00:30:23 +00:00
|
|
|
fatal("sshd requires execution with an absolute path");
|
2024-06-01 07:03:37 +00:00
|
|
|
|
|
|
|
closefrom(STDERR_FILENO + 1);
|
|
|
|
|
|
|
|
/* Reserve fds we'll need later for reexec things */
|
|
|
|
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
|
|
|
|
fatal("open %s: %s", _PATH_DEVNULL, strerror(errno));
|
|
|
|
while (devnull < REEXEC_MIN_FREE_FD) {
|
|
|
|
if ((devnull = dup(devnull)) == -1)
|
|
|
|
fatal("dup %s: %s", _PATH_DEVNULL, strerror(errno));
|
|
|
|
}
|
2004-06-25 03:33:20 +00:00
|
|
|
|
2022-11-08 22:23:47 +00:00
|
|
|
seed_rng();
|
|
|
|
|
2013-04-23 05:21:06 +00:00
|
|
|
/* If requested, redirect the logs to the specified logfile. */
|
2024-05-17 00:30:23 +00:00
|
|
|
if (logfile != NULL) {
|
|
|
|
char *cp, pid_s[32];
|
|
|
|
|
|
|
|
snprintf(pid_s, sizeof(pid_s), "%ld", (unsigned long)getpid());
|
|
|
|
cp = percent_expand(logfile,
|
|
|
|
"p", pid_s,
|
|
|
|
"P", "sshd",
|
|
|
|
(char *)NULL);
|
|
|
|
log_redirect_stderr_to(cp);
|
|
|
|
free(cp);
|
|
|
|
}
|
|
|
|
|
2000-01-14 04:45:46 +00:00
|
|
|
/*
|
|
|
|
* Force logging to stderr until we have loaded the private host
|
|
|
|
* key (unless started from inetd)
|
|
|
|
*/
|
2000-12-13 17:45:15 +00:00
|
|
|
log_init(__progname,
|
2002-02-08 11:01:54 +00:00
|
|
|
options.log_level == SYSLOG_LEVEL_NOT_SET ?
|
|
|
|
SYSLOG_LEVEL_INFO : options.log_level,
|
|
|
|
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
|
|
|
|
SYSLOG_FACILITY_AUTH : options.log_facility,
|
2020-01-31 23:11:25 +00:00
|
|
|
log_stderr || !inetd_flag || debug_flag);
|
2000-01-14 04:45:46 +00:00
|
|
|
|
2004-03-08 11:59:03 +00:00
|
|
|
/*
|
|
|
|
* Unset KRB5CCNAME, otherwise the user's session may inherit it from
|
|
|
|
* root's environment
|
2005-07-17 07:04:47 +00:00
|
|
|
*/
|
2005-02-02 07:30:33 +00:00
|
|
|
if (getenv("KRB5CCNAME") != NULL)
|
2012-02-14 18:03:30 +00:00
|
|
|
(void) unsetenv("KRB5CCNAME");
|
2005-02-02 07:30:33 +00:00
|
|
|
|
2004-06-25 03:33:20 +00:00
|
|
|
sensitive_data.have_ssh2_key = 0;
|
|
|
|
|
2008-06-10 13:01:51 +00:00
|
|
|
/*
|
2017-11-03 03:18:53 +00:00
|
|
|
* If we're not doing an extended test do not silently ignore connection
|
|
|
|
* test params.
|
2008-06-10 13:01:51 +00:00
|
|
|
*/
|
2024-05-17 00:30:23 +00:00
|
|
|
if (test_flag < 2 && have_connection_info)
|
2008-06-10 13:01:51 +00:00
|
|
|
fatal("Config test connection parameter (-C) provided without "
|
2021-04-03 06:18:40 +00:00
|
|
|
"test mode (-T)");
|
2008-06-10 13:01:51 +00:00
|
|
|
|
2004-06-25 03:33:20 +00:00
|
|
|
/* Fetch our configuration */
|
2018-07-09 21:29:36 +00:00
|
|
|
if ((cfg = sshbuf_new()) == NULL)
|
2024-05-17 00:30:23 +00:00
|
|
|
fatal("sshbuf_new config failed");
|
|
|
|
if (strcasecmp(config_file_name, "none") != 0)
|
2018-07-09 21:29:36 +00:00
|
|
|
load_server_config(config_file_name, cfg);
|
2004-06-25 03:33:20 +00:00
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
parse_server_config(&options, config_file_name, cfg,
|
|
|
|
&includes, NULL, 0);
|
2021-03-12 04:08:19 +00:00
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/* Fill in default values for those options not explicitly set. */
|
|
|
|
fill_default_server_options(&options);
|
|
|
|
|
2012-11-04 11:23:14 +00:00
|
|
|
/* Check that options are sensible */
|
|
|
|
if (options.authorized_keys_command_user == NULL &&
|
|
|
|
(options.authorized_keys_command != NULL &&
|
|
|
|
strcasecmp(options.authorized_keys_command, "none") != 0))
|
|
|
|
fatal("AuthorizedKeysCommand set without "
|
|
|
|
"AuthorizedKeysCommandUser");
|
2015-05-21 06:43:30 +00:00
|
|
|
if (options.authorized_principals_command_user == NULL &&
|
|
|
|
(options.authorized_principals_command != NULL &&
|
|
|
|
strcasecmp(options.authorized_principals_command, "none") != 0))
|
|
|
|
fatal("AuthorizedPrincipalsCommand set without "
|
|
|
|
"AuthorizedPrincipalsCommandUser");
|
2012-11-04 11:23:14 +00:00
|
|
|
|
2012-11-04 12:21:40 +00:00
|
|
|
/*
|
|
|
|
* Check whether there is any path through configured auth methods.
|
|
|
|
* Unfortunately it is not possible to verify this generally before
|
2024-05-17 00:30:23 +00:00
|
|
|
* daemonisation in the presence of Match blocks, but this catches
|
2012-11-04 12:21:40 +00:00
|
|
|
* and warns for trivial misconfigurations that could break login.
|
|
|
|
*/
|
|
|
|
if (options.num_auth_methods != 0) {
|
2017-10-05 15:52:03 +00:00
|
|
|
for (i = 0; i < options.num_auth_methods; i++) {
|
|
|
|
if (auth2_methods_valid(options.auth_methods[i],
|
2012-11-04 12:21:40 +00:00
|
|
|
1) == 0)
|
|
|
|
break;
|
|
|
|
}
|
2017-10-05 15:52:03 +00:00
|
|
|
if (i >= options.num_auth_methods)
|
2012-11-04 12:21:40 +00:00
|
|
|
fatal("AuthenticationMethods cannot be satisfied by "
|
|
|
|
"enabled authentication methods");
|
|
|
|
}
|
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/* Check that there are no remaining arguments. */
|
|
|
|
if (optind < ac) {
|
|
|
|
fprintf(stderr, "Extra argument %s.\n", av[optind]);
|
|
|
|
exit(1);
|
1999-10-27 03:42:43 +00:00
|
|
|
}
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2020-11-08 11:46:12 +00:00
|
|
|
debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION);
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2023-02-10 04:47:19 +00:00
|
|
|
if (do_dump_cfg)
|
2024-05-17 00:30:23 +00:00
|
|
|
print_config(&connection_info);
|
2006-09-07 00:36:43 +00:00
|
|
|
|
2013-07-20 03:21:52 +00:00
|
|
|
/* load host keys */
|
2006-03-26 03:19:21 +00:00
|
|
|
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
|
2017-05-30 08:52:19 +00:00
|
|
|
sizeof(struct sshkey *));
|
2013-07-20 03:21:52 +00:00
|
|
|
sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
|
2017-05-30 08:52:19 +00:00
|
|
|
sizeof(struct sshkey *));
|
2013-07-20 03:21:52 +00:00
|
|
|
|
|
|
|
if (options.host_key_agent) {
|
|
|
|
if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
|
|
|
|
setenv(SSH_AUTHSOCKET_ENV_NAME,
|
|
|
|
options.host_key_agent, 1);
|
2015-01-17 18:53:34 +00:00
|
|
|
if ((r = ssh_get_authentication_socket(NULL)) == 0)
|
|
|
|
have_agent = 1;
|
|
|
|
else
|
2020-10-18 11:32:01 +00:00
|
|
|
error_r(r, "Could not connect to agent \"%s\"",
|
|
|
|
options.host_key_agent);
|
2013-07-20 03:21:52 +00:00
|
|
|
}
|
2000-04-29 13:57:08 +00:00
|
|
|
|
2001-12-21 03:45:46 +00:00
|
|
|
for (i = 0; i < options.num_host_key_files; i++) {
|
2018-11-19 04:12:32 +00:00
|
|
|
int ll = options.host_key_file_userprovided[i] ?
|
|
|
|
SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_DEBUG1;
|
|
|
|
|
2014-12-22 07:55:51 +00:00
|
|
|
if (options.host_key_files[i] == NULL)
|
|
|
|
continue;
|
2018-07-11 18:53:29 +00:00
|
|
|
if ((r = sshkey_load_private(options.host_key_files[i], "",
|
|
|
|
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
|
2020-10-18 11:32:01 +00:00
|
|
|
do_log2_r(r, ll, "Unable to load host key \"%s\"",
|
|
|
|
options.host_key_files[i]);
|
2019-12-15 18:57:30 +00:00
|
|
|
if (sshkey_is_sk(key) &&
|
|
|
|
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
|
|
|
|
debug("host key %s requires user presence, ignoring",
|
|
|
|
options.host_key_files[i]);
|
|
|
|
key->sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
|
|
|
|
}
|
|
|
|
if (r == 0 && key != NULL &&
|
|
|
|
(r = sshkey_shield_private(key)) != 0) {
|
2020-10-18 11:32:01 +00:00
|
|
|
do_log2_r(r, ll, "Unable to shield host key \"%s\"",
|
|
|
|
options.host_key_files[i]);
|
2019-06-21 04:21:04 +00:00
|
|
|
sshkey_free(key);
|
|
|
|
key = NULL;
|
|
|
|
}
|
2018-07-11 18:53:29 +00:00
|
|
|
if ((r = sshkey_load_public(options.host_key_files[i],
|
|
|
|
&pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
|
2020-10-18 11:32:01 +00:00
|
|
|
do_log2_r(r, ll, "Unable to load host key \"%s\"",
|
|
|
|
options.host_key_files[i]);
|
2020-06-18 23:34:19 +00:00
|
|
|
if (pubkey != NULL && key != NULL) {
|
|
|
|
if (!sshkey_equal(pubkey, key)) {
|
|
|
|
error("Public key for %s does not match "
|
|
|
|
"private key", options.host_key_files[i]);
|
|
|
|
sshkey_free(pubkey);
|
|
|
|
pubkey = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pubkey == NULL && key != NULL) {
|
2018-09-13 02:08:33 +00:00
|
|
|
if ((r = sshkey_from_private(key, &pubkey)) != 0)
|
2020-10-18 11:32:01 +00:00
|
|
|
fatal_r(r, "Could not demote key: \"%s\"",
|
|
|
|
options.host_key_files[i]);
|
2020-06-18 23:34:19 +00:00
|
|
|
}
|
2022-09-17 10:34:29 +00:00
|
|
|
if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey,
|
|
|
|
options.required_rsa_size)) != 0) {
|
|
|
|
error_fr(r, "Host key %s", options.host_key_files[i]);
|
|
|
|
sshkey_free(pubkey);
|
|
|
|
sshkey_free(key);
|
|
|
|
continue;
|
|
|
|
}
|
2001-03-26 13:44:06 +00:00
|
|
|
sensitive_data.host_keys[i] = key;
|
2013-07-20 03:21:52 +00:00
|
|
|
sensitive_data.host_pubkeys[i] = pubkey;
|
|
|
|
|
2016-08-13 17:47:40 +00:00
|
|
|
if (key == NULL && pubkey != NULL && have_agent) {
|
2015-02-16 22:30:03 +00:00
|
|
|
debug("will rely on agent for hostkey %s",
|
|
|
|
options.host_key_files[i]);
|
2013-07-20 03:21:52 +00:00
|
|
|
keytype = pubkey->type;
|
|
|
|
} else if (key != NULL) {
|
|
|
|
keytype = key->type;
|
2018-07-09 21:29:36 +00:00
|
|
|
accumulate_host_timing_secret(cfg, key);
|
2013-07-20 03:21:52 +00:00
|
|
|
} else {
|
2018-11-19 04:12:32 +00:00
|
|
|
do_log2(ll, "Unable to load host key: %s",
|
2001-04-16 02:00:02 +00:00
|
|
|
options.host_key_files[i]);
|
2001-03-26 13:44:06 +00:00
|
|
|
sensitive_data.host_keys[i] = NULL;
|
2013-07-20 03:21:52 +00:00
|
|
|
sensitive_data.host_pubkeys[i] = NULL;
|
2000-11-13 11:57:25 +00:00
|
|
|
continue;
|
2000-04-29 13:57:08 +00:00
|
|
|
}
|
2013-07-20 03:21:52 +00:00
|
|
|
|
|
|
|
switch (keytype) {
|
2000-11-13 11:57:25 +00:00
|
|
|
case KEY_RSA:
|
|
|
|
case KEY_DSA:
|
2010-08-31 12:41:14 +00:00
|
|
|
case KEY_ECDSA:
|
2013-12-07 00:24:01 +00:00
|
|
|
case KEY_ED25519:
|
2019-12-15 18:57:30 +00:00
|
|
|
case KEY_ECDSA_SK:
|
|
|
|
case KEY_ED25519_SK:
|
2018-02-23 15:58:37 +00:00
|
|
|
case KEY_XMSS:
|
2015-01-31 20:30:05 +00:00
|
|
|
if (have_agent || key != NULL)
|
|
|
|
sensitive_data.have_ssh2_key = 1;
|
2000-11-13 11:57:25 +00:00
|
|
|
break;
|
2000-04-29 13:57:08 +00:00
|
|
|
}
|
2015-01-31 20:30:05 +00:00
|
|
|
if ((fp = sshkey_fingerprint(pubkey, options.fingerprint_hash,
|
|
|
|
SSH_FP_DEFAULT)) == NULL)
|
|
|
|
fatal("sshkey_fingerprint failed");
|
|
|
|
debug("%s host key #%d: %s %s",
|
2016-08-13 17:47:40 +00:00
|
|
|
key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp);
|
2015-01-31 20:30:05 +00:00
|
|
|
free(fp);
|
2000-11-13 11:57:25 +00:00
|
|
|
}
|
2018-07-09 21:29:36 +00:00
|
|
|
accumulate_host_timing_secret(cfg, NULL);
|
2016-08-13 17:47:40 +00:00
|
|
|
if (!sensitive_data.have_ssh2_key) {
|
2003-04-09 10:59:48 +00:00
|
|
|
logit("sshd: no hostkeys available -- exiting.");
|
1999-11-24 13:26:21 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2010-02-26 20:55:05 +00:00
|
|
|
/*
|
|
|
|
* Load certificates. They are stored in an array at identical
|
|
|
|
* indices to the public keys that they relate to.
|
|
|
|
*/
|
|
|
|
sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
|
2017-05-30 08:52:19 +00:00
|
|
|
sizeof(struct sshkey *));
|
2010-02-26 20:55:05 +00:00
|
|
|
for (i = 0; i < options.num_host_key_files; i++)
|
|
|
|
sensitive_data.host_certificates[i] = NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < options.num_host_cert_files; i++) {
|
2014-12-22 07:55:51 +00:00
|
|
|
if (options.host_cert_files[i] == NULL)
|
|
|
|
continue;
|
2018-07-11 18:53:29 +00:00
|
|
|
if ((r = sshkey_load_public(options.host_cert_files[i],
|
|
|
|
&key, NULL)) != 0) {
|
2020-10-18 11:32:01 +00:00
|
|
|
error_r(r, "Could not load host certificate \"%s\"",
|
|
|
|
options.host_cert_files[i]);
|
2010-02-26 20:55:05 +00:00
|
|
|
continue;
|
|
|
|
}
|
2018-07-11 18:53:29 +00:00
|
|
|
if (!sshkey_is_cert(key)) {
|
2010-02-26 20:55:05 +00:00
|
|
|
error("Certificate file is not a certificate: %s",
|
|
|
|
options.host_cert_files[i]);
|
2018-07-11 18:53:29 +00:00
|
|
|
sshkey_free(key);
|
2010-02-26 20:55:05 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* Find matching private key */
|
|
|
|
for (j = 0; j < options.num_host_key_files; j++) {
|
2018-07-11 18:53:29 +00:00
|
|
|
if (sshkey_equal_public(key,
|
2021-06-06 11:34:16 +00:00
|
|
|
sensitive_data.host_pubkeys[j])) {
|
2010-02-26 20:55:05 +00:00
|
|
|
sensitive_data.host_certificates[j] = key;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (j >= options.num_host_key_files) {
|
|
|
|
error("No matching private key for certificate: %s",
|
|
|
|
options.host_cert_files[i]);
|
2018-07-11 18:53:29 +00:00
|
|
|
sshkey_free(key);
|
2010-02-26 20:55:05 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
sensitive_data.host_certificates[j] = key;
|
2017-10-05 15:52:03 +00:00
|
|
|
debug("host certificate: #%u type %d %s", j, key->type,
|
2018-07-11 18:53:29 +00:00
|
|
|
sshkey_type(key));
|
2010-02-26 20:55:05 +00:00
|
|
|
}
|
2014-05-15 04:24:09 +00:00
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
/* Ensure privsep directory is correctly configured. */
|
2024-05-31 09:11:14 +00:00
|
|
|
need_chroot = ((getuid() == 0 || geteuid() == 0) ||
|
2024-05-17 00:30:23 +00:00
|
|
|
options.kerberos_authentication);
|
2024-05-31 09:11:14 +00:00
|
|
|
if ((getpwnam(SSH_PRIVSEP_USER)) == NULL && need_chroot) {
|
2024-05-17 00:30:23 +00:00
|
|
|
fatal("Privilege separation user %s does not exist",
|
|
|
|
SSH_PRIVSEP_USER);
|
|
|
|
}
|
|
|
|
endpwent();
|
2002-06-06 20:46:25 +00:00
|
|
|
|
2024-05-31 09:11:14 +00:00
|
|
|
if (need_chroot) {
|
2024-05-17 00:30:23 +00:00
|
|
|
if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &sb) == -1) ||
|
|
|
|
(S_ISDIR(sb.st_mode) == 0))
|
2002-06-06 20:46:25 +00:00
|
|
|
fatal("Missing privilege separation directory: %s",
|
|
|
|
_PATH_PRIVSEP_CHROOT_DIR);
|
2002-06-27 18:02:21 +00:00
|
|
|
#ifdef HAVE_CYGWIN
|
|
|
|
if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) &&
|
2024-05-17 00:30:23 +00:00
|
|
|
(sb.st_uid != getuid () ||
|
|
|
|
(sb.st_mode & (S_IWGRP|S_IWOTH)) != 0))
|
2002-06-27 18:02:21 +00:00
|
|
|
#else
|
2024-05-17 00:30:23 +00:00
|
|
|
if (sb.st_uid != 0 || (sb.st_mode & (S_IWGRP|S_IWOTH)) != 0)
|
2002-06-27 18:02:21 +00:00
|
|
|
#endif
|
2003-02-24 00:50:18 +00:00
|
|
|
fatal("%s must be owned by root and not group or "
|
2024-06-06 17:31:02 +00:00
|
|
|
"world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
|
2002-06-06 20:46:25 +00:00
|
|
|
}
|
|
|
|
|
2023-02-10 04:47:19 +00:00
|
|
|
if (test_flag > 1)
|
2024-05-17 00:30:23 +00:00
|
|
|
print_config(&connection_info);
|
2008-06-10 13:01:51 +00:00
|
|
|
|
2001-08-06 21:09:07 +00:00
|
|
|
/* Configuration looks good, so exit if in test mode. */
|
|
|
|
if (test_flag)
|
|
|
|
exit(0);
|
|
|
|
|
2002-05-10 02:20:24 +00:00
|
|
|
/*
|
|
|
|
* Clear out any supplemental groups we may have inherited. This
|
|
|
|
* prevents inadvertent creation of files with bad modes (in the
|
2003-11-21 12:48:55 +00:00
|
|
|
* portable version at least, it's certainly possible for PAM
|
|
|
|
* to create a file, and we can't control the code in every
|
2002-05-10 02:20:24 +00:00
|
|
|
* module which might be used).
|
|
|
|
*/
|
|
|
|
if (setgroups(0, NULL) < 0)
|
|
|
|
debug("setgroups() failed: %.200s", strerror(errno));
|
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
/* Prepare arguments for sshd-session */
|
|
|
|
if (rexec_argc < 0)
|
|
|
|
fatal("rexec_argc %d < 0", rexec_argc);
|
|
|
|
rexec_argv = xcalloc(rexec_argc + 3, sizeof(char *));
|
|
|
|
/* Point to the sshd-session binary instead of sshd */
|
|
|
|
rexec_argv[0] = options.sshd_session_path;
|
|
|
|
for (i = 1; i < (u_int)rexec_argc; i++) {
|
|
|
|
debug("rexec_argv[%d]='%s'", i, saved_argv[i]);
|
|
|
|
rexec_argv[i] = saved_argv[i];
|
2004-06-25 03:33:20 +00:00
|
|
|
}
|
2024-05-17 00:30:23 +00:00
|
|
|
rexec_argv[rexec_argc++] = "-R";
|
|
|
|
rexec_argv[rexec_argc] = NULL;
|
|
|
|
if (stat(rexec_argv[0], &sb) != 0 || !(sb.st_mode & (S_IXOTH|S_IXUSR)))
|
|
|
|
fatal("%s does not exist or is not executable", rexec_argv[0]);
|
|
|
|
debug3("using %s for re-exec", rexec_argv[0]);
|
|
|
|
|
2024-10-14 01:57:50 +00:00
|
|
|
/* Ensure that the privsep binary exists now too. */
|
|
|
|
if (stat(options.sshd_auth_path, &sb) != 0 ||
|
|
|
|
!(sb.st_mode & (S_IXOTH|S_IXUSR))) {
|
|
|
|
fatal("%s does not exist or is not executable",
|
|
|
|
options.sshd_auth_path);
|
|
|
|
}
|
|
|
|
|
2020-01-24 23:56:01 +00:00
|
|
|
listener_proctitle = prepare_proctitle(ac, av);
|
2004-06-25 03:33:20 +00:00
|
|
|
|
2008-06-15 21:50:58 +00:00
|
|
|
/* Ensure that umask disallows at least group and world write */
|
|
|
|
new_umask = umask(0077) | 0022;
|
|
|
|
(void) umask(new_umask);
|
|
|
|
|
2000-04-29 13:57:08 +00:00
|
|
|
/* Initialize the log (it is reinitialized below in case we forked). */
|
2024-05-17 00:30:23 +00:00
|
|
|
if (debug_flag && !inetd_flag)
|
1999-11-24 13:26:21 +00:00
|
|
|
log_stderr = 1;
|
2020-10-16 13:26:13 +00:00
|
|
|
log_init(__progname, options.log_level,
|
|
|
|
options.log_facility, log_stderr);
|
|
|
|
for (i = 0; i < options.num_log_verbose; i++)
|
|
|
|
log_verbose_add(options.log_verbose[i]);
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2000-04-29 13:57:08 +00:00
|
|
|
/*
|
2016-11-30 00:28:31 +00:00
|
|
|
* If not in debugging mode, not started from inetd and not already
|
|
|
|
* daemonized (eg re-exec via SIGHUP), disconnect from the controlling
|
|
|
|
* terminal, and fork. The original process exits.
|
2000-04-29 13:57:08 +00:00
|
|
|
*/
|
2016-11-30 00:28:31 +00:00
|
|
|
already_daemon = daemonized();
|
|
|
|
if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) {
|
2016-11-29 03:54:50 +00:00
|
|
|
|
2019-06-28 13:35:04 +00:00
|
|
|
if (daemon(0, 0) == -1)
|
1999-11-24 13:26:21 +00:00
|
|
|
fatal("daemon() failed: %.200s", strerror(errno));
|
|
|
|
|
2016-11-29 03:54:50 +00:00
|
|
|
disconnect_controlling_tty();
|
1999-10-27 03:42:43 +00:00
|
|
|
}
|
1999-11-24 13:26:21 +00:00
|
|
|
/* Reinitialize the log (because of the fork above). */
|
2000-12-13 17:45:15 +00:00
|
|
|
log_init(__progname, options.log_level, options.log_facility, log_stderr);
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2021-04-03 06:18:40 +00:00
|
|
|
/*
|
|
|
|
* Chdir to the root directory so that the current disk can be
|
|
|
|
* unmounted if desired.
|
|
|
|
*/
|
2013-05-16 10:32:29 +00:00
|
|
|
if (chdir("/") == -1)
|
|
|
|
error("chdir(\"/\"): %s", strerror(errno));
|
2001-12-21 03:45:46 +00:00
|
|
|
|
2001-03-24 00:43:26 +00:00
|
|
|
/* ignore SIGPIPE */
|
2020-01-23 07:10:22 +00:00
|
|
|
ssh_signal(SIGPIPE, SIG_IGN);
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2006-08-18 14:31:39 +00:00
|
|
|
/* Get a connection, either from inetd or a listening TCP socket */
|
1999-11-24 13:26:21 +00:00
|
|
|
if (inetd_flag) {
|
2024-05-17 00:30:23 +00:00
|
|
|
/* Send configuration to ancestor sshd-session process */
|
|
|
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1)
|
|
|
|
fatal("socketpair: %s", strerror(errno));
|
|
|
|
send_rexec_state(config_s[0], cfg);
|
|
|
|
close(config_s[0]);
|
1999-11-24 13:26:21 +00:00
|
|
|
} else {
|
2009-12-08 02:39:48 +00:00
|
|
|
platform_pre_listen();
|
2006-08-18 14:31:39 +00:00
|
|
|
server_listen();
|
2000-01-14 04:45:46 +00:00
|
|
|
|
2020-01-23 07:10:22 +00:00
|
|
|
ssh_signal(SIGHUP, sighup_handler);
|
|
|
|
ssh_signal(SIGCHLD, main_sigchld_handler);
|
|
|
|
ssh_signal(SIGTERM, sigterm_handler);
|
|
|
|
ssh_signal(SIGQUIT, sigterm_handler);
|
upstream: Add a facility to sshd(8) to penalise particular
problematic client behaviours, controlled by two new sshd_config(5) options:
PerSourcePenalties and PerSourcePenaltyExemptList.
When PerSourcePenalties are enabled, sshd(8) will monitor the exit
status of its child pre-auth session processes. Through the exit
status, it can observe situations where the session did not
authenticate as expected. These conditions include when the client
repeatedly attempted authentication unsucessfully (possibly indicating
an attack against one or more accounts, e.g. password guessing), or
when client behaviour caused sshd to crash (possibly indicating
attempts to exploit sshd).
When such a condition is observed, sshd will record a penalty of some
duration (e.g. 30 seconds) against the client's address. If this time
is above a minimum threshold specified by the PerSourcePenalties, then
connections from the client address will be refused (along with any
others in the same PerSourceNetBlockSize CIDR range).
Repeated offenses by the same client address will accrue greater
penalties, up to a configurable maximum. A PerSourcePenaltyExemptList
option allows certain address ranges to be exempt from all penalties.
We hope these options will make it significantly more difficult for
attackers to find accounts with weak/guessable passwords or exploit
bugs in sshd(8) itself.
PerSourcePenalties is off by default, but we expect to enable it
automatically in the near future.
much feedback markus@ and others, ok markus@
OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca
2024-06-06 17:15:25 +00:00
|
|
|
#ifdef SIGINFO
|
|
|
|
ssh_signal(SIGINFO, siginfo_handler);
|
|
|
|
#endif
|
2001-06-25 05:10:20 +00:00
|
|
|
|
2024-04-03 03:40:32 +00:00
|
|
|
platform_post_listen();
|
|
|
|
|
2006-08-18 14:31:39 +00:00
|
|
|
/*
|
|
|
|
* Write out the pid file after the sigterm handler
|
|
|
|
* is setup and the listen sockets are bound
|
|
|
|
*/
|
2016-12-04 22:27:25 +00:00
|
|
|
if (options.pid_file != NULL && !debug_flag) {
|
2006-08-18 14:31:39 +00:00
|
|
|
FILE *f = fopen(options.pid_file, "w");
|
|
|
|
|
2003-07-03 03:40:44 +00:00
|
|
|
if (f == NULL) {
|
|
|
|
error("Couldn't create pid file \"%s\": %s",
|
|
|
|
options.pid_file, strerror(errno));
|
|
|
|
} else {
|
2002-06-11 16:42:49 +00:00
|
|
|
fprintf(f, "%ld\n", (long) getpid());
|
1999-11-24 13:26:21 +00:00
|
|
|
fclose(f);
|
|
|
|
}
|
1999-10-27 03:42:43 +00:00
|
|
|
}
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2006-08-18 14:31:39 +00:00
|
|
|
/* Accept a connection and return in a forked child */
|
|
|
|
server_accept_loop(&sock_in, &sock_out,
|
2024-05-17 00:30:23 +00:00
|
|
|
&newsock, config_s, log_stderr);
|
1999-11-24 13:26:21 +00:00
|
|
|
}
|
1999-10-27 03:42:43 +00:00
|
|
|
|
1999-11-24 13:26:21 +00:00
|
|
|
/* This is the child processing a new connection. */
|
2004-03-08 12:11:25 +00:00
|
|
|
setproctitle("%s", "[accepted]");
|
1999-11-24 13:26:21 +00:00
|
|
|
|
2004-08-12 12:36:51 +00:00
|
|
|
/*
|
|
|
|
* Create a new session and process group since the 4.4BSD
|
|
|
|
* setlogin() affects the entire process group. We don't
|
|
|
|
* want the child to be able to affect the parent.
|
|
|
|
*/
|
2019-06-28 13:35:04 +00:00
|
|
|
if (!debug_flag && !inetd_flag && setsid() == -1)
|
2004-08-12 12:36:51 +00:00
|
|
|
error("setsid: %.100s", strerror(errno));
|
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
debug("rexec start in %d out %d newsock %d pipe %d sock %d/%d",
|
|
|
|
sock_in, sock_out, newsock, startup_pipe, config_s[0], config_s[1]);
|
|
|
|
if (!inetd_flag) {
|
2023-03-03 03:12:24 +00:00
|
|
|
if (dup2(newsock, STDIN_FILENO) == -1)
|
2024-06-01 07:03:37 +00:00
|
|
|
fatal("dup2 stdin: %s", strerror(errno));
|
2023-03-03 03:12:24 +00:00
|
|
|
if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1)
|
2024-06-01 07:03:37 +00:00
|
|
|
fatal("dup2 stdout: %s", strerror(errno));
|
|
|
|
if (newsock > STDOUT_FILENO)
|
|
|
|
close(newsock);
|
2024-05-17 00:30:23 +00:00
|
|
|
}
|
|
|
|
if (config_s[1] != REEXEC_CONFIG_PASS_FD) {
|
2023-03-03 03:12:24 +00:00
|
|
|
if (dup2(config_s[1], REEXEC_CONFIG_PASS_FD) == -1)
|
2024-06-01 07:03:37 +00:00
|
|
|
fatal("dup2 config_s: %s", strerror(errno));
|
2004-06-25 03:33:20 +00:00
|
|
|
close(config_s[1]);
|
2002-03-22 03:43:46 +00:00
|
|
|
}
|
2024-05-17 00:30:23 +00:00
|
|
|
if (startup_pipe == -1)
|
|
|
|
close(REEXEC_STARTUP_PIPE_FD);
|
|
|
|
else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) {
|
|
|
|
if (dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD) == -1)
|
2024-06-01 07:03:37 +00:00
|
|
|
fatal("dup2 startup_p: %s", strerror(errno));
|
2005-12-24 03:59:12 +00:00
|
|
|
close(startup_pipe);
|
|
|
|
}
|
2024-06-06 19:50:01 +00:00
|
|
|
log_redirect_stderr_to(NULL);
|
2024-06-01 07:03:37 +00:00
|
|
|
closefrom(REEXEC_MIN_FREE_FD);
|
2005-12-24 03:59:12 +00:00
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */
|
|
|
|
execv(rexec_argv[0], rexec_argv);
|
2008-03-11 11:58:25 +00:00
|
|
|
|
2024-05-17 00:30:23 +00:00
|
|
|
fatal("rexec of %s failed: %s", rexec_argv[0], strerror(errno));
|
2000-04-12 08:45:05 +00:00
|
|
|
}
|
2003-10-02 06:12:36 +00:00
|
|
|
|
|
|
|
/* server specific fatal cleanup */
|
|
|
|
void
|
|
|
|
cleanup_exit(int i)
|
|
|
|
{
|
|
|
|
_exit(i);
|
|
|
|
}
|