From 6f83b8e34d3dc8227d7cf39989c5966abde2305e Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 2 May 2000 09:23:45 +1000 Subject: [PATCH] - OpenBSD CVS update [channels.c] - init all fds, close all fds. [sshconnect2.c] - check whether file exists before asking for passphrase [servconf.c servconf.h sshd.8 sshd.c] - PidFile, pr 1210 [channels.c] - EINTR [channels.c] - unbreak, ok niels@ [sshd.c] - unlink pid file, ok niels@ [auth2.c] - Add missing #ifdefs; ok - markus --- ChangeLog | 15 +++++++ auth2.c | 2 +- channels.c | 110 ++++++++++++++++++++++++++++---------------------- servconf.c | 22 ++++++++-- servconf.h | 3 +- sshconnect2.c | 11 +++-- sshd.8 | 8 +++- sshd.c | 5 ++- 8 files changed, 117 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3fffa25ad..1c924fb2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,19 @@ 20000502 + - OpenBSD CVS update + [channels.c] + - init all fds, close all fds. + [sshconnect2.c] + - check whether file exists before asking for passphrase + [servconf.c servconf.h sshd.8 sshd.c] + - PidFile, pr 1210 + [channels.c] + - EINTR + [channels.c] + - unbreak, ok niels@ + [sshd.c] + - unlink pid file, ok niels@ + [auth2.c] + - Add missing #ifdefs; ok - markus - Release 2.0.0beta1 20000501 diff --git a/auth2.c b/auth2.c index 34a5f482d..e77358a3b 100644 --- a/auth2.c +++ b/auth2.c @@ -27,7 +27,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.4 2000/05/01 07:45:08 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.5 2000/05/01 23:13:39 djm Exp $"); #include #include diff --git a/channels.c b/channels.c index 1f9b515c3..bd8c337ee 100644 --- a/channels.c +++ b/channels.c @@ -17,7 +17,7 @@ */ #include "includes.h" -RCSID("$Id: channels.c,v 1.27 2000/04/30 00:00:53 damien Exp $"); +RCSID("$Id: channels.c,v 1.28 2000/05/01 23:23:45 damien Exp $"); #include "ssh.h" #include "packet.h" @@ -148,17 +148,13 @@ channel_lookup(int id) } /* - * Allocate a new channel object and set its type and socket. This will cause - * remote_name to be freed. + * register filedescriptors for a channel, used when allocating a channel or + * when the channel consumer/producer is ready, e.g. shell exec'd */ -int -channel_new(char *ctype, int type, int rfd, int wfd, int efd, - int window, int maxpack, int extended_usage, char *remote_name) +void +channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage) { - int i, found; - Channel *c; - /* Update the maximum file descriptor value. */ if (rfd > channel_max_fd_value) channel_max_fd_value = rfd; @@ -167,6 +163,24 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, if (efd > channel_max_fd_value) channel_max_fd_value = efd; /* XXX set close-on-exec -markus */ + c->rfd = rfd; + c->wfd = wfd; + c->sock = (rfd == wfd) ? rfd : -1; + c->efd = efd; + c->extended_usage = extusage; +} + +/* + * Allocate a new channel object and set its type and socket. This will cause + * remote_name to be freed. + */ + +int +channel_new(char *ctype, int type, int rfd, int wfd, int efd, + int window, int maxpack, int extusage, char *remote_name) +{ + int i, found; + Channel *c; /* Do initial allocation if this is the first call. */ if (channels_alloc == 0) { @@ -203,14 +217,10 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, buffer_init(&c->output); buffer_init(&c->extended); chan_init_iostates(c); + channel_register_fds(c, rfd, wfd, efd, extusage); c->self = found; c->type = type; c->ctype = ctype; - c->rfd = rfd; - c->wfd = wfd; - c->sock = (rfd == wfd) ? rfd : -1; - c->efd = efd; - c->extended_usage = extended_usage; c->local_window = window; c->local_window_max = window; c->local_consumed = 0; @@ -226,13 +236,38 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, debug("channel %d: new [%s]", found, remote_name); return found; } +/* old interface XXX */ int channel_allocate(int type, int sock, char *remote_name) { return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); } -/* Free the channel and close its socket. */ + +/* Close all channel fd/socket. */ + +void +channel_close_fds(Channel *c) +{ + if (c->sock != -1) { + close(c->sock); + c->sock = -1; + } + if (c->rfd != -1) { + close(c->rfd); + c->rfd = -1; + } + if (c->wfd != -1) { + close(c->wfd); + c->wfd = -1; + } + if (c->efd != -1) { + close(c->efd); + c->efd = -1; + } +} + +/* Free the channel and close its fd/socket. */ void channel_free(int id) @@ -245,25 +280,9 @@ channel_free(int id) debug("channel_free: channel %d: dettaching channel user", id); c->dettach_user(c->self, NULL); } - if (c->sock != -1) { + if (c->sock != -1) shutdown(c->sock, SHUT_RDWR); - close(c->sock); - c->sock = -1; - } - if (compat20) { - if (c->rfd != -1) { - close(c->rfd); - c->rfd = -1; - } - if (c->wfd != -1) { - close(c->wfd); - c->wfd = -1; - } - if (c->efd != -1) { - close(c->efd); - c->efd = -1; - } - } + channel_close_fds(c); buffer_free(&c->input); buffer_free(&c->output); buffer_free(&c->extended); @@ -614,6 +633,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) if (c->rfd != -1 && FD_ISSET(c->rfd, readset)) { len = read(c->rfd, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; if (len <= 0) { debug("channel %d: read<=0 rfd %d len %d", c->self, c->rfd, len); @@ -640,7 +661,9 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) FD_ISSET(c->wfd, writeset) && buffer_len(&c->output) > 0) { len = write(c->wfd, buffer_ptr(&c->output), - buffer_len(&c->output)); + buffer_len(&c->output)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; if (len <= 0) { if (compat13) { buffer_consume(&c->output, buffer_len(&c->output)); @@ -1267,7 +1290,7 @@ channel_stop_listening() } /* - * Closes the sockets of all channels. This is used to close extra file + * Closes the sockets/fds of all channels. This is used to close extra file * descriptors after a fork. */ @@ -1275,10 +1298,9 @@ void channel_close_all() { int i; - for (i = 0; i < channels_alloc; i++) { + for (i = 0; i < channels_alloc; i++) if (channels[i].type != SSH_CHANNEL_FREE) - close(channels[i].sock); - } + channel_close_fds(&channels[i]); } /* Returns the maximum file descriptor number used by the channels. */ @@ -2269,17 +2291,9 @@ channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) Channel *c = channel_lookup(id); if (c == NULL || c->type != SSH_CHANNEL_LARVAL) fatal("channel_activate for non-larval channel %d.", id); - if (rfd > channel_max_fd_value) - channel_max_fd_value = rfd; - if (wfd > channel_max_fd_value) - channel_max_fd_value = wfd; - if (efd > channel_max_fd_value) - channel_max_fd_value = efd; + + channel_register_fds(c, rfd, wfd, efd, extusage); c->type = SSH_CHANNEL_OPEN; - c->rfd = rfd; - c->wfd = wfd; - c->efd = efd; - c->extended_usage = extusage; /* XXX window size? */ c->local_window = c->local_window_max = c->local_maxpacket/2; packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); diff --git a/servconf.c b/servconf.c index 298fefbe2..16eaeba01 100644 --- a/servconf.c +++ b/servconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$Id: servconf.c,v 1.13 2000/04/29 13:57:11 damien Exp $"); +RCSID("$Id: servconf.c,v 1.14 2000/05/01 23:23:45 damien Exp $"); #include "ssh.h" #include "servconf.h" @@ -33,6 +33,7 @@ initialize_server_options(ServerOptions *options) options->listen_addrs = NULL; options->host_key_file = NULL; options->dsa_key_file = NULL; + options->pid_file = NULL; options->server_key_bits = -1; options->login_grace_time = -1; options->key_regeneration_time = -1; @@ -84,6 +85,8 @@ fill_default_server_options(ServerOptions *options) options->host_key_file = HOST_KEY_FILE; if (options->dsa_key_file == NULL) options->dsa_key_file = DSA_KEY_FILE; + if (options->pid_file == NULL) + options->pid_file = SSH_DAEMON_PID_FILE; if (options->server_key_bits == -1) options->server_key_bits = 768; if (options->login_grace_time == -1) @@ -167,7 +170,7 @@ typedef enum { sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, - sIgnoreUserKnownHosts, sDSAKeyFile, sCiphers, sProtocol + sIgnoreUserKnownHosts, sDSAKeyFile, sCiphers, sProtocol, sPidFile } ServerOpCodes; /* Textual representation of the tokens. */ @@ -178,6 +181,7 @@ static struct { { "port", sPort }, { "hostkey", sHostKeyFile }, { "dsakey", sDSAKeyFile }, + { "pidfile", sPidFile }, { "serverkeybits", sServerKeyBits }, { "logingracetime", sLoginGraceTime }, { "keyregenerationinterval", sKeyRegenerationTime }, @@ -355,7 +359,19 @@ parse_int: cp = strtok(NULL, WHITESPACE); if (!cp) { fprintf(stderr, "%s line %d: missing file name.\n", - filename, linenum); + filename, linenum); + exit(1); + } + if (*charptr == NULL) + *charptr = tilde_expand_filename(cp, getuid()); + break; + + case sPidFile: + charptr = &options->pid_file; + cp = strtok(NULL, WHITESPACE); + if (!cp) { + fprintf(stderr, "%s line %d: missing file name.\n", + filename, linenum); exit(1); } if (*charptr == NULL) diff --git a/servconf.h b/servconf.h index b8e8163dd..a5010093d 100644 --- a/servconf.h +++ b/servconf.h @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: servconf.h,v 1.9 2000/04/16 01:18:45 damien Exp $"); */ +/* RCSID("$Id: servconf.h,v 1.10 2000/05/01 23:23:46 damien Exp $"); */ #ifndef SERVCONF_H #define SERVCONF_H @@ -33,6 +33,7 @@ typedef struct { struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ char *host_key_file; /* File containing host key. */ char *dsa_key_file; /* File containing dsa host key. */ + char *pid_file; /* Where to put our pid */ int server_key_bits;/* Size of the server key. */ int login_grace_time; /* Disconnect if no auth in this time * (sec). */ diff --git a/sshconnect2.c b/sshconnect2.c index 31ef3084c..a4342e2df 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -28,7 +28,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.4 2000/04/27 17:54:01 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.5 2000/05/01 18:41:06 markus Exp $"); #include #include @@ -310,7 +310,12 @@ ssh2_try_pubkey(char *filename, Key *k; unsigned char *blob, *signature; int bloblen, slen; + struct stat st; + if (stat(filename, &st) != 0) { + debug("key does not exist: %s", filename); + return 0; + } debug("try pubkey: %s", filename); k = key_new(KEY_DSA); @@ -318,9 +323,9 @@ ssh2_try_pubkey(char *filename, int success = 0; char *passphrase; char prompt[300]; - snprintf(prompt, sizeof prompt, + snprintf(prompt, sizeof prompt, "Enter passphrase for DSA key '%.100s': ", - filename); + filename); passphrase = read_passphrase(prompt, 0); success = load_private_key(filename, passphrase, k, NULL); memset(passphrase, 0, strlen(passphrase)); diff --git a/sshd.8 b/sshd.8 index 9d8764a9c..85da7c4a1 100644 --- a/sshd.8 +++ b/sshd.8 @@ -9,7 +9,7 @@ .\" .\" Created: Sat Apr 22 21:55:14 1995 ylo .\" -.\" $Id: sshd.8,v 1.19 2000/05/01 11:10:34 damien Exp $ +.\" $Id: sshd.8,v 1.20 2000/05/01 23:23:46 damien Exp $ .\" .Dd September 25, 1999 .Dt SSHD 8 @@ -415,6 +415,12 @@ option has been specified will be allowed regardless of the value of this setting (which may be useful for taking remote backups even if root login is normally not allowed). +.It Cm PidFile +Specifies the file that contains the process identifier of the +.Nm +daemon. +The default is +.Pa /var/run/sshd.pid . .It Cm Port Specifies the port number that .Nm diff --git a/sshd.c b/sshd.c index fc2d1d20e..70f292cc7 100644 --- a/sshd.c +++ b/sshd.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.111 2000/04/27 08:01:28 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.113 2000/05/01 20:34:51 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -190,6 +190,7 @@ sigterm_handler(int sig) { log("Received signal %d; terminating.", sig); close_listen_socks(); + unlink(options.pid_file); exit(255); } @@ -729,7 +730,7 @@ main(int ac, char **av) * fail if there already is a daemon, and this will * overwrite any old pid in the file. */ - f = fopen(SSH_DAEMON_PID_FILE, "w"); + f = fopen(options.pid_file, "w"); if (f) { fprintf(f, "%u\n", (unsigned int) getpid()); fclose(f);