From 8abcdba4e06cabbda1d9f8a42ed58a81336819cd Mon Sep 17 00:00:00 2001 From: mouring Date: Thu, 28 Dec 2000 16:40:05 +0000 Subject: [PATCH] - (bal) OpenBSD CVS Update - markus@cvs.openbsd.org 2000/12/28 14:25:51 [auth.h auth2.c] count authentication failures only - markus@cvs.openbsd.org 2000/12/28 14:25:03 [sshconnect.c] fingerprint for MITM attacks, too. - markus@cvs.openbsd.org 2000/12/28 12:03:57 [sshd.8 sshd.c] document -D - markus@cvs.openbsd.org 2000/12/27 14:19:21 [serverloop.c] less chatty - markus@cvs.openbsd.org 2000/12/27 12:34 [auth1.c sshconnect2.c sshd.c] typo - markus@cvs.openbsd.org 2000/12/27 12:30:19 [readconf.c readconf.h ssh.1 sshconnect.c] new option: HostKeyAlias: allow the user to record the host key under a different name. This is useful for ssh tunneling over forwarded connections or if you run multiple sshd's on different ports on the same machine. - markus@cvs.openbsd.org 2000/12/27 11:51:53 [ssh.1 ssh.c] multiple -t force pty allocation, document ORIGINAL_COMMAND - markus@cvs.openbsd.org 2000/12/27 11:41:31 [sshd.8] update for ssh-2 --- ChangeLog | 28 ++++++++++++++++++++++++++++ auth.h | 3 +++ auth1.c | 8 ++++---- auth2.c | 21 +++++++++------------ readconf.c | 11 +++++++++-- readconf.h | 3 ++- serverloop.c | 4 ++-- ssh.1 | 24 +++++++++++++++++++----- ssh.c | 9 ++++++--- sshconnect.c | 30 +++++++++++++++++++++++------- sshconnect2.c | 4 ++-- sshd.8 | 41 ++++++++++++++++++++++++++++++----------- sshd.c | 5 +++-- 13 files changed, 140 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8f13a237..09c1a822 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,34 @@ 20001229 - (bal) Fixed spelling of 'authorized_keys' in ssh-copy-id.1 by Christian Kurz + - (bal) OpenBSD CVS Update + - markus@cvs.openbsd.org 2000/12/28 14:25:51 + [auth.h auth2.c] + count authentication failures only + - markus@cvs.openbsd.org 2000/12/28 14:25:03 + [sshconnect.c] + fingerprint for MITM attacks, too. + - markus@cvs.openbsd.org 2000/12/28 12:03:57 + [sshd.8 sshd.c] + document -D + - markus@cvs.openbsd.org 2000/12/27 14:19:21 + [serverloop.c] + less chatty + - markus@cvs.openbsd.org 2000/12/27 12:34 + [auth1.c sshconnect2.c sshd.c] + typo + - markus@cvs.openbsd.org 2000/12/27 12:30:19 + [readconf.c readconf.h ssh.1 sshconnect.c] + new option: HostKeyAlias: allow the user to record the host key + under a different name. This is useful for ssh tunneling over + forwarded connections or if you run multiple sshd's on different + ports on the same machine. + - markus@cvs.openbsd.org 2000/12/27 11:51:53 + [ssh.1 ssh.c] + multiple -t force pty allocation, document ORIGINAL_COMMAND + - markus@cvs.openbsd.org 2000/12/27 11:41:31 + [sshd.8] + update for ssh-2 20001228 - (bal) Patch to add libutil.h to loginrec.c only if the platform has diff --git a/auth.h b/auth.h index ef392ace..4b029f9c 100644 --- a/auth.h +++ b/auth.h @@ -20,6 +20,8 @@ * 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. + * + * $OpenBSD: auth.h,v 1.8 2000/12/28 14:25:51 markus Exp $ */ #ifndef AUTH_H #define AUTH_H @@ -29,6 +31,7 @@ struct Authctxt { int success; int valid; int attempt; + int failures; char *user; char *service; struct passwd *pw; diff --git a/auth1.c b/auth1.c index 5c906b60..26472e02 100644 --- a/auth1.c +++ b/auth1.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.8 2000/12/19 23:17:55 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.9 2000/12/27 12:34:49 markus Exp $"); #ifdef HAVE_OSF_SIA # include @@ -71,7 +71,7 @@ get_authname(int type) /* * read packets and try to authenticate local user 'luser'. - * return if authentication is successfull. not that pw == NULL + * return if authentication is successful. not that pw == NULL * if the user does not exists or is not allowed to login. * each auth method has to 'fake' authentication for nonexisting * users. @@ -469,11 +469,11 @@ do_authentication() } else { /* Loop until the user has been authenticated or the connection is closed, do_authloop() returns only if - authentication is successfull */ + authentication is successful */ do_authloop(pw, user); } if (pw == NULL) - fatal("internal error, authentication successfull for user '%.100s'", user); + fatal("internal error, authentication successful for user '%.100s'", user); /* The user has been authenticated and accepted. */ packet_start(SSH_SMSG_SUCCESS); diff --git a/auth2.c b/auth2.c index a0e6d577..4880b736 100644 --- a/auth2.c +++ b/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.23 2000/12/19 23:17:55 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.24 2000/12/28 14:25:51 markus Exp $"); #ifdef HAVE_OSF_SIA # include @@ -124,6 +124,7 @@ do_authentication2() memset(authctxt, 'a', sizeof(*authctxt)); authctxt->valid = 0; authctxt->attempt = 0; + authctxt->failures = 0; authctxt->success = 0; x_authctxt = authctxt; /*XXX*/ @@ -190,21 +191,14 @@ input_userauth_request(int type, int plen, void *ctxt) if (authctxt == NULL) fatal("input_userauth_request: no authctxt"); - if (authctxt->attempt++ >= AUTH_FAIL_MAX) { -#ifdef WITH_AIXAUTHENTICATE - loginfailed(authctxt->user?authctxt->user:"NOUSER", - get_canonical_hostname(), "ssh"); -#endif /* WITH_AIXAUTHENTICATE */ - packet_disconnect("too many failed userauth_requests"); - } user = packet_get_string(NULL); service = packet_get_string(NULL); method = packet_get_string(NULL); debug("userauth-request for user %s service %s method %s", user, service, method); - debug("attempt #%d", authctxt->attempt); + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); - if (authctxt->attempt == 1) { + if (authctxt->attempt++ == 0) { /* setup auth context */ struct passwd *pw = NULL; setproctitle("%s", user); @@ -273,7 +267,7 @@ userauth_log(Authctxt *authctxt, int authenticated, char *method) /* Raise logging level */ if (authenticated == 1 || !authctxt->valid || - authctxt->attempt >= AUTH_FAIL_LOG || + authctxt->failures >= AUTH_FAIL_LOG || strcmp(method, "password") == 0) authlog = log; @@ -302,6 +296,7 @@ userauth_log(Authctxt *authctxt, int authenticated, char *method) void userauth_reply(Authctxt *authctxt, int authenticated) { + char *methods; /* XXX todo: check if multiple auth methods are needed */ if (authenticated == 1) { #ifdef WITH_AIXAUTHENTICATE @@ -318,7 +313,9 @@ userauth_reply(Authctxt *authctxt, int authenticated) /* now we can break out */ authctxt->success = 1; } else if (authenticated == 0) { - char *methods = authmethods_get(); + if (authctxt->failures++ >= AUTH_FAIL_MAX) + packet_disconnect("too many failed userauth_requests"); + methods = authmethods_get(); packet_start(SSH2_MSG_USERAUTH_FAILURE); packet_put_cstring(methods); packet_put_char(0); /* XXX partial success, unused */ diff --git a/readconf.c b/readconf.c index 6f5ac8ca..d90ba37b 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.51 2000/12/19 23:17:57 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.52 2000/12/27 12:30:19 markus Exp $"); #include "ssh.h" #include "readconf.h" @@ -103,7 +103,7 @@ typedef enum { oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, - oKbdInteractiveAuthentication, oKbdInteractiveDevices + oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias } OpCodes; /* Textual representations of the tokens. */ @@ -137,6 +137,7 @@ static struct { { "identityfile", oIdentityFile }, { "identityfile2", oIdentityFile }, /* alias */ { "hostname", oHostName }, + { "hostkeyalias", oHostKeyAlias }, { "proxycommand", oProxyCommand }, { "port", oPort }, { "cipher", oCipher }, @@ -435,6 +436,10 @@ parse_string: charptr = &options->hostname; goto parse_string; + case oHostKeyAlias: + charptr = &options->host_key_alias; + goto parse_string; + case oProxyCommand: charptr = &options->proxy_command; string = xstrdup(""); @@ -689,6 +694,7 @@ initialize_options(Options * options) options->protocol = SSH_PROTO_UNKNOWN; options->num_identity_files = 0; options->hostname = NULL; + options->host_key_alias = NULL; options->proxy_command = NULL; options->user = NULL; options->escape_char = -1; @@ -802,4 +808,5 @@ fill_default_options(Options * options) /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ + /* options->host_key_alias should not be set by default */ } diff --git a/readconf.h b/readconf.h index 85d937d8..08ff7083 100644 --- a/readconf.h +++ b/readconf.h @@ -11,7 +11,7 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$OpenBSD: readconf.h,v 1.23 2000/11/12 19:50:37 markus Exp $"); */ +/* RCSID("$OpenBSD: readconf.h,v 1.24 2000/12/27 12:30:20 markus Exp $"); */ #ifndef READCONF_H #define READCONF_H @@ -69,6 +69,7 @@ typedef struct { char *ciphers; /* SSH2 ciphers in order of preference. */ int protocol; /* Protocol in order of preference. */ char *hostname; /* Real host to connect. */ + char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ int escape_char; /* Escape character; -2 = none */ diff --git a/serverloop.c b/serverloop.c index 57e7f1f7..5fb0ed02 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.38 2000/12/19 23:17:58 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.39 2000/12/27 14:19:21 markus Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -250,7 +250,7 @@ retry_select: tvp = &tv; } if (tvp!=NULL) - debug("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); + debug2("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); /* Wait for something to happen, or the timeout to expire. */ ret = select(max_fd + 1, readset, writeset, NULL, tvp); diff --git a/ssh.1 b/ssh.1 index fd791200..40cb6dfa 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.72 2000/12/12 23:11:48 markus Exp $ +.\" $OpenBSD: ssh.1,v 1.74 2000/12/27 12:30:20 markus Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -475,6 +475,11 @@ Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g., when implementing menu services. +Multiple +.Fl t +options force tty allocation, even if +.Nm +has no local tty. .It Fl T Disable pseudo-tty allocation. .It Fl v @@ -484,10 +489,9 @@ Causes to print debugging messages about its progress. This is helpful in debugging connection, authentication, and configuration problems. -The verbose mode is also used to display -.Xr skey 1 -challenges, if the user entered "s/key" as password. -Multiple -v options increases the verbosity. +Multiple +.Fl v +options increases the verbosity. Maximum is 3. .It Fl x Disables X11 forwarding. @@ -742,6 +746,12 @@ The default is .It Cm GlobalKnownHostsFile Specifies a file to use instead of .Pa /etc/ssh_known_hosts . +.It Cm HostKeyAlias +Specifies an alias that should be used instead of the +real host name when looking up or saving the host key +the kown_hosts files. +This option is useful for tunneling ssh connection +or if you have multiple servers running on a single host. .It Cm HostName Specifies the real host name to log into. This can be used to specify nicknames or abbreviations for hosts. @@ -1023,6 +1033,10 @@ Identifies the client end of the connection. The variable contains three space-separated values: client ip-address, client port number, and server port number. +.It Ev SSH_ORIGINAL_COMMAND +The variable contains the original command line if a forced command +is executed. +It can be used to extract the original arguments. .It Ev SSH_TTY This is set to the name of the tty (path to the device) associated with the current shell or command. diff --git a/ssh.c b/ssh.c index 92564b97..7035486e 100644 --- a/ssh.c +++ b/ssh.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.78 2000/12/19 23:17:58 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.79 2000/12/27 11:51:54 markus Exp $"); #include #include @@ -79,10 +79,11 @@ int debug_flag = 0; /* Flag indicating whether a tty should be allocated */ int tty_flag = 0; +int no_tty_flag = 0; +int force_tty_flag = 0; /* don't exec a shell */ int no_shell_flag = 0; -int no_tty_flag = 0; /* * Flag indicating that nothing should be read from stdin. This can be set @@ -373,6 +374,8 @@ main(int ac, char **av) options.identity_files[options.num_identity_files++] = xstrdup(optarg); break; case 't': + if (tty_flag) + force_tty_flag = 1; tty_flag = 1; break; case 'v': @@ -521,7 +524,7 @@ main(int ac, char **av) if (no_tty_flag) tty_flag = 0; /* Do not allocate a tty if stdin is not a tty. */ - if (!isatty(fileno(stdin))) { + if (!isatty(fileno(stdin)) && !force_tty_flag) { if (tty_flag) fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); tty_flag = 0; diff --git a/sshconnect.c b/sshconnect.c index 647aec79..22e69142 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.85 2000/12/21 15:10:17 markus Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.87 2000/12/28 14:25:03 markus Exp $"); #include #include @@ -499,8 +499,13 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, break; } if (local) { - debug("Forcing accepting of host key for loopback/localhost."); - return; + if (options.host_key_alias == NULL) { + debug("Forcing accepting of host key for " + "loopback/localhost."); + return; + } + if (options.check_host_ip) + options.check_host_ip = 0; } /* @@ -514,13 +519,23 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, if (options.proxy_command == NULL) { if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop), - NULL, 0, NI_NUMERICHOST) != 0) + NULL, 0, NI_NUMERICHOST) != 0) fatal("check_host_key: getnameinfo failed"); ip = xstrdup(ntop); } else { ip = xstrdup(""); } + /* + * Allow the user to record the key under a different name. This is + * useful for ssh tunneling over forwarded connections or if you run + * multiple sshd's on different ports on the same machine. + */ + if (options.host_key_alias != NULL) { + host = options.host_key_alias; + debug("using hostkeyalias: %s", host); + } + /* * Store the host key from the known host file in here so that we can * compare it with the key for the IP address. @@ -592,12 +607,11 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, } else if (options.strict_host_key_checking == 2) { /* The default */ char prompt[1024]; - char *fp = key_fingerprint(host_key); snprintf(prompt, sizeof(prompt), "The authenticity of host '%.200s (%s)' can't be established.\n" "%s key fingerprint is %s.\n" "Are you sure you want to continue connecting (yes/no)? ", - host, ip, type, fp); + host, ip, type, key_fingerprint(host_key)); if (!read_yes_or_no(prompt, -1)) fatal("Aborted by user!\n"); } @@ -642,9 +656,11 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); error("It is also possible that the %s host key has just been changed.", type); + error("The fingerprint for the %s key sent by the remote host is\n%s.", + type, key_fingerprint(host_key)); error("Please contact your system administrator."); error("Add correct host key in %.100s to get rid of this message.", - user_hostfile); + user_hostfile); error("Offending key in %s:%d", host_file, host_line); /* diff --git a/sshconnect2.c b/sshconnect2.c index aee547fb..34d72818 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.33 2000/12/20 19:37:22 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.34 2000/12/27 12:34:50 markus Exp $"); #include #include @@ -548,7 +548,7 @@ ssh_userauth2(const char *server_user, char *host) if (authctxt.agent != NULL) ssh_close_authentication_connection(authctxt.agent); - debug("ssh-userauth2 successfull: method %s", authctxt.method->name); + debug("ssh-userauth2 successful: method %s", authctxt.method->name); } void input_userauth_error(int type, int plen, void *ctxt) diff --git a/sshd.8 b/sshd.8 index 48d6be20..b2ff9a3e 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.73 2000/11/22 15:38:30 provos Exp $ +.\" $OpenBSD: sshd.8,v 1.76 2000/12/28 12:03:57 markus Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -43,7 +43,7 @@ .Nd secure shell daemon .Sh SYNOPSIS .Nm sshd -.Op Fl diqQ46 +.Op Fl diqDQ46 .Op Fl b Ar bits .Op Fl f Ar config_file .Op Fl g Ar login_grace_time @@ -202,12 +202,14 @@ If the client fails to authenticate the user within this many seconds, the server disconnects and exits. A value of zero indicates no limit. .It Fl h Ar host_key_file -Specifies the file from which the RSA host key is read (default +Specifies the file from which the host key is read (default .Pa /etc/ssh_host_key ) . This option must be given if .Nm is not run as root (as the normal host file is normally not readable by anyone but root). +It is possible to have multiple host key files for +the different protocol versions. .It Fl i Specifies that .Nm @@ -254,6 +256,12 @@ indicates that only dotted decimal addresses should be put into the .Pa utmp file. +.It Fl D +When this option is specified +.Nm +will not detach and does not become a daemon. +This allows easy monitoring of +.Nm sshd . .It Fl Q Do not print an error message if RSA support is missing. .It Fl V Ar client_protocol_id @@ -720,26 +728,37 @@ file lists the RSA keys that are permitted for RSA authentication in SSH protocols 1.3 and 1.5 Similarly, the .Pa $HOME/.ssh/authorized_keys2 -file lists the DSA keys that are -permitted for DSA authentication in SSH protocol 2.0. +file lists the DSA and RSA keys that are +permitted for public key authentication (PubkeyAuthentication) +in SSH protocol 2.0. +.Pp Each line of the file contains one key (empty lines and lines starting with a .Ql # are ignored as comments). -Each line consists of the following fields, separated by +Each RSA public key consists of the following fields, separated by spaces: options, bits, exponent, modulus, comment. -The options field -is optional; its presence is determined by whether the line starts +Each protocol version 2 public key consists of: +options, keytype, base64 encoded key, comment. +The options fields +are optional; its presence is determined by whether the line starts with a number or not (the option field never starts with a number). -The bits, exponent, modulus and comment fields give the RSA key; the +The bits, exponent, modulus and comment fields give the RSA key for +protocol version 1; the comment field is not used for anything (but may be convenient for the user to identify the key). +For protocol version 2 the keytype is +.Dq ssh-dss +or +.Dq ssh-rsa . .Pp Note that lines in this file are usually several hundred bytes long (because of the size of the RSA key modulus). You don't want to type them in; instead, copy the .Pa identity.pub +or the +.Pa id_dsa.pub file and edit it. .Pp The options (if present) consist of comma-separated option @@ -1053,7 +1072,7 @@ This version of OpenSSH .Bl -bullet .It has all components of a restrictive nature (i.e., patents, see -.Xr crypto 3 ) +.Xr ssl 8 ) directly removed from the source code; any licensed or patented components are chosen from external libraries. @@ -1080,6 +1099,6 @@ The support for SSH protocol 2 was written by Markus Friedl. .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr ssh-keygen 1 , -.Xr crypto 3 , +.Xr ssl 8 , .Xr rlogin 1 , .Xr rsh 1 diff --git a/sshd.c b/sshd.c index e10e530f..dade6564 100644 --- a/sshd.c +++ b/sshd.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.142 2000/12/20 19:37:22 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.144 2000/12/28 12:03:58 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -653,6 +653,7 @@ main(int ac, char **av) fprintf(stderr, " -f file Configuration file (default %s)\n", SERVER_CONFIG_FILE); fprintf(stderr, " -d Debugging mode (multiple -d means more debugging)\n"); fprintf(stderr, " -i Started from inetd\n"); + fprintf(stderr, " -D Do not fork into daemon mode\n"); fprintf(stderr, " -q Quiet (no logging)\n"); fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); @@ -947,7 +948,7 @@ main(int ac, char **av) /* * the read end of the pipe is ready * if the child has closed the pipe - * after successfull authentication + * after successful authentication * or if the child has died */ close(startup_pipes[i]); -- 2.45.1