summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog41
-rw-r--r--Makefile.in2
-rw-r--r--acconfig.h3
-rw-r--r--auth-krb4.c8
-rw-r--r--auth.c4
-rw-r--r--authfd.c325
-rw-r--r--bsd-mktemp.c1
-rw-r--r--configure.in16
-rw-r--r--readconf.c2
-rw-r--r--servconf.c24
-rw-r--r--servconf.h4
-rw-r--r--session.c194
-rw-r--r--ssh.14
-rw-r--r--sshd.865
-rw-r--r--sshd.c43
-rw-r--r--sshd_config1
16 files changed, 400 insertions, 337 deletions
diff --git a/ChangeLog b/ChangeLog
index 0e122cf3..2f5cee9a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/acconfig.h b/acconfig.h
index 6c25c8fc..86607710 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -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!
diff --git a/auth.c b/auth.c
index 5aeeec6d..dc3e8211 100644
--- a/auth.c
+++ b/auth.c
@@ -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;
diff --git a/authfd.c b/authfd.c
index 227c9928..a34e111a 100644
--- a/authfd.c
+++ b/authfd.c
@@ -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(
diff --git a/readconf.c b/readconf.c
index 06cfaa1a..f31b1c4e 100644
--- a/readconf.c
+++ b/readconf.c
@@ -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"
diff --git a/servconf.c b/servconf.c
index 477204cf..6affb51e 100644
--- a/servconf.c
+++ b/servconf.c
@@ -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;
diff --git a/servconf.h b/servconf.h
index 95593722..3b65c6a6 100644
--- a/servconf.h
+++ b/servconf.h
@@ -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;
diff --git a/session.c b/session.c
index e68718a7..d65b0698 100644
--- a/session.c
+++ b/session.c
@@ -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)
- /*
- * AIX handles the lastlog info differently. Display it here.
- */
- if (command == NULL && aixloginmsg && *aixloginmsg &&
- !quiet_login && !options.use_login) {
- printf("%s\n", aixloginmsg);
- }
-#endif
/* Do common processing for the child, such as execing the command. */
do_child(command, pw, s->term, s->display, s->auth_proto,
s->auth_data, s->tty);
@@ -699,6 +605,87 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
}
}
+const char *
+get_remote_name_or_ip(void)
+{
+ static const char *remote = "";
+ if (utmp_len > 0)
+ remote = get_canonical_hostname();
+ if (utmp_len == 0 || strlen(remote) > utmp_len)
+ remote = get_remote_ipaddr();
+ return remote;
+}
+
+/* administrative, login(1)-like work */
+void
+do_login(Session *s)
+{
+ FILE *f;
+ char *time_string;
+ char buf[256];
+ socklen_t fromlen;
+ struct sockaddr_storage from;
+ struct stat st;
+ time_t last_login_time;
+ struct passwd * pw = s->pw;
+ pid_t pid = getpid();
+
+ /*
+ * Get IP address of client. If the connection is not a socket, let
+ * the 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();
+ }
+ }