зеркало из https://github.com/Azure/sonic-openssh.git
- (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:
Родитель
11fa2cc383
Коммит
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
|
||||
- (djm) Replacement for inet_ntoa for Irix (which breaks on gcc)
|
||||
- (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)
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
4
auth.c
4
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;
|
||||
|
|
331
authfd.c
331
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));
|
||||
buffer_init(&request);
|
||||
buffer_put_char(&request, SSH_AGENTC_REQUEST_RSA_IDENTITIES);
|
||||
|
||||
buffer_clear(&auth->identities);
|
||||
if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
|
||||
buffer_free(&request);
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
type = buffer_get_char(&buffer);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
buffer_free(&buffer);
|
||||
return decode_reply(type);
|
||||
}
|
||||
|
||||
int
|
||||
decode_reply(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case SSH_AGENT_FAILURE:
|
||||
log("SSH_AGENT_FAILURE");
|
||||
log("SSH_AGENT_FAILURE");
|
||||
return 0;
|
||||
case SSH_AGENT_SUCCESS:
|
||||
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 "bsd-misc.h"
|
||||
#include "bsd-arc4random.h"
|
||||
|
||||
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_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"
|
||||
|
|
24
servconf.c
24
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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
194
session.c
194
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);
|
||||
/* record login, etc. similar to login(1) */
|
||||
if (command == NULL && !options.use_login)
|
||||
do_login(s);
|
||||
|
||||
/* 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_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();
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
* already exists, its value is overriden.
|
||||
|
@ -1265,8 +1252,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
|||
} else {
|
||||
/* Launch login(1). */
|
||||
|
||||
execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(),
|
||||
"-p", "-f", "--", pw->pw_name, NULL);
|
||||
execl(LOGIN_PROGRAM, "login",
|
||||
"-h", get_remote_name_or_ip(),
|
||||
"-p", "-f", "--", pw->pw_name, NULL);
|
||||
|
||||
/* 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
|
||||
.\"
|
||||
.\" $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
|
||||
.Dt SSH 1
|
||||
|
@ -994,7 +994,7 @@ If the current session has no tty,
|
|||
this variable is not set.
|
||||
.It Ev TZ
|
||||
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).
|
||||
.It Ev USER
|
||||
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
|
||||
.\"
|
||||
.\" $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
|
||||
.Dt SSHD 8
|
||||
|
@ -26,6 +26,7 @@
|
|||
.Op Fl h Ar host_key_file
|
||||
.Op Fl k Ar key_gen_time
|
||||
.Op Fl p Ar port
|
||||
.Op Fl u Ar len
|
||||
.Op Fl V Ar client_protocol_id
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
|
@ -104,7 +105,7 @@ into the machine).
|
|||
.Pp
|
||||
.Ss SSH protocol version 2
|
||||
.Pp
|
||||
Version 2 works similar:
|
||||
Version 2 works similarly:
|
||||
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.
|
||||
Forward security is provided through a Diffie-Hellman key agreement.
|
||||
|
@ -211,6 +212,22 @@ Quiet mode.
|
|||
Nothing is sent to the system log.
|
||||
Normally the beginning,
|
||||
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
|
||||
Do not print an error message if RSA support is missing.
|
||||
.It Fl V Ar client_protocol_id
|
||||
|
@ -257,7 +274,7 @@ and
|
|||
.Ql ?
|
||||
can be used as
|
||||
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.
|
||||
.Pp
|
||||
.It Cm AllowUsers
|
||||
|
@ -270,7 +287,7 @@ and
|
|||
.Ql ?
|
||||
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.
|
||||
.Pp
|
||||
.It Cm Ciphers
|
||||
|
@ -294,7 +311,7 @@ and
|
|||
.Ql ?
|
||||
can be used as
|
||||
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.
|
||||
.Pp
|
||||
.It Cm DenyUsers
|
||||
|
@ -305,7 +322,7 @@ Login is disallowed for user names that match one of the patterns.
|
|||
and
|
||||
.Ql ?
|
||||
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.
|
||||
.It Cm DSAAuthentication
|
||||
Specifies whether DSA authentication is allowed.
|
||||
|
@ -321,7 +338,7 @@ or
|
|||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm HostDsaKey
|
||||
.It Cm HostDSAKey
|
||||
Specifies the file containing the private DSA host key (default
|
||||
.Pa /etc/ssh_host_dsa_key )
|
||||
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
|
||||
.Cm PasswordAuthentication
|
||||
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
|
||||
.Dq yes .
|
||||
.It Cm KerberosOrLocalPasswd
|
||||
|
@ -443,11 +461,28 @@ Additional connections will be dropped until authentication succeeds or the
|
|||
.Cm LoginGraceTime
|
||||
expires for a connection.
|
||||
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
|
||||
Specifies whether password authentication is allowed.
|
||||
The default is
|
||||
.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
|
||||
When password authentication is allowed, it specifies whether the
|
||||
server allows login to accounts with empty password strings.
|
||||
|
@ -568,7 +603,7 @@ Specifies whether
|
|||
is used for interactive login sessions.
|
||||
Note that
|
||||
.Xr login 1
|
||||
is not never for remote command execution.
|
||||
is never used for remote command execution.
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm X11DisplayOffset
|
||||
|
@ -666,7 +701,7 @@ You don't want to type them in; instead, copy the
|
|||
.Pa identity.pub
|
||||
file and edit it.
|
||||
.Pp
|
||||
The options (if present) consists of comma-separated option
|
||||
The options (if present) consist of comma-separated option
|
||||
specifications.
|
||||
No spaces are permitted, except within double quotes.
|
||||
The following option specifications are supported:
|
||||
|
@ -740,7 +775,7 @@ and
|
|||
files contain host public keys for all known hosts.
|
||||
The global file should
|
||||
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.
|
||||
.Pp
|
||||
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
|
||||
concurrently for different ports, this contains the pid of the one
|
||||
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
|
||||
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
|
||||
|
@ -843,7 +878,7 @@ These files are consulted when using rhosts with RSA host
|
|||
authentication to check the public key of the host.
|
||||
The key must be listed in one of these files to be accepted.
|
||||
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.
|
||||
.Pa /etc/ssh_known_hosts
|
||||
should be world-readable, and
|
||||
|
@ -882,7 +917,7 @@ this file is exactly the same as for
|
|||
.Pa .rhosts .
|
||||
However, this file is
|
||||
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
|
||||
.Pa .rhosts
|
||||
authentication.
|
||||
|
|
43
sshd.c
43
sshd.c
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
#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 "rsa.h"
|
||||
|
@ -139,6 +139,9 @@ unsigned char session_id[16];
|
|||
unsigned char *session_id2 = NULL;
|
||||
int session_id2_len = 0;
|
||||
|
||||
/* record remote hostname or ip */
|
||||
unsigned int utmp_len = MAXHOSTNAMELEN;
|
||||
|
||||
/* Prototypes for various functions defined later in this file. */
|
||||
void do_ssh1_kex();
|
||||
void do_ssh2_kex();
|
||||
|
@ -400,6 +403,35 @@ destroy_sensitive_data(void)
|
|||
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_pipe; /* in child */
|
||||
|
||||
|
@ -441,7 +473,7 @@ main(int ac, char **av)
|
|||
initialize_server_options(&options);
|
||||
|
||||
/* 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) {
|
||||
case '4':
|
||||
IPv4or6 = AF_INET;
|
||||
|
@ -488,6 +520,9 @@ main(int ac, char **av)
|
|||
/* only makes sense with inetd_flag, i.e. no listen() */
|
||||
inetd_flag = 1;
|
||||
break;
|
||||
case 'u':
|
||||
utmp_len = atoi(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
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, " -h file File from which to read host key (default: %s)\n",
|
||||
HOST_KEY_FILE);
|
||||
fprintf(stderr, " -u len Maximum hostname length for utmp recording\n");
|
||||
fprintf(stderr, " -4 Use IPv4 only\n");
|
||||
fprintf(stderr, " -6 Use IPv6 only\n");
|
||||
exit(1);
|
||||
|
@ -823,7 +859,8 @@ main(int ac, char **av)
|
|||
error("newsock del O_NONBLOCK: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if (startups >= options.max_startups) {
|
||||
if (drop_connection(startups) == 1) {
|
||||
debug("drop connection #%d", startups);
|
||||
close(newsock);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -51,3 +51,4 @@ CheckMail no
|
|||
UseLogin no
|
||||
|
||||
#Subsystem sftp /usr/local/sbin/sftpd
|
||||
#MaxStartups 10:30:60
|
||||
|
|
Загрузка…
Ссылка в новой задаче