diff options
author | Damien Miller <djm@mindrot.org> | 2000-08-18 13:59:06 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-08-18 13:59:06 +1000 |
commit | 942da039d2a05e6f491883f50b516175a6dbb20f (patch) | |
tree | 0ac91ba19e494a3cb054d34db0c3b65660bd7375 | |
parent | 11fa2cc3839b1e7fed1d85aa1158cce4d498bc58 (diff) |
- (djm) OpenBSD CVS changes:
- markus@cvs.openbsd.org 2000/07/22 03:14:37
[servconf.c servconf.h sshd.8 sshd.c sshd_config]
random early drop; ok theo, niels
- deraadt@cvs.openbsd.org 2000/07/26 11:46:51
[ssh.1]
typo
- deraadt@cvs.openbsd.org 2000/08/01 11:46:11
[sshd.8]
many fixes from pepper@mail.reppep.com
- provos@cvs.openbsd.org 2000/08/01 13:01:42
[Makefile.in util.c aux.c]
rename aux.c to util.c to help with cygwin port
- deraadt@cvs.openbsd.org 2000/08/02 00:23:31
[authfd.c]
correct sun_len; Alexander@Leidinger.net
- provos@cvs.openbsd.org 2000/08/02 10:27:17
[readconf.c sshd.8]
disable kerberos authentication by default
- provos@cvs.openbsd.org 2000/08/02 11:27:05
[sshd.8 readconf.c auth-krb4.c]
disallow kerberos authentication if we can't verify the TGT; from
dugsong@
kerberos authentication is on by default only if you have a srvtab.
- markus@cvs.openbsd.org 2000/08/04 14:30:07
[auth.c]
unused
- markus@cvs.openbsd.org 2000/08/04 14:30:35
[sshd_config]
MaxStartups
- markus@cvs.openbsd.org 2000/08/15 13:20:46
[authfd.c]
cleanup; ok niels@
- markus@cvs.openbsd.org 2000/08/17 14:05:10
[session.c]
cleanup login(1)-like jobs, no duplicate utmp entries
- markus@cvs.openbsd.org 2000/08/17 14:06:34
[session.c sshd.8 sshd.c]
sshd -u len, similar to telnetd
-rw-r--r-- | ChangeLog | 41 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | acconfig.h | 3 | ||||
-rw-r--r-- | auth-krb4.c | 8 | ||||
-rw-r--r-- | auth.c | 4 | ||||
-rw-r--r-- | authfd.c | 325 | ||||
-rw-r--r-- | bsd-mktemp.c | 1 | ||||
-rw-r--r-- | configure.in | 16 | ||||
-rw-r--r-- | readconf.c | 2 | ||||
-rw-r--r-- | servconf.c | 24 | ||||
-rw-r--r-- | servconf.h | 4 | ||||
-rw-r--r-- | session.c | 194 | ||||
-rw-r--r-- | ssh.1 | 4 | ||||
-rw-r--r-- | sshd.8 | 65 | ||||
-rw-r--r-- | sshd.c | 43 | ||||
-rw-r--r-- | sshd_config | 1 |
16 files changed, 400 insertions, 337 deletions
@@ -1,3 +1,44 @@ +20000818 + - (djm) OpenBSD CVS changes: + - markus@cvs.openbsd.org 2000/07/22 03:14:37 + [servconf.c servconf.h sshd.8 sshd.c sshd_config] + random early drop; ok theo, niels + - deraadt@cvs.openbsd.org 2000/07/26 11:46:51 + [ssh.1] + typo + - deraadt@cvs.openbsd.org 2000/08/01 11:46:11 + [sshd.8] + many fixes from pepper@mail.reppep.com + - provos@cvs.openbsd.org 2000/08/01 13:01:42 + [Makefile.in util.c aux.c] + rename aux.c to util.c to help with cygwin port + - deraadt@cvs.openbsd.org 2000/08/02 00:23:31 + [authfd.c] + correct sun_len; Alexander@Leidinger.net + - provos@cvs.openbsd.org 2000/08/02 10:27:17 + [readconf.c sshd.8] + disable kerberos authentication by default + - provos@cvs.openbsd.org 2000/08/02 11:27:05 + [sshd.8 readconf.c auth-krb4.c] + disallow kerberos authentication if we can't verify the TGT; from + dugsong@ + kerberos authentication is on by default only if you have a srvtab. + - markus@cvs.openbsd.org 2000/08/04 14:30:07 + [auth.c] + unused + - markus@cvs.openbsd.org 2000/08/04 14:30:35 + [sshd_config] + MaxStartups + - markus@cvs.openbsd.org 2000/08/15 13:20:46 + [authfd.c] + cleanup; ok niels@ + - markus@cvs.openbsd.org 2000/08/17 14:05:10 + [session.c] + cleanup login(1)-like jobs, no duplicate utmp entries + - markus@cvs.openbsd.org 2000/08/17 14:06:34 + [session.c sshd.8 sshd.c] + sshd -u len, similar to telnetd + 20000816 - (djm) Replacement for inet_ntoa for Irix (which breaks on gcc) - (djm) Fix strerror replacement for old SunOS. Based on patch from diff --git a/Makefile.in b/Makefile.in index 0aaaa688..ff34c493 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,7 +34,7 @@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) -LIBSSH_OBJS=atomicio.o authfd.o authfile.o aux.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o +LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o LIBOPENBSD_COMPAT_OBJS=bsd-arc4random.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-inet_aton.o bsd-inet_ntoa.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o @@ -6,6 +6,9 @@ @TOP@ +/* Define if your system's struct sockaddr_un has a sun_len member */ +#undef HAVE_SUN_LEN_IN_SOCKADDR_UN + /* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ #undef BROKEN_INET_NTOA diff --git a/auth-krb4.c b/auth-krb4.c index e32089b7..ae2b2a3d 100644 --- a/auth-krb4.c +++ b/auth-krb4.c @@ -9,7 +9,7 @@ #include "ssh.h" #include "servconf.h" -RCSID("$OpenBSD: auth-krb4.c,v 1.15 2000/06/22 23:54:59 djm Exp $"); +RCSID("$OpenBSD: auth-krb4.c,v 1.16 2000/08/02 17:27:04 provos Exp $"); #ifdef KRB4 char *ticket = NULL; @@ -82,11 +82,12 @@ auth_krb4_password(struct passwd * pw, const char *password) if (r == RD_AP_UNDEC) { /* * Probably didn't have a srvtab on - * localhost. Allow login. + * localhost. Disallow login. */ log("Kerberos V4 TGT for %s unverifiable, " "no srvtab installed? krb_rd_req: %s", pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; } else if (r != KSUCCESS) { log("Kerberos V4 %s ticket unverifiable: %s", KRB4_SERVICE_NAME, krb_err_txt[r]); @@ -94,12 +95,13 @@ auth_krb4_password(struct passwd * pw, const char *password) } } else if (r == KDC_PR_UNKNOWN) { /* - * Allow login if no rcmd service exists, but + * Disallow login if no rcmd service exists, and * log the error. */ log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " "not registered, or srvtab is wrong?", pw->pw_name, krb_err_txt[r], KRB4_SERVICE_NAME, phost); + goto kerberos_auth_failure; } else { /* * TGT is bad, forget it. Possibly spoofed! @@ -5,7 +5,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $"); +RCSID("$OpenBSD: auth.c,v 1.8 2000/08/04 20:30:07 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -30,8 +30,6 @@ RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $"); #include "ssh2.h" #include "auth.h" #include "session.h" -#include "dispatch.h" - /* import */ extern ServerOptions options; @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.22 2000/07/16 08:27:20 markus Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.24 2000/08/15 19:20:46 markus Exp $"); #include "ssh.h" #include "rsa.h" @@ -31,7 +31,7 @@ RCSID("$OpenBSD: authfd.c,v 1.22 2000/07/16 08:27:20 markus Exp $"); #include "kex.h" /* helper */ -int ssh_agent_get_reply(AuthenticationConnection *auth); +int decode_reply(int type); /* Returns the number of the authentication fd, or -1 if there is none. */ @@ -39,7 +39,7 @@ int ssh_get_authentication_socket() { const char *authsocket; - int sock; + int sock, len; struct sockaddr_un sunaddr; authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); @@ -48,6 +48,11 @@ ssh_get_authentication_socket() sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); +#ifdef HAVE_SUN_LEN_IN_SOCKADDR_UN + sunaddr.sun_len = len = SUN_LEN(&sunaddr)+1; +#else /* HAVE_SUN_LEN_IN_SOCKADDR_UN */ + len = SUN_LEN(&sunaddr)+1; +#endif /* HAVE_SUN_LEN_IN_SOCKADDR_UN */ sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) @@ -58,13 +63,67 @@ ssh_get_authentication_socket() close(sock); return -1; } - if (connect(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { + if (connect(sock, (struct sockaddr *) & sunaddr, len) < 0) { close(sock); return -1; } return sock; } +int +ssh_request_reply(AuthenticationConnection *auth, + Buffer *request, Buffer *reply) +{ + int l, len; + char buf[1024]; + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(request); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(request), + buffer_len(request)) != buffer_len(request)) { + error("Error writing to authentication socket."); + return 0; + } + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + len = 4; + while (len > 0) { + l = read(auth->fd, buf + 4 - len, len); + if (l <= 0) { + error("Error reading response length from authentication socket."); + return 0; + } + len -= l; + } + + /* Extract the length, and check it for sanity. */ + len = GET_32BIT(buf); + if (len > 256 * 1024) + fatal("Authentication response too long: %d", len); + + /* Read the rest of the response in to the buffer. */ + buffer_clear(reply); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + l = read(auth->fd, buf, l); + if (l <= 0) { + error("Error reading response from authentication socket."); + return 0; + } + buffer_append(reply, (char *) buf, l); + len -= l; + } + return 1; +} + /* * Closes the agent socket if it should be closed (depends on how it was * obtained). The argument must have been returned by @@ -133,62 +192,35 @@ ssh_close_authentication_connection(AuthenticationConnection *ac) int ssh_get_first_identity(AuthenticationConnection *auth, - BIGNUM *e, BIGNUM *n, char **comment) + BIGNUM *e, BIGNUM *n, char **comment) { - unsigned char msg[8192]; - int len, l; + Buffer request; + int type; /* * Send a message to the agent requesting for a list of the * identities it can represent. */ - PUT_32BIT(msg, 1); - msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES; - if (atomicio(write, auth->fd, msg, 5) != 5) { - error("write auth->fd: %.100s", strerror(errno)); - return 0; - } - /* Read the length of the response. XXX implement timeouts here. */ - len = 4; - while (len > 0) { - l = read(auth->fd, msg + 4 - len, len); - if (l <= 0) { - error("read auth->fd: %.100s", strerror(errno)); - return 0; - } - len -= l; - } - - /* - * Extract the length, and check it for sanity. (We cannot trust - * authentication agents). - */ - len = GET_32BIT(msg); - if (len < 1 || len > 256 * 1024) - fatal("Authentication reply message too long: %d\n", len); + buffer_init(&request); + buffer_put_char(&request, SSH_AGENTC_REQUEST_RSA_IDENTITIES); - /* Read the packet itself. */ buffer_clear(&auth->identities); - while (len > 0) { - l = len; - if (l > sizeof(msg)) - l = sizeof(msg); - l = read(auth->fd, msg, l); - if (l <= 0) - fatal("Incomplete authentication reply."); - buffer_append(&auth->identities, (char *) msg, l); - len -= l; + if (ssh_request_reply(auth, &request, &auth->identities) == 0) { + buffer_free(&request); + return 0; } + buffer_free(&request); /* Get message type, and verify that we got a proper answer. */ - buffer_get(&auth->identities, (char *) msg, 1); - if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER) - fatal("Bad authentication reply message type: %d", msg[0]); + type = buffer_get_char(&auth->identities); + if (type != SSH_AGENT_RSA_IDENTITIES_ANSWER) + fatal("Bad authentication reply message type: %d", type); /* Get the number of entries in the response and check it for sanity. */ auth->howmany = buffer_get_int(&auth->identities); if (auth->howmany > 1024) - fatal("Too many identities in authentication reply: %d\n", auth->howmany); + fatal("Too many identities in authentication reply: %d\n", + auth->howmany); /* Return the first entry (if any). */ return ssh_get_next_identity(auth, e, n, comment); @@ -203,7 +235,7 @@ ssh_get_first_identity(AuthenticationConnection *auth, int ssh_get_next_identity(AuthenticationConnection *auth, - BIGNUM *e, BIGNUM *n, char **comment) + BIGNUM *e, BIGNUM *n, char **comment) { unsigned int bits; @@ -240,23 +272,22 @@ ssh_get_next_identity(AuthenticationConnection *auth, int ssh_decrypt_challenge(AuthenticationConnection *auth, - BIGNUM* e, BIGNUM *n, BIGNUM *challenge, - unsigned char session_id[16], - unsigned int response_type, - unsigned char response[16]) + BIGNUM* e, BIGNUM *n, BIGNUM *challenge, + unsigned char session_id[16], + unsigned int response_type, + unsigned char response[16]) { Buffer buffer; - unsigned char buf[8192]; - int len, l, i; + int success = 0; + int i; + int type; - /* Response type 0 is no longer supported. */ if (response_type == 0) - fatal("Compatibility with ssh protocol version 1.0 no longer supported."); + fatal("Compatibility with ssh protocol version " + "1.0 no longer supported."); - /* Format a message to the agent. */ - buf[0] = SSH_AGENTC_RSA_CHALLENGE; buffer_init(&buffer); - buffer_append(&buffer, (char *) buf, 1); + buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE); buffer_put_int(&buffer, BN_num_bits(n)); buffer_put_bignum(&buffer, e); buffer_put_bignum(&buffer, n); @@ -264,77 +295,27 @@ ssh_decrypt_challenge(AuthenticationConnection *auth, buffer_append(&buffer, (char *) session_id, 16); buffer_put_int(&buffer, response_type); - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); -error_cleanup: + if (ssh_request_reply(auth, &buffer, &buffer) == 0) { buffer_free(&buffer); return 0; } - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - goto error_cleanup; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Authentication response too long: %d", len); - - /* Read the rest of the response in tothe buffer. */ - buffer_clear(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - goto error_cleanup; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - buffer_get(&buffer, (char *) buf, 1); + type = buffer_get_char(&buffer); - /* Check for agent failure message. */ - if (buf[0] == SSH_AGENT_FAILURE) { + if (type == SSH_AGENT_FAILURE) { log("Agent admitted failure to authenticate using the key."); - goto error_cleanup; + } else if (type != SSH_AGENT_RSA_RESPONSE) { + fatal("Bad authentication response: %d", type); + } else { + success = 1; + /* + * Get the response from the packet. This will abort with a + * fatal error if the packet is corrupt. + */ + for (i = 0; i < 16; i++) + response[i] = buffer_get_char(&buffer); } - /* Now it must be an authentication response packet. */ - if (buf[0] != SSH_AGENT_RSA_RESPONSE) - fatal("Bad authentication response: %d", buf[0]); - - /* - * Get the response from the packet. This will abort with a fatal - * error if the packet is corrupt. - */ - for (i = 0; i < 16; i++) - response[i] = buffer_get_char(&buffer); - - /* The buffer containing the packet is no longer needed. */ buffer_free(&buffer); - - /* Correct answer. */ - return 1; + return success; } /* Encode key for a message to the agent. */ @@ -378,8 +359,7 @@ int ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) { Buffer buffer; - unsigned char buf[8192]; - int len; + int type; buffer_init(&buffer); @@ -395,21 +375,13 @@ ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) return 0; break; } - - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); + if (ssh_request_reply(auth, &buffer, &buffer) == 0) { buffer_free(&buffer); return 0; } + type = buffer_get_char(&buffer); buffer_free(&buffer); - return ssh_agent_get_reply(auth); + return decode_reply(type); } /* @@ -421,30 +393,21 @@ int ssh_remove_identity(AuthenticationConnection *auth, RSA *key) { Buffer buffer; - unsigned char buf[5]; - int len; + int type; - /* Format a message to the agent. */ buffer_init(&buffer); buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY); buffer_put_int(&buffer, BN_num_bits(key->n)); buffer_put_bignum(&buffer, key->e); buffer_put_bignum(&buffer, key->n); - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); + if (ssh_request_reply(auth, &buffer, &buffer) == 0) { buffer_free(&buffer); return 0; } + type = buffer_get_char(&buffer); buffer_free(&buffer); - return ssh_agent_get_reply(auth); + return decode_reply(type); } /* @@ -455,73 +418,27 @@ ssh_remove_identity(AuthenticationConnection *auth, RSA *key) int ssh_remove_all_identities(AuthenticationConnection *auth) { - unsigned char buf[5]; + Buffer buffer; + int type; - /* Get the length of the message, and format it in the buffer. */ - PUT_32BIT(buf, 1); - buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES; + buffer_init(&buffer); + buffer_put_char(&buffer, SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES); - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 5) != 5) { - error("Error writing to authentication socket."); + if (ssh_request_reply(auth, &buffer, &buffer) == 0) { + buffer_free(&buffer); return 0; } - return ssh_agent_get_reply(auth); + type = buffer_get_char(&buffer); + buffer_free(&buffer); + return decode_reply(type); } -/* - * Read for reply from agent. returns 1 for success, 0 on error - */ - int -ssh_agent_get_reply(AuthenticationConnection *auth) +decode_reply(int type) { - Buffer buffer; - unsigned char buf[8192]; - int len, l, type; - - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - buffer_free(&buffer); - return 0; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Response from agent too long: %d", len); - - /* Read the rest of the response in to the buffer. */ - buffer_init(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - buffer_free(&buffer); - return 0; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - type = buffer_get_char(&buffer); - buffer_free(&buffer); switch (type) { case SSH_AGENT_FAILURE: -log("SSH_AGENT_FAILURE"); + log("SSH_AGENT_FAILURE"); return 0; case SSH_AGENT_SUCCESS: return 1; diff --git a/bsd-mktemp.c b/bsd-mktemp.c index 7c02ea1a..23831fa9 100644 --- a/bsd-mktemp.c +++ b/bsd-mktemp.c @@ -52,6 +52,7 @@ static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp #include <unistd.h> #include "bsd-misc.h" +#include "bsd-arc4random.h" static int _gettemp(char *, int *, int, int); diff --git a/configure.in b/configure.in index 974d0df6..e9467011 100644 --- a/configure.in +++ b/configure.in @@ -686,6 +686,22 @@ OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmp.h, HAVE_TIME_IN_UTMP) OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmpx.h, HAVE_TIME_IN_UTMPX) OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmpx.h, HAVE_TV_IN_UTMPX) +AC_CACHE_CHECK([for sun_len field in struct sockaddr_un], + ac_cv_have_sun_len_in_struct_sockaddr_un, [ + AC_TRY_COMPILE( + [ +#include <sys/types.h> +#include <sys/socket.h> + ], + [ struct sockaddr_un s; s.sun_len = 1; ], + [ ac_cv_have_sun_len_in_struct_sockaddr_un="yes" ], + [ ac_cv_have_sun_len_in_struct_sockaddr_un="no" ], + ) +]) +if test "x$ac_cv_have_sun_len_in_struct_sockaddr_un" = "xyes" ; then + AC_DEFINE(HAVE_SUN_LEN_IN_SOCKADDR_UN) +fi + AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], ac_cv_have_ss_family_in_struct_ss, [ AC_TRY_COMPILE( @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.43 2000/07/14 22:59:46 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.45 2000/08/02 17:27:04 provos Exp $"); #include "ssh.h" #include "cipher.h" @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.49 2000/07/14 22:59:46 markus Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.50 2000/07/22 09:14:36 markus Exp $"); #include "ssh.h" #include "servconf.h" @@ -76,6 +76,8 @@ initialize_server_options(ServerOptions *options) options->protocol = SSH_PROTO_UNKNOWN; options->gateway_ports = -1; options->num_subsystems = 0; + options->max_startups_begin = -1; + options->max_startups_rate = -1; options->max_startups = -1; } @@ -162,6 +164,10 @@ fill_default_server_options(ServerOptions *options) options->gateway_ports = 0; if (options->max_startups == -1) options->max_startups = 10; + if (options->max_startups_rate == -1) + options->max_startups_rate = 100; /* 100% */ + if (options->max_startups_begin == -1) + options->max_startups_begin = options->max_startups; } /* Keyword tokens. */ @@ -644,6 +650,22 @@ parse_flag: break; case sMaxStartups: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing MaxStartups spec.", + filename, linenum); + if (sscanf(arg, "%d:%d:%d", + &options->max_startups_begin, + &options->max_startups_rate, + &options->max_startups) == 3) { + if (options->max_startups_begin > + options->max_startups || + options->max_startups_rate > 100 || + options->max_startups_rate < 1) + fatal("%s line %d: Illegal MaxStartups spec.", + filename, linenum); + break; + } intptr = &options->max_startups; goto parse_int; @@ -13,7 +13,7 @@ * */ -/* RCSID("$OpenBSD: servconf.h,v 1.26 2000/06/26 21:59:18 markus Exp $"); */ +/* RCSID("$OpenBSD: servconf.h,v 1.27 2000/07/22 09:14:36 markus Exp $"); */ #ifndef SERVCONF_H #define SERVCONF_H @@ -100,6 +100,8 @@ typedef struct { char *subsystem_name[MAX_SUBSYSTEMS]; char *subsystem_command[MAX_SUBSYSTEMS]; + int max_startups_begin; + int max_startups_rate; int max_startups; } ServerOptions; @@ -8,7 +8,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.23 2000/07/11 08:11:33 deraadt Exp $"); +RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -85,6 +85,7 @@ void session_pty_cleanup(Session *s); void session_proctitle(Session *s); void do_exec_pty(Session *s, const char *command, struct passwd * pw); void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); +void do_login(Session *s); void do_child(const char *command, struct passwd * pw, const char *term, @@ -101,6 +102,7 @@ static const char *__progname = "sshd"; extern int log_stderr; extern int debug_flag; +extern unsigned int utmp_len; extern int startup_pipe; @@ -523,35 +525,14 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) void do_exec_pty(Session *s, const char *command, struct passwd * pw) { - FILE *f; - char buf[100], *time_string; - char line[256]; - const char *hostname; int fdout, ptyfd, ttyfd, ptymaster; - int quiet_login; pid_t pid; - socklen_t fromlen; - struct sockaddr_storage from; - struct stat st; - time_t last_login_time; if (s == NULL) fatal("do_exec_pty: no session"); ptyfd = s->ptyfd; ttyfd = s->ttyfd; - /* Get remote host name. */ - hostname = get_canonical_hostname(); - - /* - * Get the time when the user last logged in. Buf will be set to - * contain the hostname the last login was from. - */ - if (!options.use_login) { - last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, - buf, sizeof(buf)); - } - #ifdef USE_PAM do_pam_session(pw->pw_name, s->tty); do_pam_setcred(); @@ -559,10 +540,7 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw) /* Fork the child. */ if ((pid = fork()) == 0) { - pid = getpid(); - - /* Child. Reinitialize the log because the pid has - changed. */ + /* Child. Reinitialize the log because the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); /* Close the master side of the pseudo tty. */ @@ -586,82 +564,10 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw) /* Close the extra descriptor for the pseudo tty. */ close(ttyfd); -/* XXXX ? move to do_child() ??*/ - /* - * Get IP address of client. This is needed because we want - * to record where the user logged in from. If the - * connection is not a socket, let the ip address be 0.0.0.0. - */ - memset(&from, 0, sizeof(from)); - if (packet_connection_is_on_socket()) { - fromlen = sizeof(from); - if (getpeername(packet_get_connection_in(), - (struct sockaddr *) & from, &fromlen) < 0) { - debug("getpeername: %.100s", strerror(errno)); - fatal_cleanup(); - } - } - /* Record that there was a login on that terminal. */ - if (!options.use_login || command != NULL) - record_login(pid, s->tty, pw->pw_name, pw->pw_uid, - hostname, (struct sockaddr *)&from); - - /* Check if .hushlogin exists. */ - snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); - quiet_login = stat(line, &st) >= 0; + /* record login, etc. similar to login(1) */ + if (command == NULL && !options.use_login) + do_login(s); -#ifdef USE_PAM - if (!quiet_login) - print_pam_messages(); -#endif /* USE_PAM */ - - /* - * If the user has logged in before, display the time of last - * login. However, don't display anything extra if a command - * has been specified (so that ssh can be used to execute - * commands on a remote machine without users knowing they - * are going to another machine). Login(1) will do this for - * us as well, so check if login(1) is used - */ - if (command == NULL && last_login_time != 0 && !quiet_login && - !options.use_login) { - /* Convert the date to a string. */ - time_string = ctime(&last_login_time); - /* Remove the trailing newline. */ - if (strchr(time_string, '\n')) - *strchr(time_string, '\n') = 0; - /* Display the last login time. Host if displayed - if known. */ - if (strcmp(buf, "") == 0) - printf("Last login: %s\r\n", time_string); - else - printf("Last login: %s from %s\r\n", time_string, buf); - } - /* - * Print /etc/motd unless a command was specified or printing - * it was disabled in server options or login(1) will be - * used. Note that some machines appear to print it in - * /etc/profile or similar. - */ - if (command == NULL && options.print_motd && !quiet_login && - !options.use_login) { - /* Print /etc/motd if it exists. */ - f = fopen("/etc/motd", "r"); - if (f) { - while (fgets(line, sizeof(line), f)) - fputs(line, stdout); - fclose(f); - } - } -#if defined(WITH_AIXAUTHENTICATE) - /* |