mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-29 16:54:51 +02:00
- (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
This commit is contained in:
parent
11fa2cc383
commit
942da039d2
41
ChangeLog
41
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
|
20000816
|
||||||
- (djm) Replacement for inet_ntoa for Irix (which breaks on gcc)
|
- (djm) Replacement for inet_ntoa for Irix (which breaks on gcc)
|
||||||
- (djm) Fix strerror replacement for old SunOS. Based on patch from
|
- (djm) Fix strerror replacement for old SunOS. Based on patch from
|
||||||
|
@ -34,7 +34,7 @@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
|
|||||||
|
|
||||||
TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS)
|
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
|
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@
|
@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) */
|
/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */
|
||||||
#undef BROKEN_INET_NTOA
|
#undef BROKEN_INET_NTOA
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "servconf.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
|
#ifdef KRB4
|
||||||
char *ticket = NULL;
|
char *ticket = NULL;
|
||||||
@ -82,11 +82,12 @@ auth_krb4_password(struct passwd * pw, const char *password)
|
|||||||
if (r == RD_AP_UNDEC) {
|
if (r == RD_AP_UNDEC) {
|
||||||
/*
|
/*
|
||||||
* Probably didn't have a srvtab on
|
* Probably didn't have a srvtab on
|
||||||
* localhost. Allow login.
|
* localhost. Disallow login.
|
||||||
*/
|
*/
|
||||||
log("Kerberos V4 TGT for %s unverifiable, "
|
log("Kerberos V4 TGT for %s unverifiable, "
|
||||||
"no srvtab installed? krb_rd_req: %s",
|
"no srvtab installed? krb_rd_req: %s",
|
||||||
pw->pw_name, krb_err_txt[r]);
|
pw->pw_name, krb_err_txt[r]);
|
||||||
|
goto kerberos_auth_failure;
|
||||||
} else if (r != KSUCCESS) {
|
} else if (r != KSUCCESS) {
|
||||||
log("Kerberos V4 %s ticket unverifiable: %s",
|
log("Kerberos V4 %s ticket unverifiable: %s",
|
||||||
KRB4_SERVICE_NAME, krb_err_txt[r]);
|
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) {
|
} 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 the error.
|
||||||
*/
|
*/
|
||||||
log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
|
log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
|
||||||
"not registered, or srvtab is wrong?", pw->pw_name,
|
"not registered, or srvtab is wrong?", pw->pw_name,
|
||||||
krb_err_txt[r], KRB4_SERVICE_NAME, phost);
|
krb_err_txt[r], KRB4_SERVICE_NAME, phost);
|
||||||
|
goto kerberos_auth_failure;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* TGT is bad, forget it. Possibly spoofed!
|
* TGT is bad, forget it. Possibly spoofed!
|
||||||
|
4
auth.c
4
auth.c
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "xmalloc.h"
|
||||||
#include "rsa.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 "ssh2.h"
|
||||||
#include "auth.h"
|
#include "auth.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "dispatch.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* import */
|
/* import */
|
||||||
extern ServerOptions options;
|
extern ServerOptions options;
|
||||||
|
331
authfd.c
331
authfd.c
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "ssh.h"
|
||||||
#include "rsa.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"
|
#include "kex.h"
|
||||||
|
|
||||||
/* helper */
|
/* 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. */
|
/* Returns the number of the authentication fd, or -1 if there is none. */
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ int
|
|||||||
ssh_get_authentication_socket()
|
ssh_get_authentication_socket()
|
||||||
{
|
{
|
||||||
const char *authsocket;
|
const char *authsocket;
|
||||||
int sock;
|
int sock, len;
|
||||||
struct sockaddr_un sunaddr;
|
struct sockaddr_un sunaddr;
|
||||||
|
|
||||||
authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
|
authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
|
||||||
@ -48,6 +48,11 @@ ssh_get_authentication_socket()
|
|||||||
|
|
||||||
sunaddr.sun_family = AF_UNIX;
|
sunaddr.sun_family = AF_UNIX;
|
||||||
strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
|
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);
|
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (sock < 0)
|
if (sock < 0)
|
||||||
@ -58,13 +63,67 @@ ssh_get_authentication_socket()
|
|||||||
close(sock);
|
close(sock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (connect(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
|
if (connect(sock, (struct sockaddr *) & sunaddr, len) < 0) {
|
||||||
close(sock);
|
close(sock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return sock;
|
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
|
* Closes the agent socket if it should be closed (depends on how it was
|
||||||
* obtained). The argument must have been returned by
|
* obtained). The argument must have been returned by
|
||||||
@ -133,62 +192,35 @@ ssh_close_authentication_connection(AuthenticationConnection *ac)
|
|||||||
|
|
||||||
int
|
int
|
||||||
ssh_get_first_identity(AuthenticationConnection *auth,
|
ssh_get_first_identity(AuthenticationConnection *auth,
|
||||||
BIGNUM *e, BIGNUM *n, char **comment)
|
BIGNUM *e, BIGNUM *n, char **comment)
|
||||||
{
|
{
|
||||||
unsigned char msg[8192];
|
Buffer request;
|
||||||
int len, l;
|
int type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send a message to the agent requesting for a list of the
|
* Send a message to the agent requesting for a list of the
|
||||||
* identities it can represent.
|
* identities it can represent.
|
||||||
*/
|
*/
|
||||||
PUT_32BIT(msg, 1);
|
buffer_init(&request);
|
||||||
msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
|
buffer_put_char(&request, SSH_AGENTC_REQUEST_RSA_IDENTITIES);
|
||||||
if (atomicio(write, auth->fd, msg, 5) != 5) {
|
|
||||||
error("write auth->fd: %.100s", strerror(errno));
|
buffer_clear(&auth->identities);
|
||||||
|
if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
|
||||||
|
buffer_free(&request);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Read the length of the response. XXX implement timeouts here. */
|
buffer_free(&request);
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get message type, and verify that we got a proper answer. */
|
/* Get message type, and verify that we got a proper answer. */
|
||||||
buffer_get(&auth->identities, (char *) msg, 1);
|
type = buffer_get_char(&auth->identities);
|
||||||
if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER)
|
if (type != SSH_AGENT_RSA_IDENTITIES_ANSWER)
|
||||||
fatal("Bad authentication reply message type: %d", msg[0]);
|
fatal("Bad authentication reply message type: %d", type);
|
||||||
|
|
||||||
/* Get the number of entries in the response and check it for sanity. */
|
/* Get the number of entries in the response and check it for sanity. */
|
||||||
auth->howmany = buffer_get_int(&auth->identities);
|
auth->howmany = buffer_get_int(&auth->identities);
|
||||||
if (auth->howmany > 1024)
|
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 the first entry (if any). */
|
||||||
return ssh_get_next_identity(auth, e, n, comment);
|
return ssh_get_next_identity(auth, e, n, comment);
|
||||||
@ -203,7 +235,7 @@ ssh_get_first_identity(AuthenticationConnection *auth,
|
|||||||
|
|
||||||
int
|
int
|
||||||
ssh_get_next_identity(AuthenticationConnection *auth,
|
ssh_get_next_identity(AuthenticationConnection *auth,
|
||||||
BIGNUM *e, BIGNUM *n, char **comment)
|
BIGNUM *e, BIGNUM *n, char **comment)
|
||||||
{
|
{
|
||||||
unsigned int bits;
|
unsigned int bits;
|
||||||
|
|
||||||
@ -240,23 +272,22 @@ ssh_get_next_identity(AuthenticationConnection *auth,
|
|||||||
|
|
||||||
int
|
int
|
||||||
ssh_decrypt_challenge(AuthenticationConnection *auth,
|
ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||||
BIGNUM* e, BIGNUM *n, BIGNUM *challenge,
|
BIGNUM* e, BIGNUM *n, BIGNUM *challenge,
|
||||||
unsigned char session_id[16],
|
unsigned char session_id[16],
|
||||||
unsigned int response_type,
|
unsigned int response_type,
|
||||||
unsigned char response[16])
|
unsigned char response[16])
|
||||||
{
|
{
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
unsigned char buf[8192];
|
int success = 0;
|
||||||
int len, l, i;
|
int i;
|
||||||
|
int type;
|
||||||
|
|
||||||
/* Response type 0 is no longer supported. */
|
|
||||||
if (response_type == 0)
|
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_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_int(&buffer, BN_num_bits(n));
|
||||||
buffer_put_bignum(&buffer, e);
|
buffer_put_bignum(&buffer, e);
|
||||||
buffer_put_bignum(&buffer, n);
|
buffer_put_bignum(&buffer, n);
|
||||||
@ -264,77 +295,27 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
|
|||||||
buffer_append(&buffer, (char *) session_id, 16);
|
buffer_append(&buffer, (char *) session_id, 16);
|
||||||
buffer_put_int(&buffer, response_type);
|
buffer_put_int(&buffer, response_type);
|
||||||
|
|
||||||
/* Get the length of the message, and format it in the buffer. */
|
if (ssh_request_reply(auth, &buffer, &buffer) == 0) {
|
||||||
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:
|
|
||||||
buffer_free(&buffer);
|
buffer_free(&buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
type = buffer_get_char(&buffer);
|
||||||
* 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. */
|
if (type == SSH_AGENT_FAILURE) {
|
||||||
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);
|
|
||||||
|
|
||||||
/* Check for agent failure message. */
|
|
||||||
if (buf[0] == SSH_AGENT_FAILURE) {
|
|
||||||
log("Agent admitted failure to authenticate using the key.");
|
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);
|
buffer_free(&buffer);
|
||||||
|
return success;
|
||||||
/* Correct answer. */
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode key for a message to the agent. */
|
/* Encode key for a message to the agent. */
|
||||||
@ -378,8 +359,7 @@ int
|
|||||||
ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
|
ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
|
||||||
{
|
{
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
unsigned char buf[8192];
|
int type;
|
||||||
int len;
|
|
||||||
|
|
||||||
buffer_init(&buffer);
|
buffer_init(&buffer);
|
||||||
|
|
||||||
@ -395,21 +375,13 @@ ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (ssh_request_reply(auth, &buffer, &buffer) == 0) {
|
||||||
/* 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.");
|
|
||||||
buffer_free(&buffer);
|
buffer_free(&buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
type = buffer_get_char(&buffer);
|
||||||
buffer_free(&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)
|
ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
|
||||||
{
|
{
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
unsigned char buf[5];
|
int type;
|
||||||
int len;
|
|
||||||
|
|
||||||
/* Format a message to the agent. */
|
|
||||||
buffer_init(&buffer);
|
buffer_init(&buffer);
|
||||||
buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY);
|
buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY);
|
||||||
buffer_put_int(&buffer, BN_num_bits(key->n));
|
buffer_put_int(&buffer, BN_num_bits(key->n));
|
||||||
buffer_put_bignum(&buffer, key->e);
|
buffer_put_bignum(&buffer, key->e);
|
||||||
buffer_put_bignum(&buffer, key->n);
|
buffer_put_bignum(&buffer, key->n);
|
||||||
|
|
||||||
/* Get the length of the message, and format it in the buffer. */
|
if (ssh_request_reply(auth, &buffer, &buffer) == 0) {
|
||||||
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.");
|
|
||||||
buffer_free(&buffer);
|
buffer_free(&buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
type = buffer_get_char(&buffer);
|
||||||
buffer_free(&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
|
int
|
||||||
ssh_remove_all_identities(AuthenticationConnection *auth)
|
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. */
|
buffer_init(&buffer);
|
||||||
PUT_32BIT(buf, 1);
|
buffer_put_char(&buffer, SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES);
|
||||||
buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES;
|
|
||||||
|
|
||||||
/* Send the length and then the packet to the agent. */
|
if (ssh_request_reply(auth, &buffer, &buffer) == 0) {
|
||||||
if (atomicio(write, auth->fd, buf, 5) != 5) {
|
buffer_free(&buffer);
|
||||||
error("Error writing to authentication socket.");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ssh_agent_get_reply(auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read for reply from agent. returns 1 for success, 0 on error
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
ssh_agent_get_reply(AuthenticationConnection *auth)
|
|
||||||
{
|
|
||||||
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);
|
type = buffer_get_char(&buffer);
|
||||||
buffer_free(&buffer);
|
buffer_free(&buffer);
|
||||||
|
return decode_reply(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
decode_reply(int type)
|
||||||
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSH_AGENT_FAILURE:
|
case SSH_AGENT_FAILURE:
|
||||||
log("SSH_AGENT_FAILURE");
|
log("SSH_AGENT_FAILURE");
|
||||||
return 0;
|
return 0;
|
||||||
case SSH_AGENT_SUCCESS:
|
case SSH_AGENT_SUCCESS:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -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 <unistd.h>
|
||||||
|
|
||||||
#include "bsd-misc.h"
|
#include "bsd-misc.h"
|
||||||
|
#include "bsd-arc4random.h"
|
||||||
|
|
||||||
static int _gettemp(char *, int *, int, int);
|
static int _gettemp(char *, int *, int, int);
|
||||||
|
|
||||||
|
16
configure.in
16
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_time, utmpx.h, HAVE_TIME_IN_UTMPX)
|
||||||
OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmpx.h, HAVE_TV_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_CACHE_CHECK([for ss_family field in struct sockaddr_storage],
|
||||||
ac_cv_have_ss_family_in_struct_ss, [
|
ac_cv_have_ss_family_in_struct_ss, [
|
||||||
AC_TRY_COMPILE(
|
AC_TRY_COMPILE(
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "ssh.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
|
24
servconf.c
24
servconf.c
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "ssh.h"
|
||||||
#include "servconf.h"
|
#include "servconf.h"
|
||||||
@ -76,6 +76,8 @@ initialize_server_options(ServerOptions *options)
|
|||||||
options->protocol = SSH_PROTO_UNKNOWN;
|
options->protocol = SSH_PROTO_UNKNOWN;
|
||||||
options->gateway_ports = -1;
|
options->gateway_ports = -1;
|
||||||
options->num_subsystems = 0;
|
options->num_subsystems = 0;
|
||||||
|
options->max_startups_begin = -1;
|
||||||
|
options->max_startups_rate = -1;
|
||||||
options->max_startups = -1;
|
options->max_startups = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +164,10 @@ fill_default_server_options(ServerOptions *options)
|
|||||||
options->gateway_ports = 0;
|
options->gateway_ports = 0;
|
||||||
if (options->max_startups == -1)
|
if (options->max_startups == -1)
|
||||||
options->max_startups = 10;
|
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. */
|
/* Keyword tokens. */
|
||||||
@ -644,6 +650,22 @@ parse_flag:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case sMaxStartups:
|
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;
|
intptr = &options->max_startups;
|
||||||
goto parse_int;
|
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
|
#ifndef SERVCONF_H
|
||||||
#define SERVCONF_H
|
#define SERVCONF_H
|
||||||
@ -100,6 +100,8 @@ typedef struct {
|
|||||||
char *subsystem_name[MAX_SUBSYSTEMS];
|
char *subsystem_name[MAX_SUBSYSTEMS];
|
||||||
char *subsystem_command[MAX_SUBSYSTEMS];
|
char *subsystem_command[MAX_SUBSYSTEMS];
|
||||||
|
|
||||||
|
int max_startups_begin;
|
||||||
|
int max_startups_rate;
|
||||||
int max_startups;
|
int max_startups;
|
||||||
|
|
||||||
} ServerOptions;
|
} ServerOptions;
|
||||||
|
194
session.c
194
session.c
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "xmalloc.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
@ -85,6 +85,7 @@ void session_pty_cleanup(Session *s);
|
|||||||
void session_proctitle(Session *s);
|
void session_proctitle(Session *s);
|
||||||
void do_exec_pty(Session *s, const char *command, struct passwd * pw);
|
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_exec_no_pty(Session *s, const char *command, struct passwd * pw);
|
||||||
|
void do_login(Session *s);
|
||||||
|
|
||||||
void
|
void
|
||||||
do_child(const char *command, struct passwd * pw, const char *term,
|
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 log_stderr;
|
||||||
extern int debug_flag;
|
extern int debug_flag;
|
||||||
|
extern unsigned int utmp_len;
|
||||||
|
|
||||||
extern int startup_pipe;
|
extern int startup_pipe;
|
||||||
|
|
||||||
@ -523,35 +525,14 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw)
|
|||||||
void
|
void
|
||||||
do_exec_pty(Session *s, const char *command, struct passwd * pw)
|
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 fdout, ptyfd, ttyfd, ptymaster;
|
||||||
int quiet_login;
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
socklen_t fromlen;
|
|
||||||
struct sockaddr_storage from;
|
|
||||||
struct stat st;
|
|
||||||
time_t last_login_time;
|
|
||||||
|
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
fatal("do_exec_pty: no session");
|
fatal("do_exec_pty: no session");
|
||||||
ptyfd = s->ptyfd;
|
ptyfd = s->ptyfd;
|
||||||
ttyfd = s->ttyfd;
|
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
|
#ifdef USE_PAM
|
||||||
do_pam_session(pw->pw_name, s->tty);
|
do_pam_session(pw->pw_name, s->tty);
|
||||||
do_pam_setcred();
|
do_pam_setcred();
|
||||||
@ -559,10 +540,7 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
|
|||||||
|
|
||||||
/* Fork the child. */
|
/* Fork the child. */
|
||||||
if ((pid = fork()) == 0) {
|
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);
|
log_init(__progname, options.log_level, options.log_facility, log_stderr);
|
||||||
|
|
||||||
/* Close the master side of the pseudo tty. */
|
/* 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 the extra descriptor for the pseudo tty. */
|
||||||
close(ttyfd);
|
close(ttyfd);
|
||||||
|
|
||||||
/* XXXX ? move to do_child() ??*/
|
/* record login, etc. similar to login(1) */
|
||||||
/*
|
if (command == NULL && !options.use_login)
|
||||||
* Get IP address of client. This is needed because we want
|
do_login(s);
|
||||||
* 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;
|
|
||||||
|
|
||||||
#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 common processing for the child, such as execing the command. */
|
||||||
do_child(command, pw, s->term, s->display, s->auth_proto,
|
do_child(command, pw, s->term, s->display, s->auth_proto,
|
||||||
s->auth_data, s->tty);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record that there was a login on that tty from the remote host. */
|
||||||
|
record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
|
||||||
|
get_remote_name_or_ip(), (struct sockaddr *)&from);
|
||||||
|
|
||||||
|
/* Done if .hushlogin exists. */
|
||||||
|
snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
|
||||||
|
if (stat(buf, &st) >= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef USE_PAM
|
||||||
|
print_pam_messages();
|
||||||
|
#endif /* USE_PAM */
|
||||||
|
#ifdef WITH_AIXAUTHENTICATE
|
||||||
|
if (aixloginmsg && *aixloginmsg)
|
||||||
|
printf("%s\n", aixloginmsg);
|
||||||
|
#endif /* WITH_AIXAUTHENTICATE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the time when the user last logged in. 'buf' will be set
|
||||||
|
* to contain the hostname the last login was from.
|
||||||
|
*/
|
||||||
|
last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
|
||||||
|
buf, sizeof(buf));
|
||||||
|
if (last_login_time != 0) {
|
||||||
|
time_string = ctime(&last_login_time);
|
||||||
|
if (strchr(time_string, '\n'))
|
||||||
|
*strchr(time_string, '\n') = 0;
|
||||||
|
if (strcmp(buf, "") == 0)
|
||||||
|
printf("Last login: %s\r\n", time_string);
|
||||||
|
else
|
||||||
|
printf("Last login: %s from %s\r\n", time_string, buf);
|
||||||
|
}
|
||||||
|
if (options.print_motd) {
|
||||||
|
f = fopen("/etc/motd", "r");
|
||||||
|
if (f) {
|
||||||
|
while (fgets(buf, sizeof(buf), f))
|
||||||
|
fputs(buf, stdout);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the value of the given variable in the environment. If the variable
|
* Sets the value of the given variable in the environment. If the variable
|
||||||
* already exists, its value is overriden.
|
* already exists, its value is overriden.
|
||||||
@ -1265,8 +1252,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
|||||||
} else {
|
} else {
|
||||||
/* Launch login(1). */
|
/* Launch login(1). */
|
||||||
|
|
||||||
execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(),
|
execl(LOGIN_PROGRAM, "login",
|
||||||
"-p", "-f", "--", pw->pw_name, NULL);
|
"-h", get_remote_name_or_ip(),
|
||||||
|
"-p", "-f", "--", pw->pw_name, NULL);
|
||||||
|
|
||||||
/* Login couldn't be executed, die. */
|
/* Login couldn't be executed, die. */
|
||||||
|
|
||||||
|
4
ssh.1
4
ssh.1
@ -9,7 +9,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" Created: Sat Apr 22 21:55:14 1995 ylo
|
.\" Created: Sat Apr 22 21:55:14 1995 ylo
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: ssh.1,v 1.28 2000/06/07 09:55:44 djm Exp $
|
.\" $Id: ssh.1,v 1.29 2000/08/18 03:59:06 djm Exp $
|
||||||
.\"
|
.\"
|
||||||
.Dd September 25, 1999
|
.Dd September 25, 1999
|
||||||
.Dt SSH 1
|
.Dt SSH 1
|
||||||
@ -994,7 +994,7 @@ If the current session has no tty,
|
|||||||
this variable is not set.
|
this variable is not set.
|
||||||
.It Ev TZ
|
.It Ev TZ
|
||||||
The timezone variable is set to indicate the present timezone if it
|
The timezone variable is set to indicate the present timezone if it
|
||||||
was set when the daemon was started (e.i., the daemon passes the value
|
was set when the daemon was started (i.e., the daemon passes the value
|
||||||
on to new connections).
|
on to new connections).
|
||||||
.It Ev USER
|
.It Ev USER
|
||||||
Set to the name of the user logging in.
|
Set to the name of the user logging in.
|
||||||
|
65
sshd.8
65
sshd.8
@ -9,7 +9,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" Created: Sat Apr 22 21:55:14 1995 ylo
|
.\" Created: Sat Apr 22 21:55:14 1995 ylo
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: sshd.8,v 1.25 2000/07/11 07:31:39 djm Exp $
|
.\" $Id: sshd.8,v 1.26 2000/08/18 03:59:06 djm Exp $
|
||||||
.\"
|
.\"
|
||||||
.Dd September 25, 1999
|
.Dd September 25, 1999
|
||||||
.Dt SSHD 8
|
.Dt SSHD 8
|
||||||
@ -26,6 +26,7 @@
|
|||||||
.Op Fl h Ar host_key_file
|
.Op Fl h Ar host_key_file
|
||||||
.Op Fl k Ar key_gen_time
|
.Op Fl k Ar key_gen_time
|
||||||
.Op Fl p Ar port
|
.Op Fl p Ar port
|
||||||
|
.Op Fl u Ar len
|
||||||
.Op Fl V Ar client_protocol_id
|
.Op Fl V Ar client_protocol_id
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
@ -104,7 +105,7 @@ into the machine).
|
|||||||
.Pp
|
.Pp
|
||||||
.Ss SSH protocol version 2
|
.Ss SSH protocol version 2
|
||||||
.Pp
|
.Pp
|
||||||
Version 2 works similar:
|
Version 2 works similarly:
|
||||||
Each host has a host-specific DSA key used to identify the host.
|
Each host has a host-specific DSA key used to identify the host.
|
||||||
However, when the daemon starts, it does not generate a server key.
|
However, when the daemon starts, it does not generate a server key.
|
||||||
Forward security is provided through a Diffie-Hellman key agreement.
|
Forward security is provided through a Diffie-Hellman key agreement.
|
||||||
@ -211,6 +212,22 @@ Quiet mode.
|
|||||||
Nothing is sent to the system log.
|
Nothing is sent to the system log.
|
||||||
Normally the beginning,
|
Normally the beginning,
|
||||||
authentication, and termination of each connection is logged.
|
authentication, and termination of each connection is logged.
|
||||||
|
.It Fl u Ar len
|
||||||
|
This option is used to specify the size of the field
|
||||||
|
in the
|
||||||
|
.Li utmp
|
||||||
|
structure that holds the remote host name.
|
||||||
|
If the resolved host name is longer than
|
||||||
|
.Ar len ,
|
||||||
|
the dotted decimal value will be used instead.
|
||||||
|
This allows hosts with very long host names that
|
||||||
|
overflow this field to still be uniquely identified.
|
||||||
|
Specifying
|
||||||
|
.Fl u0
|
||||||
|
indicates that only dotted decimal addresses
|
||||||
|
should be put into the
|
||||||
|
.Pa utmp
|
||||||
|
file.
|
||||||
.It Fl Q
|
.It Fl Q
|
||||||
Do not print an error message if RSA support is missing.
|
Do not print an error message if RSA support is missing.
|
||||||
.It Fl V Ar client_protocol_id
|
.It Fl V Ar client_protocol_id
|
||||||
@ -257,7 +274,7 @@ and
|
|||||||
.Ql ?
|
.Ql ?
|
||||||
can be used as
|
can be used as
|
||||||
wildcards in the patterns.
|
wildcards in the patterns.
|
||||||
Only group names are valid, a numerical group ID isn't recognized.
|
Only group names are valid; a numerical group ID isn't recognized.
|
||||||
By default login is allowed regardless of the primary group.
|
By default login is allowed regardless of the primary group.
|
||||||
.Pp
|
.Pp
|
||||||
.It Cm AllowUsers
|
.It Cm AllowUsers
|
||||||
@ -270,7 +287,7 @@ and
|
|||||||
.Ql ?
|
.Ql ?
|
||||||
can be used as
|
can be used as
|
||||||
wildcards in the patterns.
|
wildcards in the patterns.
|
||||||
Only user names are valid, a numerical user ID isn't recognized.
|
Only user names are valid; a numerical user ID isn't recognized.
|
||||||
By default login is allowed regardless of the user name.
|
By default login is allowed regardless of the user name.
|
||||||
.Pp
|
.Pp
|
||||||
.It Cm Ciphers
|
.It Cm Ciphers
|
||||||
@ -294,7 +311,7 @@ and
|
|||||||
.Ql ?
|
.Ql ?
|
||||||
can be used as
|
can be used as
|
||||||
wildcards in the patterns.
|
wildcards in the patterns.
|
||||||
Only group names are valid, a numerical group ID isn't recognized.
|
Only group names are valid; a numerical group ID isn't recognized.
|
||||||
By default login is allowed regardless of the primary group.
|
By default login is allowed regardless of the primary group.
|
||||||
.Pp
|
.Pp
|
||||||
.It Cm DenyUsers
|
.It Cm DenyUsers
|
||||||
@ -305,7 +322,7 @@ Login is disallowed for user names that match one of the patterns.
|
|||||||
and
|
and
|
||||||
.Ql ?
|
.Ql ?
|
||||||
can be used as wildcards in the patterns.
|
can be used as wildcards in the patterns.
|
||||||
Only user names are valid, a numerical user ID isn't recognized.
|
Only user names are valid; a numerical user ID isn't recognized.
|
||||||
By default login is allowed regardless of the user name.
|
By default login is allowed regardless of the user name.
|
||||||
.It Cm DSAAuthentication
|
.It Cm DSAAuthentication
|
||||||
Specifies whether DSA authentication is allowed.
|
Specifies whether DSA authentication is allowed.
|
||||||
@ -321,7 +338,7 @@ or
|
|||||||
.Dq no .
|
.Dq no .
|
||||||
The default is
|
The default is
|
||||||
.Dq no .
|
.Dq no .
|
||||||
.It Cm HostDsaKey
|
.It Cm HostDSAKey
|
||||||
Specifies the file containing the private DSA host key (default
|
Specifies the file containing the private DSA host key (default
|
||||||
.Pa /etc/ssh_host_dsa_key )
|
.Pa /etc/ssh_host_dsa_key )
|
||||||
used by SSH protocol 2.0.
|
used by SSH protocol 2.0.
|
||||||
@ -383,7 +400,8 @@ Specifies whether Kerberos authentication is allowed.
|
|||||||
This can be in the form of a Kerberos ticket, or if
|
This can be in the form of a Kerberos ticket, or if
|
||||||
.Cm PasswordAuthentication
|
.Cm PasswordAuthentication
|
||||||
is yes, the password provided by the user will be validated through
|
is yes, the password provided by the user will be validated through
|
||||||
the Kerberos KDC.
|
the Kerberos KDC. To use this option, the server needs a
|
||||||
|
Kerberos servtab which allows the verification of the KDC's identity.
|
||||||
Default is
|
Default is
|
||||||
.Dq yes .
|
.Dq yes .
|
||||||
.It Cm KerberosOrLocalPasswd
|
.It Cm KerberosOrLocalPasswd
|
||||||
@ -443,11 +461,28 @@ Additional connections will be dropped until authentication succeeds or the
|
|||||||
.Cm LoginGraceTime
|
.Cm LoginGraceTime
|
||||||
expires for a connection.
|
expires for a connection.
|
||||||
The default is 10.
|
The default is 10.
|
||||||
|
.Pp
|
||||||
|
Alternatively, random early drop can be enabled by specifying
|
||||||
|
the three colon separated values
|
||||||
|
.Dq start:rate:full
|
||||||
|
(e.g. "10:30:60").
|
||||||
|
.Nm
|
||||||
|
will refuse connection attempts with a probabillity of
|
||||||
|
.Dq rate/100
|
||||||
|
(30%)
|
||||||
|
if there are currently
|
||||||
|
.Dq start
|
||||||
|
(10)
|
||||||
|
unauthenticated connections.
|
||||||
|
The probabillity increases linearly and all connection attempts
|
||||||
|
are refused if the number of unauthenticated connections reaches
|
||||||
|
.Dq full
|
||||||
|
(60).
|
||||||
.It Cm PasswordAuthentication
|
.It Cm PasswordAuthentication
|
||||||
Specifies whether password authentication is allowed.
|
Specifies whether password authentication is allowed.
|
||||||
The default is
|
The default is
|
||||||
.Dq yes .
|
.Dq yes .
|
||||||
Note that this option applies to both protocol version 1 and 2.
|
Note that this option applies to both protocol versions 1 and 2.
|
||||||
.It Cm PermitEmptyPasswords
|
.It Cm PermitEmptyPasswords
|
||||||
When password authentication is allowed, it specifies whether the
|
When password authentication is allowed, it specifies whether the
|
||||||
server allows login to accounts with empty password strings.
|
server allows login to accounts with empty password strings.
|
||||||
@ -568,7 +603,7 @@ Specifies whether
|
|||||||
is used for interactive login sessions.
|
is used for interactive login sessions.
|
||||||
Note that
|
Note that
|
||||||
.Xr login 1
|
.Xr login 1
|
||||||
is not never for remote command execution.
|
is never used for remote command execution.
|
||||||
The default is
|
The default is
|
||||||
.Dq no .
|
.Dq no .
|
||||||
.It Cm X11DisplayOffset
|
.It Cm X11DisplayOffset
|
||||||
@ -666,7 +701,7 @@ You don't want to type them in; instead, copy the
|
|||||||
.Pa identity.pub
|
.Pa identity.pub
|
||||||
file and edit it.
|
file and edit it.
|
||||||
.Pp
|
.Pp
|
||||||
The options (if present) consists of comma-separated option
|
The options (if present) consist of comma-separated option
|
||||||
specifications.
|
specifications.
|
||||||
No spaces are permitted, except within double quotes.
|
No spaces are permitted, except within double quotes.
|
||||||
The following option specifications are supported:
|
The following option specifications are supported:
|
||||||
@ -740,7 +775,7 @@ and
|
|||||||
files contain host public keys for all known hosts.
|
files contain host public keys for all known hosts.
|
||||||
The global file should
|
The global file should
|
||||||
be prepared by the administrator (optional), and the per-user file is
|
be prepared by the administrator (optional), and the per-user file is
|
||||||
maintained automatically: whenever the user connects an unknown host
|
maintained automatically: whenever the user connects from an unknown host
|
||||||
its key is added to the per-user file.
|
its key is added to the per-user file.
|
||||||
.Pp
|
.Pp
|
||||||
Each line in these files contains the following fields: hostnames,
|
Each line in these files contains the following fields: hostnames,
|
||||||
@ -815,7 +850,7 @@ Contains the process ID of the
|
|||||||
listening for connections (if there are several daemons running
|
listening for connections (if there are several daemons running
|
||||||
concurrently for different ports, this contains the pid of the one
|
concurrently for different ports, this contains the pid of the one
|
||||||
started last).
|
started last).
|
||||||
The contents of this file are not sensitive; it can be world-readable.
|
The content of this file is not sensitive; it can be world-readable.
|
||||||
.It Pa $HOME/.ssh/authorized_keys
|
.It Pa $HOME/.ssh/authorized_keys
|
||||||
Lists the RSA keys that can be used to log into the user's account.
|
Lists the RSA keys that can be used to log into the user's account.
|
||||||
This file must be readable by root (which may on some machines imply
|
This file must be readable by root (which may on some machines imply
|
||||||
@ -843,7 +878,7 @@ These files are consulted when using rhosts with RSA host
|
|||||||
authentication to check the public key of the host.
|
authentication to check the public key of the host.
|
||||||
The key must be listed in one of these files to be accepted.
|
The key must be listed in one of these files to be accepted.
|
||||||
The client uses the same files
|
The client uses the same files
|
||||||
to verify that the remote host is the one we intended to connect.
|
to verify that the remote host is the one it intended to connect.
|
||||||
These files should be writable only by root/the owner.
|
These files should be writable only by root/the owner.
|
||||||
.Pa /etc/ssh_known_hosts
|
.Pa /etc/ssh_known_hosts
|
||||||
should be world-readable, and
|
should be world-readable, and
|
||||||
@ -882,7 +917,7 @@ this file is exactly the same as for
|
|||||||
.Pa .rhosts .
|
.Pa .rhosts .
|
||||||
However, this file is
|
However, this file is
|
||||||
not used by rlogin and rshd, so using this permits access using SSH only.
|
not used by rlogin and rshd, so using this permits access using SSH only.
|
||||||
.Pa /etc/hosts.equiv
|
.It Pa /etc/hosts.equiv
|
||||||
This file is used during
|
This file is used during
|
||||||
.Pa .rhosts
|
.Pa .rhosts
|
||||||
authentication.
|
authentication.
|
||||||
|
43
sshd.c
43
sshd.c
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshd.c,v 1.123 2000/07/18 01:25:01 djm Exp $");
|
RCSID("$OpenBSD: sshd.c,v 1.125 2000/08/17 20:06:34 markus Exp $");
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
@ -139,6 +139,9 @@ unsigned char session_id[16];
|
|||||||
unsigned char *session_id2 = NULL;
|
unsigned char *session_id2 = NULL;
|
||||||
int session_id2_len = 0;
|
int session_id2_len = 0;
|
||||||
|
|
||||||
|
/* record remote hostname or ip */
|
||||||
|
unsigned int utmp_len = MAXHOSTNAMELEN;
|
||||||
|
|
||||||
/* Prototypes for various functions defined later in this file. */
|
/* Prototypes for various functions defined later in this file. */
|
||||||
void do_ssh1_kex();
|
void do_ssh1_kex();
|
||||||
void do_ssh2_kex();
|
void do_ssh2_kex();
|
||||||
@ -400,6 +403,35 @@ destroy_sensitive_data(void)
|
|||||||
key_free(sensitive_data.dsa_host_key);
|
key_free(sensitive_data.dsa_host_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
drop_connection(int startups)
|
||||||
|
{
|
||||||
|
double p, r;
|
||||||
|
|
||||||
|
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;
|
||||||
|
p /= (double) (options.max_startups - options.max_startups_begin);
|
||||||
|
p += options.max_startups_rate;
|
||||||
|
p /= 100.0;
|
||||||
|
r = arc4random() / (double) UINT_MAX;
|
||||||
|
|
||||||
|
debug("drop_connection: p %g, r %g", p, r);
|
||||||
|
return (r < p) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */
|
int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */
|
||||||
int startup_pipe; /* in child */
|
int startup_pipe; /* in child */
|
||||||
|
|
||||||
@ -441,7 +473,7 @@ main(int ac, char **av)
|
|||||||
initialize_server_options(&options);
|
initialize_server_options(&options);
|
||||||
|
|
||||||
/* Parse command-line arguments. */
|
/* Parse command-line arguments. */
|
||||||
while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) {
|
while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:diqQ46")) != EOF) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case '4':
|
case '4':
|
||||||
IPv4or6 = AF_INET;
|
IPv4or6 = AF_INET;
|
||||||
@ -488,6 +520,9 @@ main(int ac, char **av)
|
|||||||
/* only makes sense with inetd_flag, i.e. no listen() */
|
/* only makes sense with inetd_flag, i.e. no listen() */
|
||||||
inetd_flag = 1;
|
inetd_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
utmp_len = atoi(optarg);
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "sshd version %s\n", SSH_VERSION);
|
fprintf(stderr, "sshd version %s\n", SSH_VERSION);
|
||||||
@ -503,6 +538,7 @@ main(int ac, char **av)
|
|||||||
fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n");
|
fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n");
|
||||||
fprintf(stderr, " -h file File from which to read host key (default: %s)\n",
|
fprintf(stderr, " -h file File from which to read host key (default: %s)\n",
|
||||||
HOST_KEY_FILE);
|
HOST_KEY_FILE);
|
||||||
|
fprintf(stderr, " -u len Maximum hostname length for utmp recording\n");
|
||||||
fprintf(stderr, " -4 Use IPv4 only\n");
|
fprintf(stderr, " -4 Use IPv4 only\n");
|
||||||
fprintf(stderr, " -6 Use IPv6 only\n");
|
fprintf(stderr, " -6 Use IPv6 only\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -823,7 +859,8 @@ main(int ac, char **av)
|
|||||||
error("newsock del O_NONBLOCK: %s", strerror(errno));
|
error("newsock del O_NONBLOCK: %s", strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (startups >= options.max_startups) {
|
if (drop_connection(startups) == 1) {
|
||||||
|
debug("drop connection #%d", startups);
|
||||||
close(newsock);
|
close(newsock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -51,3 +51,4 @@ CheckMail no
|
|||||||
UseLogin no
|
UseLogin no
|
||||||
|
|
||||||
#Subsystem sftp /usr/local/sbin/sftpd
|
#Subsystem sftp /usr/local/sbin/sftpd
|
||||||
|
#MaxStartups 10:30:60
|
||||||
|
Loading…
x
Reference in New Issue
Block a user