OpenSSH 3.6.1 as of 2003/4/3

* The 'kex guesses' bugfix from OpenSSH 3.6 triggers a bug
  in a few other SSH v2 implementations and causes connections to
  stall.  OpenSSH 3.6.1 disables this bugfix when interoperating
  with these implementations.
* RSA blinding is now used by ssh(1), sshd(8) and ssh-agent(1).
  in order to avoid potential timing attacks against the RSA keys.
  Older versions of OpenSSH have been using RSA blinding in
  ssh-keysign(1) only.
* ssh-agent(1) optionally requires user confirmation if a key gets
  used, see '-c' in ssh-add(1).
* sshd(8) now handles PermitRootLogin correctly when UsePrivilegeSeparation
  is enabled.
* sshd(8) now removes X11 cookies when a session gets closed.
* ssh-keysign(8) is disabled by default and only enabled if the
  new EnableSSHKeysign option is set in the global ssh_config(5)
  file.
* ssh(1) and sshd(8) now handle 'kex guesses' correctly (key exchange
  guesses).
* ssh(1) no longer overwrites SIG_IGN.  This matches behaviour from
  rsh(1) and is used by backup tools.
* setting ProxyCommand to 'none' disables the proxy feature, see
  ssh_config(5).
* scp(1) supports add -1 and -2.
* scp(1) supports bandwidth limiting.
* sftp(1) displays a progressmeter.
* sftp(1) has improved error handling for scripting.
This commit is contained in:
itojun 2003-04-03 05:57:11 +00:00
parent d0a69bd4ab
commit 14012871d8
79 changed files with 2371 additions and 1500 deletions

View File

@ -76,14 +76,6 @@ OpenSSH contains no GPL code.
POSSIBILITY OF SUCH DAMAGES.
2)
The 32-bit CRC implementation in crc32.c is due to Gary S. Brown.
Comments in the file indicate it may be used for any purpose without
restrictions:
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
3)
The 32-bit CRC compensation attack detector in deattack.c was
contributed by CORE SDI S.A. under a BSD-style license.
@ -104,7 +96,7 @@ OpenSSH contains no GPL code.
* Ariel Futoransky <futo@core-sdi.com>
* <http://www.core-sdi.com>
4)
3)
ssh-keygen was contributed by David Mazieres under a BSD-style
license.
@ -114,7 +106,7 @@ OpenSSH contains no GPL code.
* permitted provided that due credit is given to the author and the
* OpenBSD project by leaving this copyright notice intact.
5)
4)
The Rijndael implementation by Vincent Rijmen, Antoon Bosselaers
and Paulo Barreto is in the public domain and distributed
with the following license:
@ -141,7 +133,7 @@ OpenSSH contains no GPL code.
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6)
5)
One component of the ssh source code is under a 4-clause BSD license,
held by the University of California, since we pulled these parts from
original Berkeley code. The Regents of the University of California
@ -179,7 +171,7 @@ OpenSSH contains no GPL code.
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
7)
6)
Remaining components of the software are provided under a standard
2-term BSD licence with the following names as copyright holders:

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-krb4.c,v 1.1.1.9 2002/10/01 13:39:55 itojun Exp $ */
/* $NetBSD: auth-krb4.c,v 1.1.1.10 2003/04/03 05:57:14 itojun Exp $ */
/*
* Copyright (c) 1999 Dug Song. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-krb4.c,v 1.28 2002/09/26 11:38:43 markus Exp $");
RCSID("$OpenBSD: auth-krb4.c,v 1.29 2003/02/21 10:34:48 mpech Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -272,7 +272,7 @@ auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply)
reply->length = r;
/* Clear session key. */
memset(&adat.session, 0, sizeof(&adat.session));
memset(&adat.session, 0, sizeof(adat.session));
return (1);
}
#endif /* KRB4 */

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-krb5.c,v 1.1.1.5 2002/10/01 13:40:02 itojun Exp $ */
/* $NetBSD: auth-krb5.c,v 1.1.1.6 2003/04/03 05:57:14 itojun Exp $ */
/*
* Kerberos v5 authentication and ticket-passing routines.
*
@ -29,7 +29,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-krb5.c,v 1.9 2002/09/09 06:48:06 itojun Exp $");
RCSID("$OpenBSD: auth-krb5.c,v 1.10 2002/11/21 23:03:51 deraadt Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -98,7 +98,7 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply)
if (problem)
goto err;
problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL ,
problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
KRB5_NT_SRV_HST, &server);
if (problem)
goto err;

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth.c,v 1.1.1.14 2002/10/01 13:39:56 itojun Exp $ */
/* $NetBSD: auth.c,v 1.1.1.15 2003/04/03 05:57:15 itojun Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth.c,v 1.45 2002/09/20 18:41:29 stevesk Exp $");
RCSID("$OpenBSD: auth.c,v 1.46 2002/11/04 10:07:53 markus Exp $");
#include <libgen.h>
@ -341,6 +341,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
uid_t uid = pw->pw_uid;
char buf[MAXPATHLEN], homedir[MAXPATHLEN];
char *cp;
int comparehome = 0;
struct stat st;
if (realpath(file, buf) == NULL) {
@ -348,11 +349,8 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
strerror(errno));
return -1;
}
if (realpath(pw->pw_dir, homedir) == NULL) {
snprintf(err, errlen, "realpath %s failed: %s", pw->pw_dir,
strerror(errno));
return -1;
}
if (realpath(pw->pw_dir, homedir) != NULL)
comparehome = 1;
/* check the open file to avoid races */
if (fstat(fileno(f), &st) < 0 ||
@ -381,7 +379,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
}
/* If are passed the homedir then we can stop */
if (strcmp(homedir, buf) == 0) {
if (comparehome && strcmp(homedir, buf) == 0) {
debug3("secure_filename: terminating check at '%s'",
buf);
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth1.c,v 1.1.1.14 2002/10/01 13:39:56 itojun Exp $ */
/* $NetBSD: auth1.c,v 1.1.1.15 2003/04/03 05:57:15 itojun Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -11,7 +11,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth1.c,v 1.44 2002/09/26 11:38:43 markus Exp $");
RCSID("$OpenBSD: auth1.c,v 1.47 2003/02/06 21:22:42 markus Exp $");
#include "xmalloc.h"
#include "rsa.h"
@ -151,7 +151,7 @@ do_authloop(Authctxt *authctxt)
snprintf(info, sizeof(info),
" tktuser %.100s",
client_user);
/* Send response to client */
packet_start(
SSH_SMSG_AUTH_KERBEROS_RESPONSE);
@ -289,7 +289,6 @@ do_authloop(Authctxt *authctxt)
debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
if (options.challenge_response_authentication == 1) {
char *response = packet_get_string(&dlen);
debug("got response '%s'", response);
packet_check_eom();
authenticated = verify_response(authctxt, response);
memset(response, 'r', dlen);
@ -316,8 +315,7 @@ do_authloop(Authctxt *authctxt)
authctxt->user);
/* Special handling for root */
if (!use_privsep &&
authenticated && authctxt->pw->pw_uid == 0 &&
if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(get_authname(type)))
authenticated = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth2.c,v 1.1.1.18 2002/10/01 13:39:56 itojun Exp $ */
/* $NetBSD: auth2.c,v 1.1.1.19 2003/04/03 05:57:16 itojun Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth2.c,v 1.95 2002/08/22 21:33:58 markus Exp $");
RCSID("$OpenBSD: auth2.c,v 1.96 2003/02/06 21:22:43 markus Exp $");
#include "ssh2.h"
#include "xmalloc.h"
@ -196,8 +196,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
authctxt->user);
/* Special handling for root */
if (!use_privsep &&
authenticated && authctxt->pw->pw_uid == 0 &&
if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(method))
authenticated = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: authfd.c,v 1.1.1.13 2002/10/01 13:39:56 itojun Exp $ */
/* $NetBSD: authfd.c,v 1.1.1.14 2003/04/03 05:57:16 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfd.c,v 1.57 2002/09/11 18:27:26 stevesk Exp $");
RCSID("$OpenBSD: authfd.c,v 1.58 2003/01/23 13:50:27 markus Exp $");
#include <openssl/evp.h>
@ -500,10 +500,10 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
int
ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
const char *comment, u_int life)
const char *comment, u_int life, u_int confirm)
{
Buffer msg;
int type, constrained = (life != 0);
int type, constrained = (life || confirm);
buffer_init(&msg);
@ -533,6 +533,8 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
buffer_put_int(&msg, life);
}
if (confirm != 0)
buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
}
if (ssh_request_reply(auth, &msg, &msg) == 0) {
buffer_free(&msg);
@ -546,7 +548,7 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
int
ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
{
return ssh_add_identity_constrained(auth, key, comment, 0);
return ssh_add_identity_constrained(auth, key, comment, 0, 0);
}
/*

View File

@ -1,5 +1,5 @@
/* $NetBSD: authfd.h,v 1.1.1.9 2002/10/01 13:39:56 itojun Exp $ */
/* $OpenBSD: authfd.h,v 1.31 2002/09/11 18:27:25 stevesk Exp $ */
/* $NetBSD: authfd.h,v 1.1.1.10 2003/04/03 05:57:16 itojun Exp $ */
/* $OpenBSD: authfd.h,v 1.32 2003/01/23 13:50:27 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -52,6 +52,7 @@
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
/* extended failure messages */
#define SSH2_AGENT_FAILURE 30
@ -77,7 +78,8 @@ int ssh_get_num_identities(AuthenticationConnection *, int);
Key *ssh_get_first_identity(AuthenticationConnection *, char **, int);
Key *ssh_get_next_identity(AuthenticationConnection *, char **, int);
int ssh_add_identity(AuthenticationConnection *, Key *, const char *);
int ssh_add_identity_constrained(AuthenticationConnection *, Key *, const char *, u_int);
int ssh_add_identity_constrained(AuthenticationConnection *, Key *,
const char *, u_int, u_int);
int ssh_remove_identity(AuthenticationConnection *, Key *);
int ssh_remove_all_identities(AuthenticationConnection *, int);
int ssh_lock_agent(AuthenticationConnection *, int, const char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: authfile.c,v 1.1.1.14 2002/06/26 14:02:54 itojun Exp $ */
/* $NetBSD: authfile.c,v 1.1.1.15 2003/04/03 05:57:17 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -37,7 +37,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfile.c,v 1.50 2002/06/24 14:55:38 markus Exp $");
RCSID("$OpenBSD: authfile.c,v 1.52 2003/03/13 11:42:18 markus Exp $");
#include <openssl/err.h>
#include <openssl/evp.h>
@ -233,12 +233,17 @@ key_load_public_rsa1(int fd, const char *filename, char **commentp)
{
Buffer buffer;
Key *pub;
struct stat st;
char *cp;
int i;
off_t len;
len = lseek(fd, (off_t) 0, SEEK_END);
lseek(fd, (off_t) 0, SEEK_SET);
if (fstat(fd, &st) < 0) {
error("fstat for key file %.200s failed: %.100s",
filename, strerror(errno));
return NULL;
}
len = st.st_size;
buffer_init(&buffer);
cp = buffer_append_space(&buffer, len);
@ -319,9 +324,15 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
CipherContext ciphercontext;
Cipher *cipher;
Key *prv = NULL;
struct stat st;
len = lseek(fd, (off_t) 0, SEEK_END);
lseek(fd, (off_t) 0, SEEK_SET);
if (fstat(fd, &st) < 0) {
error("fstat for key file %.200s failed: %.100s",
filename, strerror(errno));
close(fd);
return NULL;
}
len = st.st_size;
buffer_init(&buffer);
cp = buffer_append_space(&buffer, len);
@ -411,6 +422,12 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
rsa_generate_additional_parameters(prv->rsa);
buffer_free(&decrypted);
/* enable blinding */
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
error("key_load_private_rsa1: RSA_blinding_on failed");
goto fail;
}
close(fd);
return prv;
@ -450,6 +467,11 @@ key_load_private_pem(int fd, int type, const char *passphrase,
#ifdef DEBUG_PK
RSA_print_fp(stderr, prv->rsa, 8);
#endif
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
error("key_load_private_pem: RSA_blinding_on failed");
key_free(prv);
prv = NULL;
}
} else if (pk->type == EVP_PKEY_DSA &&
(type == KEY_UNSPEC||type==KEY_DSA)) {
prv = key_new(KEY_UNSPEC);

View File

@ -1,4 +1,4 @@
/* $NetBSD: bufaux.c,v 1.1.1.9 2002/06/26 14:02:54 itojun Exp $ */
/* $NetBSD: bufaux.c,v 1.1.1.10 2003/04/03 05:57:17 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -38,7 +38,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: bufaux.c,v 1.27 2002/06/26 08:53:12 markus Exp $");
RCSID("$OpenBSD: bufaux.c,v 1.28 2002/10/23 10:40:16 markus Exp $");
#include <openssl/bn.h>
#include "bufaux.h"
@ -222,7 +222,7 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
/* Get the length. */
len = buffer_get_int(buffer);
if (len > 256 * 1024)
fatal("buffer_get_string: bad string length %d", len);
fatal("buffer_get_string: bad string length %u", len);
/* Allocate space for the string. Add one byte for a null character. */
value = xmalloc(len + 1);
/* Get the string. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: canohost.c,v 1.1.1.11 2002/10/01 13:39:56 itojun Exp $ */
/* $NetBSD: canohost.c,v 1.1.1.12 2003/04/03 05:57:17 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: canohost.c,v 1.34 2002/09/23 20:46:27 stevesk Exp $");
RCSID("$OpenBSD: canohost.c,v 1.35 2002/11/26 02:38:54 stevesk Exp $");
#include "packet.h"
#include "xmalloc.h"
@ -39,7 +39,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
/* Get IP address of client. */
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(socket, (struct sockaddr *) &from, &fromlen) < 0) {
if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername failed: %.100s", strerror(errno));
fatal_cleanup();
}
@ -181,8 +181,8 @@ get_canonical_hostname(int verify_reverse_mapping)
}
/*
* Returns the remote IP-address of socket as a string. The returned
* string must be freed.
* Returns the local/remote IP-address/hostname of socket as a string.
* The returned string must be freed.
*/
static char *
get_socket_address(int socket, int remote, int flags)
@ -207,7 +207,7 @@ get_socket_address(int socket, int remote, int flags)
/* Get the address in ascii. */
if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop),
NULL, 0, flags) != 0) {
error("get_socket_ipaddr: getnameinfo %d failed", flags);
error("get_socket_address: getnameinfo %d failed", flags);
return NULL;
}
return xstrdup(ntop);
@ -293,7 +293,7 @@ get_sock_port(int sock, int local)
return 0;
}
} else {
if (getpeername(sock, (struct sockaddr *) & from, &fromlen) < 0) {
if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername failed: %.100s", strerror(errno));
fatal_cleanup();
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: channels.c,v 1.1.1.18 2002/10/01 13:39:57 itojun Exp $ */
/* $NetBSD: channels.c,v 1.1.1.19 2003/04/03 05:57:19 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -40,7 +40,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: channels.c,v 1.183 2002/09/17 07:47:02 itojun Exp $");
RCSID("$OpenBSD: channels.c,v 1.187 2003/03/05 22:33:43 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -413,13 +413,13 @@ channel_not_very_much_buffered_data(void)
#if 0
if (!compat20 &&
buffer_len(&c->input) > packet_get_maxsize()) {
debug("channel %d: big input buffer %d",
debug2("channel %d: big input buffer %d",
c->self, buffer_len(&c->input));
return 0;
}
#endif
if (buffer_len(&c->output) > packet_get_maxsize()) {
debug("channel %d: big output buffer %d > %d",
debug2("channel %d: big output buffer %d > %d",
c->self, buffer_len(&c->output),
packet_get_maxsize());
return 0;
@ -578,7 +578,7 @@ channel_send_open(int id)
log("channel_send_open: %d: bad id", id);
return;
}
debug("send channel open %d", id);
debug2("channel %d: send open", id);
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring(c->ctype);
packet_put_int(c->self);
@ -588,15 +588,15 @@ channel_send_open(int id)
}
void
channel_request_start(int local_id, char *service, int wantconfirm)
channel_request_start(int id, char *service, int wantconfirm)
{
Channel *c = channel_lookup(local_id);
Channel *c = channel_lookup(id);
if (c == NULL) {
log("channel_request_start: %d: unknown channel id", local_id);
log("channel_request_start: %d: unknown channel id", id);
return;
}
debug("channel request %d: %s", local_id, service) ;
debug("channel %d: request %s", id, service) ;
packet_start(SSH2_MSG_CHANNEL_REQUEST);
packet_put_int(c->remote_id);
packet_put_cstring(service);
@ -1992,6 +1992,7 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt)
c->remote_id = remote_id;
}
if (c == NULL) {
xfree(originator_string);
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(remote_id);
packet_send();
@ -2270,7 +2271,10 @@ connect_to(const char *host, u_short port)
}
sock = socket(ai->ai_family, SOCK_STREAM, 0);
if (sock < 0) {
error("socket: %.100s", strerror(errno));
if (ai->ai_next == NULL)
error("socket: %.100s", strerror(errno));
else
verbose("socket: %.100s", strerror(errno));
continue;
}
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
@ -2573,6 +2577,7 @@ x11_input_open(int type, u_int32_t seq, void *ctxt)
/* Send refusal to the remote host. */
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(remote_id);
xfree(remote_host);
} else {
/* Send a confirmation to the remote host. */
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);

View File

@ -1,4 +1,4 @@
/* $NetBSD: cipher.c,v 1.1.1.10 2002/10/01 13:39:57 itojun Exp $ */
/* $NetBSD: cipher.c,v 1.1.1.11 2003/04/03 05:57:19 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: cipher.c,v 1.61 2002/07/12 15:50:17 markus Exp $");
RCSID("$OpenBSD: cipher.c,v 1.62 2002/11/21 22:45:31 markus Exp $");
#include "xmalloc.h"
#include "log.h"
@ -222,7 +222,7 @@ cipher_init(CipherContext *cc, Cipher *cipher,
cipher->name);
klen = EVP_CIPHER_CTX_key_length(&cc->evp);
if (klen > 0 && keylen != klen) {
debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
fatal("cipher_init: set keylen failed (%d -> %d)",
klen, keylen);

View File

@ -1,4 +1,4 @@
/* $NetBSD: clientloop.c,v 1.1.1.18 2002/10/01 13:39:57 itojun Exp $ */
/* $NetBSD: clientloop.c,v 1.1.1.19 2003/04/03 05:57:20 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -60,7 +60,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: clientloop.c,v 1.104 2002/08/22 19:38:42 stevesk Exp $");
RCSID("$OpenBSD: clientloop.c,v 1.108 2003/04/02 09:48:07 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -889,10 +889,16 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
client_init_dispatch();
/* Set signal handlers to restore non-blocking mode. */
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler);
/*
* Set signal handlers, (e.g. to restore non-blocking mode)
* but don't overwrite SIG_IGN, matches behaviour from rsh(1)
*/
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, signal_handler);
if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
signal(SIGQUIT, signal_handler);
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
signal(SIGTERM, signal_handler);
if (have_pty)
signal(SIGWINCH, window_change_handler);
@ -963,9 +969,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Do channel operations unless rekeying in progress. */
if (!rekeying) {
channel_after_select(readset, writeset);
if (need_rekeying) {
debug("user requests rekeying");
if (need_rekeying || packet_need_rekeying()) {
debug("need rekeying");
xxx_kex->done = 0;
kex_send_kexinit(xxx_kex);
need_rekeying = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: compat.c,v 1.1.1.12 2002/10/01 13:39:57 itojun Exp $ */
/* $NetBSD: compat.c,v 1.1.1.13 2003/04/03 05:57:20 itojun Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: compat.c,v 1.65 2002/09/27 10:42:09 mickey Exp $");
RCSID("$OpenBSD: compat.c,v 1.66 2003/04/01 10:31:26 markus Exp $");
#include "buffer.h"
#include "packet.h"
@ -86,10 +86,12 @@ compat_datafellows(const char *version)
{ "*MindTerm*", 0 },
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE|
SSH_BUG_FIRSTKEX },
{ "2.1 *", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE|
SSH_BUG_FIRSTKEX },
{ "2.0.13*,"
"2.0.14*,"
"2.0.15*,"
@ -101,26 +103,28 @@ compat_datafellows(const char *version)
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
SSH_BUG_PKOK|SSH_BUG_RSASIGMD5|
SSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE|
SSH_BUG_DUMMYCHAN },
SSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX },
{ "2.0.11*,"
"2.0.12*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
SSH_BUG_PKAUTH|SSH_BUG_PKOK|
SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|
SSH_BUG_DUMMYCHAN },
SSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX },
{ "2.0.*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
SSH_BUG_PKAUTH|SSH_BUG_PKOK|
SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|
SSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN },
SSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN|
SSH_BUG_FIRSTKEX },
{ "2.2.0*,"
"2.3.0*", SSH_BUG_HMAC|SSH_BUG_DEBUG|
SSH_BUG_RSASIGMD5 },
{ "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5 },
SSH_BUG_RSASIGMD5|SSH_BUG_FIRSTKEX },
{ "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5|
SSH_BUG_FIRSTKEX },
{ "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */
{ "2.*", SSH_BUG_DEBUG },
{ "2.*", SSH_BUG_DEBUG|SSH_BUG_FIRSTKEX },
{ "3.0.*", SSH_BUG_DEBUG },
{ "3.0 SecureCRT*", SSH_OLD_SESSIONID },
{ "1.7 SecureFX*", SSH_OLD_SESSIONID },

View File

@ -1,5 +1,5 @@
/* $NetBSD: compat.h,v 1.1.1.11 2002/10/01 13:39:57 itojun Exp $ */
/* $OpenBSD: compat.h,v 1.33 2002/09/27 10:42:09 mickey Exp $ */
/* $NetBSD: compat.h,v 1.1.1.12 2003/04/03 05:57:20 itojun Exp $ */
/* $OpenBSD: compat.h,v 1.34 2003/04/01 10:31:26 markus Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@ -56,6 +56,7 @@
#define SSH_BUG_EXTEOF 0x00200000
#define SSH_BUG_K5USER 0x00400000
#define SSH_BUG_PROBE 0x00800000
#define SSH_BUG_FIRSTKEX 0x01000000
void enable_compat13(void);
void enable_compat20(void);

View File

@ -1,115 +1,107 @@
/* $NetBSD: crc32.c,v 1.1.1.4 2001/04/10 07:13:54 itojun Exp $ */
/* $NetBSD: crc32.c,v 1.1.1.5 2003/04/03 05:57:20 itojun Exp $ */
/* $OpenBSD: crc32.c,v 1.9 2003/02/12 21:39:50 markus Exp $ */
/*
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
* Copyright (c) 2003 Markus Friedl. All rights reserved.
*
* First, the polynomial itself and its table of feedback terms. The
* polynomial is
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Note that we take it "backwards" and put the highest-order term in
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
* the MSB being 1
*
* Note that the usual hardware shift register implementation, which
* is what we're using (we're merely optimizing it by doing eight-bit
* chunks at a time) shifts bits into the lowest-order term. In our
* implementation, that means shifting towards the right. Why do we
* do it this way? Because the calculated CRC must be transmitted in
* order from highest-order term to lowest-order term. UARTs transmit
* characters in order from LSB to MSB. By storing the CRC this way
* we hand it to the UART in the order low-byte to high-byte; the UART
* sends each low-bit to hight-bit; and the result is transmission bit
* by bit from highest- to lowest-order term without requiring any bit
* shuffling on our part. Reception works similarly
*
* The feedback terms table consists of 256, 32-bit entries. Notes
*
* The table can be generated at runtime if desired; code to do so
* is shown later. It might not be obvious, but the feedback
* terms simply represent the results of eight shift/xor opera
* tions for all combinations of data and CRC register values
*
* The values must be right-shifted by eight bits by the "updcrc
* logic; the shift must be u_(bring in zeroes). On some
* hardware you could probably optimize the shift in assembler by
* using byte-swap instructions
* polynomial $edb88320
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: crc32.c,v 1.8 2000/12/19 23:17:56 markus Exp $");
#include <sys/types.h>
#include "crc32.h"
static u_int crc32_tab[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
static const u_int32_t crc32tab[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
/* Return a 32-bit CRC of the contents of the buffer. */
u_int
ssh_crc32(const u_char *s, u_int len)
u_int32_t
ssh_crc32(const u_char *buf, u_int32_t size)
{
u_int i;
u_int crc32val;
u_int32_t i, crc;
crc32val = 0;
for (i = 0; i < len; i ++) {
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
}
return crc32val;
crc = 0;
for (i = 0; i < size; i++)
crc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
return crc;
}

View File

@ -1,22 +1,31 @@
/* $NetBSD: crc32.h,v 1.1.1.7 2002/03/08 01:20:43 itojun Exp $ */
/* $OpenBSD: crc32.h,v 1.13 2002/03/04 17:27:39 stevesk Exp $ */
/* $NetBSD: crc32.h,v 1.1.1.8 2003/04/03 05:57:20 itojun Exp $ */
/* $OpenBSD: crc32.h,v 1.14 2003/02/12 21:39:50 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1992 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Functions for computing 32-bit CRC.
* Copyright (c) 2003 Markus Friedl. All rights reserved.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CRC32_H
#define CRC32_H
u_int ssh_crc32(const u_char *, u_int);
#endif /* CRC32_H */
#ifndef SSH_CRC32_H
#define SSH_CRC32_H
u_int32_t ssh_crc32(const u_char *, u_int32_t);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: dh.c,v 1.1.1.8 2002/10/01 13:39:57 itojun Exp $ */
/* $NetBSD: dh.c,v 1.1.1.9 2003/04/03 05:57:20 itojun Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: dh.c,v 1.22 2002/06/27 08:49:44 markus Exp $");
RCSID("$OpenBSD: dh.c,v 1.23 2002/11/21 22:22:50 markus Exp $");
#include "xmalloc.h"
@ -183,7 +183,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
for (i = 0; i <= n; i++)
if (BN_is_bit_set(dh_pub, i))
bits_set++;
debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
/* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
@ -215,7 +215,7 @@ dh_gen_key(DH *dh, int need)
for (i = 0; i <= BN_num_bits(dh->priv_key); i++)
if (BN_is_bit_set(dh->priv_key, i))
bits_set++;
debug("dh_gen_key: priv key bits set: %d/%d",
debug2("dh_gen_key: priv key bits set: %d/%d",
bits_set, BN_num_bits(dh->priv_key));
if (tries++ > 10)
fatal("dh_gen_key: too many bad keys: giving up");

View File

@ -1,5 +1,5 @@
/* $NetBSD: hostfile.h,v 1.1.1.8 2002/10/01 13:39:57 itojun Exp $ */
/* $OpenBSD: hostfile.h,v 1.12 2002/09/08 20:24:08 markus Exp $ */
/* $NetBSD: hostfile.h,v 1.1.1.9 2003/04/03 05:57:21 itojun Exp $ */
/* $OpenBSD: hostfile.h,v 1.13 2002/11/21 23:03:51 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -20,10 +20,10 @@ typedef enum {
} HostStatus;
int hostfile_read_key(char **, u_int *, Key *);
HostStatus
check_host_in_hostfile(const char *, const char *, Key *, Key *, int *);
int add_host_to_hostfile(const char *, const char *, Key *);
int
lookup_key_in_hostfile_by_type(const char *, const char *, int , Key *, int *);
HostStatus check_host_in_hostfile(const char *, const char *,
Key *, Key *, int *);
int add_host_to_hostfile(const char *, const char *, Key *);
int lookup_key_in_hostfile_by_type(const char *, const char *,
int, Key *, int *);
#endif

69
crypto/dist/ssh/kex.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: kex.c,v 1.1.1.14 2002/06/26 14:02:59 itojun Exp $ */
/* $NetBSD: kex.c,v 1.1.1.15 2003/04/03 05:57:22 itojun Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $");
RCSID("$OpenBSD: kex.c,v 1.55 2003/04/01 10:31:26 markus Exp $");
#include <openssl/crypto.h>
@ -45,11 +45,6 @@ RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $");
#define KEX_COOKIE_LEN 16
/* Use privilege separation for sshd */
int use_privsep;
struct monitor *pmonitor;
/* prototype */
static void kex_kexinit_finish(Kex *);
static void kex_choose_conf(Kex *);
@ -75,7 +70,7 @@ kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
/* parse buffer and return algorithm proposal */
static char **
kex_buf2prop(Buffer *raw)
kex_buf2prop(Buffer *raw, int *first_kex_follows)
{
Buffer b;
int i;
@ -95,6 +90,8 @@ kex_buf2prop(Buffer *raw)
}
/* first kex follows / reserved */
i = buffer_get_char(&b);
if (first_kex_follows != NULL)
*first_kex_follows = i;
debug2("kex_parse_kexinit: first_kex_follows %d ", i);
i = buffer_get_int(&b);
debug2("kex_parse_kexinit: reserved %d ", i);
@ -136,7 +133,7 @@ kex_finish(Kex *kex)
/* packet_write_wait(); */
debug("SSH2_MSG_NEWKEYS sent");
debug("waiting for SSH2_MSG_NEWKEYS");
debug("expecting SSH2_MSG_NEWKEYS");
packet_read_expect(SSH2_MSG_NEWKEYS);
packet_check_eom();
debug("SSH2_MSG_NEWKEYS received");
@ -236,14 +233,10 @@ kex_kexinit_finish(Kex *kex)
kex_choose_conf(kex);
switch (kex->kex_type) {
case DH_GRP1_SHA1:
kexdh(kex);
break;
case DH_GEX_SHA1:
kexgex(kex);
break;
default:
if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX &&
kex->kex[kex->kex_type] != NULL) {
(kex->kex[kex->kex_type])(kex);
} else {
fatal("Unsupported key exchange %d", kex->kex_type);
}
}
@ -300,9 +293,9 @@ choose_kex(Kex *k, char *client, char *server)
if (k->name == NULL)
fatal("no kex alg");
if (strcmp(k->name, KEX_DH1) == 0) {
k->kex_type = DH_GRP1_SHA1;
k->kex_type = KEX_DH_GRP1_SHA1;
} else if (strcmp(k->name, KEX_DHGEX) == 0) {
k->kex_type = DH_GEX_SHA1;
k->kex_type = KEX_DH_GEX_SHA1;
} else
fatal("bad kex alg %s", k->name);
}
@ -318,6 +311,30 @@ choose_hostkeyalg(Kex *k, char *client, char *server)
xfree(hostkeyalg);
}
static int
proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
{
static int check[] = {
PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
};
int *idx;
char *p;
for (idx = &check[0]; *idx != -1; idx++) {
if ((p = strchr(my[*idx], ',')) != NULL)
*p = '\0';
if ((p = strchr(peer[*idx], ',')) != NULL)
*p = '\0';
if (strcmp(my[*idx], peer[*idx]) != 0) {
debug2("proposal mismatch: my %s peer %s",
my[*idx], peer[*idx]);
return (0);
}
}
debug2("proposals match");
return (1);
}
static void
kex_choose_conf(Kex *kex)
{
@ -328,9 +345,10 @@ kex_choose_conf(Kex *kex)
int mode;
int ctos; /* direction: if true client-to-server */
int need;
int first_kex_follows, type;
my = kex_buf2prop(&kex->my);
peer = kex_buf2prop(&kex->peer);
my = kex_buf2prop(&kex->my, NULL);
peer = kex_buf2prop(&kex->peer, &first_kex_follows);
if (kex->server) {
cprop=peer;
@ -374,6 +392,13 @@ kex_choose_conf(Kex *kex)
/* XXX need runden? */
kex->we_need = need;
/* ignore the next message if the proposals do not match */
if (first_kex_follows && !proposals_match(my, peer) &&
!(datafellows & SSH_BUG_FIRSTKEX)) {
type = packet_read();
debug2("skipping next packet (type %u)", type);
}
kex_prop_free(my);
kex_prop_free(peer);
}
@ -434,7 +459,7 @@ kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
for (i = 0; i < NKEYS; i++)
keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret);
debug("kex_derive_keys");
debug2("kex_derive_keys");
for (mode = 0; mode < MODE_MAX; mode++) {
current_keys[mode] = kex->newkeys[mode];
kex->newkeys[mode] = NULL;

25
crypto/dist/ssh/kex.h vendored
View File

@ -1,5 +1,5 @@
/* $NetBSD: kex.h,v 1.1.1.12 2002/10/01 13:39:57 itojun Exp $ */
/* $OpenBSD: kex.h,v 1.32 2002/09/09 14:54:14 markus Exp $ */
/* $NetBSD: kex.h,v 1.1.1.13 2003/04/03 05:57:22 itojun Exp $ */
/* $OpenBSD: kex.h,v 1.33 2003/02/16 17:09:57 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -56,8 +56,9 @@ enum kex_modes {
};
enum kex_exchange {
DH_GRP1_SHA1,
DH_GEX_SHA1
KEX_DH_GRP1_SHA1,
KEX_DH_GEX_SHA1,
KEX_MAX
};
#define KEX_INIT_SENT 0x0001
@ -113,6 +114,7 @@ struct Kex {
int (*verify_host_key)(Key *);
Key *(*load_host_key)(int);
int (*host_key_index)(Key *);
void (*kex[KEX_MAX])(Kex *);
};
Kex *kex_setup(char *[PROPOSAL_MAX]);
@ -122,11 +124,20 @@ void kex_send_kexinit(Kex *);
void kex_input_kexinit(int, u_int32_t, void *);
void kex_derive_keys(Kex *, u_char *, BIGNUM *);
void kexdh(Kex *);
void kexgex(Kex *);
Newkeys *kex_get_newkeys(int);
void kexdh_client(Kex *);
void kexdh_server(Kex *);
void kexgex_client(Kex *);
void kexgex_server(Kex *);
u_char *
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
BIGNUM *, BIGNUM *, BIGNUM *);
u_char *
kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int,
int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *);
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
void dump_digest(char *, u_char *, int);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexdh.c,v 1.1.1.5 2002/04/22 07:37:29 itojun Exp $ */
/* $NetBSD: kexdh.c,v 1.1.1.6 2003/04/03 05:57:22 itojun Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -24,23 +24,16 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $");
RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $");
#include <openssl/crypto.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include "xmalloc.h"
#include "buffer.h"
#include "bufaux.h"
#include "key.h"
#include "kex.h"
#include "log.h"
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
#include "monitor_wrap.h"
#include "kex.h"
static u_char *
u_char *
kex_dh_hash(
char *client_version_string,
char *server_version_string,
@ -87,222 +80,3 @@ kex_dh_hash(
#endif
return digest;
}
/* client */
static void
kexdh_client(Kex *kex)
{
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
DH *dh;
Key *server_host_key;
u_char *server_host_key_blob = NULL, *signature = NULL;
u_char *kbuf, *hash;
u_int klen, kout, slen, sbloblen;
/* generate and send 'e', client DH public key */
dh = dh_new_group1();
dh_gen_key(dh, kex->we_need * 8);
packet_start(SSH2_MSG_KEXDH_INIT);
packet_put_bignum2(dh->pub_key);
packet_send();
debug("sending SSH2_MSG_KEXDH_INIT");
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
debug("expecting SSH2_MSG_KEXDH_REPLY");
packet_read_expect(SSH2_MSG_KEXDH_REPLY);
/* key, cert */
server_host_key_blob = packet_get_string(&sbloblen);
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
if (server_host_key == NULL)
fatal("cannot decode server_host_key_blob");
if (server_host_key->type != kex->hostkey_type)
fatal("type mismatch for decoded server_host_key_blob");
if (kex->verify_host_key == NULL)
fatal("cannot verify server_host_key");
if (kex->verify_host_key(server_host_key) == -1)
fatal("server_host_key verification failed");
/* DH paramter f, server public DH key */
if ((dh_server_pub = BN_new()) == NULL)
fatal("dh_server_pub == NULL");
packet_get_bignum2(dh_server_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_server_pub= ");
BN_print_fp(stderr, dh_server_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_server_pub));
#endif
/* signed H */
signature = packet_get_string(&slen);
packet_check_eom();
if (!dh_pub_is_valid(dh, dh_server_pub))
packet_disconnect("bad server public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_server_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexdh_client: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
/* calc and verify H */
hash = kex_dh_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
server_host_key_blob, sbloblen,
dh->pub_key,
dh_server_pub,
shared_secret
);
xfree(server_host_key_blob);
BN_clear_free(dh_server_pub);
DH_free(dh);
if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
/* save session id */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}
/* server */
static void
kexdh_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
DH *dh;
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout;
u_int slen;
/* generate server DH public key */
dh = dh_new_group1();
dh_gen_key(dh, kex->we_need * 8);
debug("expecting SSH2_MSG_KEXDH_INIT");
packet_read_expect(SSH2_MSG_KEXDH_INIT);
if (kex->load_host_key == NULL)
fatal("Cannot load hostkey");
server_host_key = kex->load_host_key(kex->hostkey_type);
if (server_host_key == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
/* key, cert */
if ((dh_client_pub = BN_new()) == NULL)
fatal("dh_client_pub == NULL");
packet_get_bignum2(dh_client_pub);
packet_check_eom();
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_client_pub= ");
BN_print_fp(stderr, dh_client_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_client_pub));
#endif
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
if (!dh_pub_is_valid(dh, dh_client_pub))
packet_disconnect("bad client public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_client_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexdh_server: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
/* calc H */
hash = kex_dh_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
server_host_key_blob, sbloblen,
dh_client_pub,
dh->pub_key,
shared_secret
);
BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
/* sign H */
/* XXX hashlen depends on KEX */
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
/* destroy_sensitive_data(); */
/* send server hostkey, DH pubkey 'f' and singed H */
packet_start(SSH2_MSG_KEXDH_REPLY);
packet_put_string(server_host_key_blob, sbloblen);
packet_put_bignum2(dh->pub_key); /* f */
packet_put_string(signature, slen);
packet_send();
xfree(signature);
xfree(server_host_key_blob);
/* have keys, free DH */
DH_free(dh);
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}
void
kexdh(Kex *kex)
{
if (kex->server)
kexdh_server(kex);
else
kexdh_client(kex);
}

138
crypto/dist/ssh/kexdhc.c vendored Normal file
View File

@ -0,0 +1,138 @@
/* $NetBSD: kexdhc.c,v 1.1.1.1 2003/04/03 05:57:22 itojun Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: kexdhc.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
#include "xmalloc.h"
#include "key.h"
#include "kex.h"
#include "log.h"
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
void
kexdh_client(Kex *kex)
{
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
DH *dh;
Key *server_host_key;
u_char *server_host_key_blob = NULL, *signature = NULL;
u_char *kbuf, *hash;
u_int klen, kout, slen, sbloblen;
/* generate and send 'e', client DH public key */
dh = dh_new_group1();
dh_gen_key(dh, kex->we_need * 8);
packet_start(SSH2_MSG_KEXDH_INIT);
packet_put_bignum2(dh->pub_key);
packet_send();
debug("sending SSH2_MSG_KEXDH_INIT");
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
debug("expecting SSH2_MSG_KEXDH_REPLY");
packet_read_expect(SSH2_MSG_KEXDH_REPLY);
/* key, cert */
server_host_key_blob = packet_get_string(&sbloblen);
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
if (server_host_key == NULL)
fatal("cannot decode server_host_key_blob");
if (server_host_key->type != kex->hostkey_type)
fatal("type mismatch for decoded server_host_key_blob");
if (kex->verify_host_key == NULL)
fatal("cannot verify server_host_key");
if (kex->verify_host_key(server_host_key) == -1)
fatal("server_host_key verification failed");
/* DH paramter f, server public DH key */
if ((dh_server_pub = BN_new()) == NULL)
fatal("dh_server_pub == NULL");
packet_get_bignum2(dh_server_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_server_pub= ");
BN_print_fp(stderr, dh_server_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_server_pub));
#endif
/* signed H */
signature = packet_get_string(&slen);
packet_check_eom();
if (!dh_pub_is_valid(dh, dh_server_pub))
packet_disconnect("bad server public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_server_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexdh_client: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
/* calc and verify H */
hash = kex_dh_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
server_host_key_blob, sbloblen,
dh->pub_key,
dh_server_pub,
shared_secret
);
xfree(server_host_key_blob);
BN_clear_free(dh_server_pub);
DH_free(dh);
if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
/* save session id */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}

139
crypto/dist/ssh/kexdhs.c vendored Normal file
View File

@ -0,0 +1,139 @@
/* $NetBSD: kexdhs.c,v 1.1.1.1 2003/04/03 05:57:22 itojun Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: kexdhs.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
#include "xmalloc.h"
#include "key.h"
#include "kex.h"
#include "log.h"
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
#include "monitor_wrap.h"
void
kexdh_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
DH *dh;
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout;
u_int slen;
/* generate server DH public key */
dh = dh_new_group1();
dh_gen_key(dh, kex->we_need * 8);
debug("expecting SSH2_MSG_KEXDH_INIT");
packet_read_expect(SSH2_MSG_KEXDH_INIT);
if (kex->load_host_key == NULL)
fatal("Cannot load hostkey");
server_host_key = kex->load_host_key(kex->hostkey_type);
if (server_host_key == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
/* key, cert */
if ((dh_client_pub = BN_new()) == NULL)
fatal("dh_client_pub == NULL");
packet_get_bignum2(dh_client_pub);
packet_check_eom();
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_client_pub= ");
BN_print_fp(stderr, dh_client_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_client_pub));
#endif
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
if (!dh_pub_is_valid(dh, dh_client_pub))
packet_disconnect("bad client public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_client_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexdh_server: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
/* calc H */
hash = kex_dh_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
server_host_key_blob, sbloblen,
dh_client_pub,
dh->pub_key,
shared_secret
);
BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
/* sign H */
/* XXX hashlen depends on KEX */
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
/* destroy_sensitive_data(); */
/* send server hostkey, DH pubkey 'f' and singed H */
packet_start(SSH2_MSG_KEXDH_REPLY);
packet_put_string(server_host_key_blob, sbloblen);
packet_put_bignum2(dh->pub_key); /* f */
packet_put_string(signature, slen);
packet_send();
xfree(signature);
xfree(server_host_key_blob);
/* have keys, free DH */
DH_free(dh);
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexgex.c,v 1.1.1.6 2002/04/22 07:37:29 itojun Exp $ */
/* $NetBSD: kexgex.c,v 1.1.1.7 2003/04/03 05:57:22 itojun Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -25,23 +25,16 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $");
RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $");
#include <openssl/bn.h>
#include <openssl/evp.h>
#include "xmalloc.h"
#include "buffer.h"
#include "bufaux.h"
#include "key.h"
#include "kex.h"
#include "log.h"
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
#include "compat.h"
#include "monitor_wrap.h"
static u_char *
u_char *
kexgex_hash(
char *client_version_string,
char *server_version_string,
@ -98,318 +91,3 @@ kexgex_hash(
#endif
return digest;
}
/* client */
static void
kexgex_client(Kex *kex)
{
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
BIGNUM *p = NULL, *g = NULL;
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int klen, kout, slen, sbloblen;
int min, max, nbits;
DH *dh;
nbits = dh_estimate(kex->we_need * 8);
if (datafellows & SSH_OLD_DHGEX) {
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent");
/* Old GEX request */
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
packet_put_int(nbits);
min = DH_GRP_MIN;
max = DH_GRP_MAX;
} else {
debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent");
/* New GEX request */
min = DH_GRP_MIN;
max = DH_GRP_MAX;
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
packet_put_int(min);
packet_put_int(nbits);
packet_put_int(max);
}
#ifdef DEBUG_KEXDH
fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
min, nbits, max);
#endif
packet_send();
debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP");
packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP);
if ((p = BN_new()) == NULL)
fatal("BN_new");
packet_get_bignum2(p);
if ((g = BN_new()) == NULL)
fatal("BN_new");
packet_get_bignum2(g);
packet_check_eom();
if (BN_num_bits(p) < min || BN_num_bits(p) > max)
fatal("DH_GEX group out of range: %d !< %d !< %d",
min, BN_num_bits(p), max);
dh = dh_new_group(g, p);
dh_gen_key(dh, kex->we_need * 8);
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
/* generate and send 'e', client DH public key */
packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
packet_put_bignum2(dh->pub_key);
packet_send();
debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY");
packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY);
/* key, cert */
server_host_key_blob = packet_get_string(&sbloblen);
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
if (server_host_key == NULL)
fatal("cannot decode server_host_key_blob");
if (server_host_key->type != kex->hostkey_type)
fatal("type mismatch for decoded server_host_key_blob");
if (kex->verify_host_key == NULL)
fatal("cannot verify server_host_key");
if (kex->verify_host_key(server_host_key) == -1)
fatal("server_host_key verification failed");
/* DH paramter f, server public DH key */
if ((dh_server_pub = BN_new()) == NULL)
fatal("dh_server_pub == NULL");
packet_get_bignum2(dh_server_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_server_pub= ");
BN_print_fp(stderr, dh_server_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_server_pub));
#endif
/* signed H */
signature = packet_get_string(&slen);
packet_check_eom();
if (!dh_pub_is_valid(dh, dh_server_pub))
packet_disconnect("bad server public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_server_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexgex_client: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
if (datafellows & SSH_OLD_DHGEX)
min = max = -1;
/* calc and verify H */
hash = kexgex_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
server_host_key_blob, sbloblen,
min, nbits, max,
dh->p, dh->g,
dh->pub_key,
dh_server_pub,
shared_secret
);
/* have keys, free DH */
DH_free(dh);
xfree(server_host_key_blob);
BN_clear_free(dh_server_pub);
if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
/* save session id */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}
/* server */
static void
kexgex_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
Key *server_host_key;
DH *dh;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout, slen;
int min = -1, max = -1, nbits = -1, type;
if (kex->load_host_key == NULL)
fatal("Cannot load hostkey");
server_host_key = kex->load_host_key(kex->hostkey_type);
if (server_host_key == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
type = packet_read();
switch (type) {
case SSH2_MSG_KEX_DH_GEX_REQUEST:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
min = packet_get_int();
nbits = packet_get_int();
max = packet_get_int();
min = MAX(DH_GRP_MIN, min);
max = MIN(DH_GRP_MAX, max);
break;
case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received");
nbits = packet_get_int();
min = DH_GRP_MIN;
max = DH_GRP_MAX;
/* unused for old GEX */
break;
default:
fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
}
packet_check_eom();
if (max < min || nbits < min || max < nbits)
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
min, nbits, max);
/* Contact privileged parent */
dh = PRIVSEP(choose_dh(min, nbits, max));
if (dh == NULL)
packet_disconnect("Protocol error: no matching DH grp found");
debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
packet_put_bignum2(dh->p);
packet_put_bignum2(dh->g);
packet_send();
/* flush */
packet_write_wait();
/* Compute our exchange value in parallel with the client */
dh_gen_key(dh, kex->we_need * 8);
debug("expecting SSH2_MSG_KEX_DH_GEX_INIT");
packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT);
/* key, cert */
if ((dh_client_pub = BN_new()) == NULL)
fatal("dh_client_pub == NULL");
packet_get_bignum2(dh_client_pub);
packet_check_eom();
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_client_pub= ");
BN_print_fp(stderr, dh_client_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_client_pub));
#endif
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
if (!dh_pub_is_valid(dh, dh_client_pub))
packet_disconnect("bad client public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_client_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexgex_server: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
min = max = -1;
/* calc H */ /* XXX depends on 'kex' */
hash = kexgex_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
server_host_key_blob, sbloblen,
min, nbits, max,
dh->p, dh->g,
dh_client_pub,
dh->pub_key,
shared_secret
);
BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
/* sign H */
/* XXX hashlen depends on KEX */
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
/* destroy_sensitive_data(); */
/* send server hostkey, DH pubkey 'f' and singed H */
debug("SSH2_MSG_KEX_DH_GEX_REPLY sent");
packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
packet_put_string(server_host_key_blob, sbloblen);
packet_put_bignum2(dh->pub_key); /* f */
packet_put_string(signature, slen);
packet_send();
xfree(signature);
xfree(server_host_key_blob);
/* have keys, free DH */
DH_free(dh);
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}
void
kexgex(Kex *kex)
{
if (kex->server)
kexgex_server(kex);
else
kexgex_client(kex);
}

190
crypto/dist/ssh/kexgexc.c vendored Normal file
View File

@ -0,0 +1,190 @@
/* $NetBSD: kexgexc.c,v 1.1.1.1 2003/04/03 05:57:22 itojun Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: kexgexc.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
#include "xmalloc.h"
#include "key.h"
#include "kex.h"
#include "log.h"
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
#include "compat.h"
void
kexgex_client(Kex *kex)
{
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
BIGNUM *p = NULL, *g = NULL;
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int klen, kout, slen, sbloblen;
int min, max, nbits;
DH *dh;
nbits = dh_estimate(kex->we_need * 8);
if (datafellows & SSH_OLD_DHGEX) {
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent");
/* Old GEX request */
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
packet_put_int(nbits);
min = DH_GRP_MIN;
max = DH_GRP_MAX;
} else {
debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent");
/* New GEX request */
min = DH_GRP_MIN;
max = DH_GRP_MAX;
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
packet_put_int(min);
packet_put_int(nbits);
packet_put_int(max);
}
#ifdef DEBUG_KEXDH
fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
min, nbits, max);
#endif
packet_send();
debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP");
packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP);
if ((p = BN_new()) == NULL)
fatal("BN_new");
packet_get_bignum2(p);
if ((g = BN_new()) == NULL)
fatal("BN_new");
packet_get_bignum2(g);
packet_check_eom();
if (BN_num_bits(p) < min || BN_num_bits(p) > max)
fatal("DH_GEX group out of range: %d !< %d !< %d",
min, BN_num_bits(p), max);
dh = dh_new_group(g, p);
dh_gen_key(dh, kex->we_need * 8);
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
/* generate and send 'e', client DH public key */
packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
packet_put_bignum2(dh->pub_key);
packet_send();
debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY");
packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY);
/* key, cert */
server_host_key_blob = packet_get_string(&sbloblen);
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
if (server_host_key == NULL)
fatal("cannot decode server_host_key_blob");
if (server_host_key->type != kex->hostkey_type)
fatal("type mismatch for decoded server_host_key_blob");
if (kex->verify_host_key == NULL)
fatal("cannot verify server_host_key");
if (kex->verify_host_key(server_host_key) == -1)
fatal("server_host_key verification failed");
/* DH paramter f, server public DH key */
if ((dh_server_pub = BN_new()) == NULL)
fatal("dh_server_pub == NULL");
packet_get_bignum2(dh_server_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_server_pub= ");
BN_print_fp(stderr, dh_server_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_server_pub));
#endif
/* signed H */
signature = packet_get_string(&slen);
packet_check_eom();
if (!dh_pub_is_valid(dh, dh_server_pub))
packet_disconnect("bad server public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_server_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexgex_client: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
if (datafellows & SSH_OLD_DHGEX)
min = max = -1;
/* calc and verify H */
hash = kexgex_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
server_host_key_blob, sbloblen,
min, nbits, max,
dh->p, dh->g,
dh->pub_key,
dh_server_pub,
shared_secret
);
/* have keys, free DH */
DH_free(dh);
xfree(server_host_key_blob);
BN_clear_free(dh_server_pub);
if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
/* save session id */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}

187
crypto/dist/ssh/kexgexs.c vendored Normal file
View File

@ -0,0 +1,187 @@
/* $NetBSD: kexgexs.c,v 1.1.1.1 2003/04/03 05:57:22 itojun Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: kexgexs.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
#include "xmalloc.h"
#include "key.h"
#include "kex.h"
#include "log.h"
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
#include "compat.h"
#include "monitor_wrap.h"
void
kexgex_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
Key *server_host_key;
DH *dh;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout, slen;
int min = -1, max = -1, nbits = -1, type;
if (kex->load_host_key == NULL)
fatal("Cannot load hostkey");
server_host_key = kex->load_host_key(kex->hostkey_type);
if (server_host_key == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
type = packet_read();
switch (type) {
case SSH2_MSG_KEX_DH_GEX_REQUEST:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
min = packet_get_int();
nbits = packet_get_int();
max = packet_get_int();
min = MAX(DH_GRP_MIN, min);
max = MIN(DH_GRP_MAX, max);
break;
case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received");
nbits = packet_get_int();
min = DH_GRP_MIN;
max = DH_GRP_MAX;
/* unused for old GEX */
break;
default:
fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
}
packet_check_eom();
if (max < min || nbits < min || max < nbits)
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
min, nbits, max);
/* Contact privileged parent */
dh = PRIVSEP(choose_dh(min, nbits, max));
if (dh == NULL)
packet_disconnect("Protocol error: no matching DH grp found");
debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
packet_put_bignum2(dh->p);
packet_put_bignum2(dh->g);
packet_send();
/* flush */
packet_write_wait();
/* Compute our exchange value in parallel with the client */
dh_gen_key(dh, kex->we_need * 8);
debug("expecting SSH2_MSG_KEX_DH_GEX_INIT");
packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT);
/* key, cert */
if ((dh_client_pub = BN_new()) == NULL)
fatal("dh_client_pub == NULL");
packet_get_bignum2(dh_client_pub);
packet_check_eom();
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_client_pub= ");
BN_print_fp(stderr, dh_client_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_client_pub));
#endif
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
#endif
if (!dh_pub_is_valid(dh, dh_client_pub))
packet_disconnect("bad client public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_client_pub, dh);
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
if ((shared_secret = BN_new()) == NULL)
fatal("kexgex_server: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
min = max = -1;
/* calc H */ /* XXX depends on 'kex' */
hash = kexgex_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
server_host_key_blob, sbloblen,
min, nbits, max,
dh->p, dh->g,
dh_client_pub,
dh->pub_key,
shared_secret
);
BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
/* sign H */
/* XXX hashlen depends on KEX */
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
/* destroy_sensitive_data(); */
/* send server hostkey, DH pubkey 'f' and singed H */
debug("SSH2_MSG_KEX_DH_GEX_REPLY sent");
packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
packet_put_string(server_host_key_blob, sbloblen);
packet_put_bignum2(dh->pub_key); /* f */
packet_put_string(signature, slen);
packet_send();
xfree(signature);
xfree(server_host_key_blob);
/* have keys, free DH */
DH_free(dh);
kex_derive_keys(kex, hash, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}

10
crypto/dist/ssh/key.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.1.1.15 2002/10/01 13:39:57 itojun Exp $ */
/* $NetBSD: key.c,v 1.1.1.16 2003/04/03 05:57:23 itojun Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -33,15 +33,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: key.c,v 1.49 2002/09/09 14:54:14 markus Exp $");
RCSID("$OpenBSD: key.c,v 1.51 2003/02/12 09:33:04 markus Exp $");
#include <openssl/evp.h>
#include "xmalloc.h"
#include "key.h"
#include "rsa.h"
#include "ssh-dss.h"
#include "ssh-rsa.h"
#include "uuencode.h"
#include "buffer.h"
#include "bufaux.h"
@ -411,14 +409,14 @@ key_read(Key *ret, char **cpp)
case KEY_DSA:
space = strchr(cp, ' ');
if (space == NULL) {
debug3("key_read: no space");
debug3("key_read: missing whitespace");
return -1;
}
*space = '\0';
type = key_type_from_name(cp);
*space = ' ';
if (type == KEY_UNSPEC) {
debug3("key_read: no key found");
debug3("key_read: missing keytype");
return -1;
}
cp = space+1;

View File

@ -1,5 +1,5 @@
/* $NetBSD: key.h,v 1.1.1.9 2002/04/22 07:37:29 itojun Exp $ */
/* $OpenBSD: key.h,v 1.19 2002/03/18 17:23:31 markus Exp $ */
/* $NetBSD: key.h,v 1.1.1.10 2003/04/03 05:57:23 itojun Exp $ */
/* $OpenBSD: key.h,v 1.20 2003/02/12 09:33:04 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -79,4 +79,9 @@ int key_names_valid2(const char *);
int key_sign(Key *, u_char **, u_int *, u_char *, u_int);
int key_verify(Key *, u_char *, u_int, u_char *, u_int);
int ssh_dss_sign(Key *, u_char **, u_int *, u_char *, u_int);
int ssh_dss_verify(Key *, u_char *, u_int, u_char *, u_int);
int ssh_rsa_sign(Key *, u_char **, u_int *, u_char *, u_int);
int ssh_rsa_verify(Key *, u_char *, u_int, u_char *, u_int);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: log.c,v 1.1.1.8 2002/10/01 13:39:57 itojun Exp $ */
/* $NetBSD: log.c,v 1.1.1.9 2003/04/03 05:57:23 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,7 +35,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: log.c,v 1.24 2002/07/19 15:43:33 markus Exp $");
RCSID("$OpenBSD: log.c,v 1.25 2003/01/11 18:29:43 markus Exp $");
#include "log.h"
#include "xmalloc.h"
@ -231,6 +231,7 @@ fatal_remove_all_cleanups(void)
next_cu = cu->next;
xfree(cu);
}
fatal_cleanups = NULL;
}
/* Cleanup and exit */

View File

@ -1,4 +1,4 @@
/* $NetBSD: misc.c,v 1.1.1.8 2002/03/08 01:20:47 itojun Exp $ */
/* $NetBSD: misc.c,v 1.1.1.9 2003/04/03 05:57:23 itojun Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: misc.c,v 1.19 2002/03/04 17:27:39 stevesk Exp $");
RCSID("$OpenBSD: misc.c,v 1.20 2002/12/13 10:03:15 markus Exp $");
#include "misc.h"
#include "log.h"
@ -106,7 +106,7 @@ set_nodelay(int fd)
return;
}
opt = 1;
debug("fd %d setting TCP_NODELAY", fd);
debug2("fd %d setting TCP_NODELAY", fd);
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
}

View File

@ -1,3 +1,4 @@
# $NetBSD: moduli,v 1.1.1.3 2003/04/03 05:57:11 itojun Exp $
# $OpenBSD: moduli,v 1.1 2001/06/22 22:07:54 provos Exp $
# Time Type Tests Tries Size Generator Modulus

View File

@ -1,4 +1,5 @@
.\" $OpenBSD: moduli.5,v 1.6 2002/09/18 07:36:32 deraadt Exp $
.\" $NetBSD: moduli.5,v 1.1.1.6 2003/04/03 05:57:11 itojun Exp $
.\" $OpenBSD: moduli.5,v 1.7 2003/03/06 20:48:35 jmc Exp $
.\"
.\" Copyright 1997, 2000 William Allen Simpson <wsimpson@greendragon.com>
.\" All rights reserved.
@ -40,7 +41,7 @@
The
.Pa /etc/moduli
file contains the system-wide Diffie-Hellman prime moduli for
.Xr sshd .
.Xr sshd 8 .
.Pp
Each line in this file contains the following fields:
Time, Type, Tests, Tries, Size, Generator, Modulus.

View File

@ -1,4 +1,4 @@
/* $NetBSD: monitor.c,v 1.1.1.5 2002/10/01 13:40:02 itojun Exp $ */
/* $NetBSD: monitor.c,v 1.1.1.6 2003/04/03 05:57:24 itojun Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -26,7 +26,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor.c,v 1.29 2002/09/26 11:38:43 markus Exp $");
RCSID("$OpenBSD: monitor.c,v 1.37 2003/04/02 09:48:07 markus Exp $");
#include <openssl/dh.h>
@ -616,20 +616,20 @@ mm_answer_bsdauthquery(int socket, Buffer *m)
u_int numprompts;
u_int *echo_on;
char **prompts;
int res;
u_int success;
res = bsdauth_query(authctxt, &name, &infotxt, &numprompts,
&prompts, &echo_on);
success = bsdauth_query(authctxt, &name, &infotxt, &numprompts,
&prompts, &echo_on) < 0 ? 0 : 1;
buffer_clear(m);
buffer_put_int(m, res);
if (res != -1)
buffer_put_int(m, success);
if (success)
buffer_put_cstring(m, prompts[0]);
debug3("%s: sending challenge res: %d", __func__, res);
debug3("%s: sending challenge success: %u", __func__, success);
mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m);
if (res != -1) {
if (success) {
xfree(name);
xfree(infotxt);
xfree(prompts);
@ -673,16 +673,16 @@ mm_answer_skeyquery(int socket, Buffer *m)
{
struct skey skey;
char challenge[1024];
int res;
u_int success;
res = skeychallenge(&skey, authctxt->user, challenge);
success = skeychallenge(&skey, authctxt->user, challenge) < 0 ? 0 : 1;
buffer_clear(m);
buffer_put_int(m, res);
if (res != -1)
buffer_put_int(m, success);
if (success)
buffer_put_cstring(m, challenge);
debug3("%s: sending challenge res: %d", __func__, res);
debug3("%s: sending challenge success: %u", __func__, success);
mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m);
return (0);
@ -772,8 +772,9 @@ mm_answer_keyallowed(int socket, Buffer *m)
fatal("%s: unknown key type %d", __func__, type);
break;
}
key_free(key);
}
if (key != NULL)
key_free(key);
/* clear temporarily storage (used by verify) */
monitor_reset_key_state();
@ -792,6 +793,7 @@ mm_answer_keyallowed(int socket, Buffer *m)
buffer_clear(m);
buffer_put_int(m, allowed);
buffer_put_int(m, forced_command != NULL);
mm_append_debug(m);
@ -1154,6 +1156,7 @@ mm_answer_rsa_keyallowed(int socket, Buffer *m)
}
buffer_clear(m);
buffer_put_int(m, allowed);
buffer_put_int(m, forced_command != NULL);
/* clear temporarily storage (used by generate challenge) */
monitor_reset_key_state();
@ -1168,8 +1171,9 @@ mm_answer_rsa_keyallowed(int socket, Buffer *m)
key_blob = blob;
key_bloblen = blen;
key_blobtype = MM_RSAUSERKEY;
key_free(key);
}
if (key != NULL)
key_free(key);
mm_append_debug(m);
@ -1210,6 +1214,9 @@ mm_answer_rsa_challenge(int socket, Buffer *m)
mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m);
monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);
xfree(blob);
key_free(key);
return (0);
}
@ -1240,6 +1247,7 @@ mm_answer_rsa_response(int socket, Buffer *m)
fatal("%s: received bad response to challenge", __func__);
success = auth_rsa_verify_response(key, ssh1_challenge, response);
xfree(blob);
key_free(key);
xfree(response);
@ -1424,6 +1432,8 @@ mm_get_kex(Buffer *m)
(memcmp(kex->session_id, session_id2, session_id2_len) != 0))
fatal("mm_get_get: internal error: bad session id");
kex->we_need = buffer_get_int(m);
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
kex->server = 1;
kex->hostkey_type = buffer_get_int(m);
kex->kex_type = buffer_get_int(m);
@ -1453,6 +1463,8 @@ mm_get_keystate(struct monitor *pmonitor)
Buffer m;
u_char *blob, *p;
u_int bloblen, plen;
u_int32_t seqnr, packets;
u_int64_t blocks;
debug3("%s: Waiting for new keys", __func__);
@ -1482,8 +1494,14 @@ mm_get_keystate(struct monitor *pmonitor)
xfree(blob);
/* Now get sequence numbers for the packets */
packet_set_seqnr(MODE_OUT, buffer_get_int(&m));
packet_set_seqnr(MODE_IN, buffer_get_int(&m));
seqnr = buffer_get_int(&m);
blocks = buffer_get_int64(&m);
packets = buffer_get_int(&m);
packet_set_state(MODE_OUT, seqnr, blocks, packets);
seqnr = buffer_get_int(&m);
blocks = buffer_get_int64(&m);
packets = buffer_get_int(&m);
packet_set_state(MODE_IN, seqnr, blocks, packets);
skip:
/* Get the key context */
@ -1517,7 +1535,7 @@ mm_get_keystate(struct monitor *pmonitor)
void *
mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
{
size_t len = size * ncount;
size_t len = (size_t) size * ncount;
void *address;
if (len == 0 || ncount > SIZE_T_MAX / size)

View File

@ -1,4 +1,4 @@
/* $NetBSD: monitor_wrap.c,v 1.1.1.4 2002/10/01 13:40:03 itojun Exp $ */
/* $NetBSD: monitor_wrap.c,v 1.1.1.5 2003/04/03 05:57:25 itojun Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -26,7 +26,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor_wrap.c,v 1.19 2002/09/26 11:38:43 markus Exp $");
RCSID("$OpenBSD: monitor_wrap.c,v 1.25 2003/04/02 09:48:07 markus Exp $");
#include <openssl/bn.h>
#include <openssl/dh.h>
@ -35,6 +35,7 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.19 2002/09/26 11:38:43 markus Exp $");
#include "dh.h"
#include "kex.h"
#include "auth.h"
#include "auth-options.h"
#include "buffer.h"
#include "bufaux.h"
#include "packet.h"
@ -311,7 +312,7 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
Buffer m;
u_char *blob;
u_int len;
int allowed = 0;
int allowed = 0, have_forced = 0;
debug3("%s entering", __func__);
@ -333,6 +334,11 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
allowed = buffer_get_int(&m);
/* fake forced command */
auth_clear_options();
have_forced = buffer_get_int(&m);
forced_command = have_forced ? xstrdup("true") : NULL;
/* Send potential debug messages */
mm_send_debug(&m);
@ -513,6 +519,8 @@ mm_send_keystate(struct monitor *pmonitor)
Buffer m;
u_char *blob, *p;
u_int bloblen, plen;
u_int32_t seqnr, packets;
u_int64_t blocks;
buffer_init(&m);
@ -561,8 +569,14 @@ mm_send_keystate(struct monitor *pmonitor)
buffer_put_string(&m, blob, bloblen);
xfree(blob);
buffer_put_int(&m, packet_get_seqnr(MODE_OUT));
buffer_put_int(&m, packet_get_seqnr(MODE_IN));
packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
buffer_put_int(&m, seqnr);
buffer_put_int64(&m, blocks);
buffer_put_int(&m, packets);
packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
buffer_put_int(&m, seqnr);
buffer_put_int64(&m, blocks);
buffer_put_int(&m, packets);
debug3("%s: New keys have been sent", __func__);
skip:
@ -696,7 +710,7 @@ mm_bsdauth_query(void *ctx, char **name, char **infotxt,
u_int *numprompts, char ***prompts, u_int **echo_on)
{
Buffer m;
int res;
u_int success;
char *challenge;
debug3("%s: entering", __func__);
@ -706,8 +720,8 @@ mm_bsdauth_query(void *ctx, char **name, char **infotxt,
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
&m);
res = buffer_get_int(&m);
if (res == -1) {
success = buffer_get_int(&m);
if (success == 0) {
debug3("%s: no challenge", __func__);
buffer_free(&m);
return (-1);
@ -753,7 +767,8 @@ mm_skey_query(void *ctx, char **name, char **infotxt,
u_int *numprompts, char ***prompts, u_int **echo_on)
{
Buffer m;
int len, res;
int len;
u_int success;
char *p, *challenge;
debug3("%s: entering", __func__);
@ -763,8 +778,8 @@ mm_skey_query(void *ctx, char **name, char **infotxt,
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
&m);
res = buffer_get_int(&m);
if (res == -1) {
success = buffer_get_int(&m);
if (success == 0) {
debug3("%s: no challenge", __func__);
buffer_free(&m);
return (-1);
@ -834,7 +849,7 @@ mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
Key *key;
u_char *blob;
u_int blen;
int allowed = 0;
int allowed = 0, have_forced = 0;
debug3("%s entering", __func__);
@ -846,6 +861,11 @@ mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
allowed = buffer_get_int(&m);
/* fake forced command */
auth_clear_options();
have_forced = buffer_get_int(&m);
forced_command = have_forced ? xstrdup("true") : NULL;
if (allowed && rkey != NULL) {
blob = buffer_get_string(&m, &blen);
if ((key = key_from_blob(blob, blen)) == NULL)
@ -951,7 +971,7 @@ mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply)
xfree(p);
}
buffer_free(&m);
return (success);
return (success);
}
#endif

22
crypto/dist/ssh/msg.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: msg.c,v 1.1.1.3 2002/10/01 13:40:03 itojun Exp $ */
/* $NetBSD: msg.c,v 1.1.1.4 2003/04/03 05:57:25 itojun Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: msg.c,v 1.4 2002/07/01 16:15:25 deraadt Exp $");
RCSID("$OpenBSD: msg.c,v 1.5 2002/12/19 00:07:02 djm Exp $");
#include "buffer.h"
#include "getput.h"
@ -32,43 +32,43 @@ RCSID("$OpenBSD: msg.c,v 1.4 2002/07/01 16:15:25 deraadt Exp $");
#include "msg.h"
void
msg_send(int fd, u_char type, Buffer *m)
ssh_msg_send(int fd, u_char type, Buffer *m)
{
u_char buf[5];
u_int mlen = buffer_len(m);
debug3("msg_send: type %u", (unsigned int)type & 0xff);
debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff);
PUT_32BIT(buf, mlen + 1);
buf[4] = type; /* 1st byte of payload is mesg-type */
if (atomicio(write, fd, buf, sizeof(buf)) != sizeof(buf))
fatal("msg_send: write");
fatal("ssh_msg_send: write");
if (atomicio(write, fd, buffer_ptr(m), mlen) != mlen)
fatal("msg_send: write");
fatal("ssh_msg_send: write");
}
int
msg_recv(int fd, Buffer *m)
ssh_msg_recv(int fd, Buffer *m)
{
u_char buf[4];
ssize_t res;
u_int msg_len;
debug3("msg_recv entering");
debug3("ssh_msg_recv entering");
res = atomicio(read, fd, buf, sizeof(buf));
if (res != sizeof(buf)) {
if (res == 0)
return -1;
fatal("msg_recv: read: header %ld", (long)res);
fatal("ssh_msg_recv: read: header %ld", (long)res);
}
msg_len = GET_32BIT(buf);
if (msg_len > 256 * 1024)
fatal("msg_recv: read: bad msg_len %u", msg_len);
fatal("ssh_msg_recv: read: bad msg_len %u", msg_len);
buffer_clear(m);
buffer_append_space(m, msg_len);
res = atomicio(read, fd, buffer_ptr(m), msg_len);
if (res != msg_len)
fatal("msg_recv: read: %ld != msg_len", (long)res);
fatal("ssh_msg_recv: read: %ld != msg_len", (long)res);
return 0;
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: msg.h,v 1.1.1.1 2002/06/24 05:26:12 itojun Exp $ */
/* $OpenBSD: msg.h,v 1.1 2002/05/23 19:24:30 markus Exp $ */
/* $NetBSD: msg.h,v 1.1.1.2 2003/04/03 05:57:25 itojun Exp $ */
/* $OpenBSD: msg.h,v 1.2 2002/12/19 00:07:02 djm Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@ -26,7 +26,7 @@
#ifndef SSH_MSG_H
#define SSH_MSG_H
void msg_send(int, u_char, Buffer *);
int msg_recv(int, Buffer *);
void ssh_msg_send(int, u_char, Buffer *);
int ssh_msg_recv(int, Buffer *);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: packet.c,v 1.1.1.15 2002/10/01 13:39:58 itojun Exp $ */
/* $NetBSD: packet.c,v 1.1.1.16 2003/04/03 05:57:26 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -38,7 +38,9 @@
*/
#include "includes.h"
RCSID("$OpenBSD: packet.c,v 1.97 2002/07/04 08:12:15 deraadt Exp $");
RCSID("$OpenBSD: packet.c,v 1.105 2003/04/02 09:48:07 markus Exp $");
#include <sys/queue.h>
#include "xmalloc.h"
#include "buffer.h"
@ -117,8 +119,14 @@ static int interactive_mode = 0;
/* Session key information for Encryption and MAC */
Newkeys *newkeys[MODE_MAX];
static u_int32_t read_seqnr = 0;
static u_int32_t send_seqnr = 0;
static struct packet_state {
u_int32_t seqnr;
u_int32_t packets;
u_int64_t blocks;
} p_read, p_send;
static u_int64_t max_blocks_in, max_blocks_out;
static u_int32_t rekey_limit;
/* Session key for protocol v1 */
static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
@ -127,6 +135,13 @@ static u_int ssh1_keylen;
/* roundup current message to extra_pad bytes */
static u_char extra_pad = 0;
struct packet {
TAILQ_ENTRY(packet) next;
u_char type;
Buffer payload;
};
TAILQ_HEAD(, packet) outgoing;
/*
* Sets the descriptors used for communication. Disables encryption until
* packet_set_encryption_key is called.
@ -149,6 +164,7 @@ packet_set_connection(int fd_in, int fd_out)
buffer_init(&output);
buffer_init(&outgoing_packet);
buffer_init(&incoming_packet);
TAILQ_INIT(&outgoing);
}
/* Kludge: arrange the close function to be called from fatal(). */
fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
@ -255,22 +271,26 @@ packet_get_ssh1_cipher()
return (cipher_get_number(receive_context.cipher));
}
u_int32_t
packet_get_seqnr(int mode)
void
packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets)
{
return (mode == MODE_IN ? read_seqnr : send_seqnr);
struct packet_state *state;
state = (mode == MODE_IN) ? &p_read : &p_send;
*seqnr = state->seqnr;
*blocks = state->blocks;
*packets = state->packets;
}
void
packet_set_seqnr(int mode, u_int32_t seqnr)
packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets)
{
if (mode == MODE_IN)
read_seqnr = seqnr;
else if (mode == MODE_OUT)
send_seqnr = seqnr;
else
fatal("packet_set_seqnr: bad mode %d", mode);
struct packet_state *state;
state = (mode == MODE_IN) ? &p_read : &p_send;
state->seqnr = seqnr;
state->blocks = blocks;
state->packets = packets;
}
/* returns 1 if connection is via ipv4 */
@ -558,19 +578,24 @@ set_newkeys(int mode)
Mac *mac;
Comp *comp;
CipherContext *cc;
u_int64_t *max_blocks;
int encrypt;
debug("newkeys: mode %d", mode);
debug2("set_newkeys: mode %d", mode);
if (mode == MODE_OUT) {
cc = &send_context;
encrypt = CIPHER_ENCRYPT;
p_send.packets = p_send.blocks = 0;
max_blocks = &max_blocks_out;
} else {
cc = &receive_context;
encrypt = CIPHER_DECRYPT;
p_read.packets = p_read.blocks = 0;
max_blocks = &max_blocks_in;
}
if (newkeys[mode] != NULL) {
debug("newkeys: rekeying");
debug("set_newkeys: rekeying");
cipher_cleanup(cc);
enc = &newkeys[mode]->enc;
mac = &newkeys[mode]->mac;
@ -606,13 +631,16 @@ set_newkeys(int mode)
buffer_compress_init_recv();
comp->enabled = 1;
}
*max_blocks = ((u_int64_t)1 << (enc->block_size*2));
if (rekey_limit)
*max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
}
/*
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
*/
static void
packet_send2(void)
packet_send2_wrapped(void)
{
u_char type, *cp, *macbuf = NULL;
u_char padlen, pad;
@ -694,10 +722,10 @@ packet_send2(void)
/* compute MAC over seqnr and packet(length fields, payload, padding) */
if (mac && mac->enabled) {
macbuf = mac_compute(mac, send_seqnr,
macbuf = mac_compute(mac, p_send.seqnr,
buffer_ptr(&outgoing_packet),
buffer_len(&outgoing_packet));
DBG(debug("done calc MAC out #%d", send_seqnr));
DBG(debug("done calc MAC out #%d", p_send.seqnr));
}
/* encrypt packet and append to output buffer. */
cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
@ -711,14 +739,64 @@ packet_send2(void)
buffer_dump(&output);
#endif
/* increment sequence number for outgoing packets */
if (++send_seqnr == 0)
if (++p_send.seqnr == 0)
log("outgoing seqnr wraps around");
if (++p_send.packets == 0)
if (!(datafellows & SSH_BUG_NOREKEY))
fatal("XXX too many packets with same key");
p_send.blocks += (packet_length + 4) / block_size;
buffer_clear(&outgoing_packet);
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_OUT);
}
static void
packet_send2(void)
{
static int rekeying = 0;
struct packet *p;
u_char type, *cp;
cp = buffer_ptr(&outgoing_packet);
type = cp[5];
/* during rekeying we can only send key exchange messages */
if (rekeying) {
if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
(type <= SSH2_MSG_TRANSPORT_MAX))) {
debug("enqueue packet: %u", type);
p = xmalloc(sizeof(*p));
p->type = type;
memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
buffer_init(&outgoing_packet);
TAILQ_INSERT_TAIL(&outgoing, p, next);
return;
}
}
/* rekeying starts with sending KEXINIT */
if (type == SSH2_MSG_KEXINIT)
rekeying = 1;
packet_send2_wrapped();
/* after a NEWKEYS message we can send the complete queue */
if (type == SSH2_MSG_NEWKEYS) {
rekeying = 0;
while ((p = TAILQ_FIRST(&outgoing))) {
type = p->type;
debug("dequeue packet: %u", type);
buffer_free(&outgoing_packet);
memcpy(&outgoing_packet, &p->payload,
sizeof(Buffer));
TAILQ_REMOVE(&outgoing, p, next);
xfree(p);
packet_send2_wrapped();
}
}
}
void
packet_send(void)
{
@ -836,7 +914,7 @@ packet_read_poll1(void)
cp = buffer_ptr(&input);
len = GET_32BIT(cp);
if (len < 1 + 2 + 2 || len > 256 * 1024)
packet_disconnect("Bad packet length %d.", len);
packet_disconnect("Bad packet length %u.", len);
padded_len = (len + 8) & ~7;
/* Check if the packet has been entirely received. */
@ -932,9 +1010,9 @@ packet_read_poll2(u_int32_t *seqnr_p)
packet_length = GET_32BIT(cp);
if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
buffer_dump(&incoming_packet);
packet_disconnect("Bad packet length %d.", packet_length);
packet_disconnect("Bad packet length %u.", packet_length);
}
DBG(debug("input: packet len %d", packet_length+4));
DBG(debug("input: packet len %u", packet_length+4));
buffer_consume(&input, block_size);
}
/* we have a partial packet of block_size bytes */
@ -962,18 +1040,22 @@ packet_read_poll2(u_int32_t *seqnr_p)
* increment sequence number for incoming packet
*/
if (mac && mac->enabled) {
macbuf = mac_compute(mac, read_seqnr,
macbuf = mac_compute(mac, p_read.seqnr,
buffer_ptr(&incoming_packet),
buffer_len(&incoming_packet));
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
packet_disconnect("Corrupted MAC on input.");
DBG(debug("MAC #%d ok", read_seqnr));
DBG(debug("MAC #%d ok", p_read.seqnr));
buffer_consume(&input, mac->mac_len);
}
if (seqnr_p != NULL)
*seqnr_p = read_seqnr;
if (++read_seqnr == 0)
*seqnr_p = p_read.seqnr;
if (++p_read.seqnr == 0)
log("incoming seqnr wraps around");
if (++p_read.packets == 0)
if (!(datafellows & SSH_BUG_NOREKEY))
fatal("XXX too many packets with same key");
p_read.blocks += (packet_length + 4) / block_size;
/* get padlen */
cp = buffer_ptr(&incoming_packet);
@ -1222,6 +1304,9 @@ packet_disconnect(const char *fmt,...)
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
/* Display the error locally */
log("Disconnecting: %.100s", buf);
/* Send the disconnect message to the other side, and wait for it to get sent. */
if (compat20) {
packet_start(SSH2_MSG_DISCONNECT);
@ -1241,8 +1326,6 @@ packet_disconnect(const char *fmt,...)
/* Close the connection. */
packet_close();
/* Display the error locally and exit. */
log("Disconnecting: %.100s", buf);
fatal_cleanup();
}
@ -1309,14 +1392,26 @@ packet_not_very_much_data_to_write(void)
return buffer_len(&output) < 128 * 1024;
}
static void
packet_set_tos(int interactive)
{
int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT;
if (!packet_connection_is_on_socket() ||
!packet_connection_is_ipv4())
return;
if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &tos,
sizeof(tos)) < 0)
error("setsockopt IP_TOS %d: %.100s:",
tos, strerror(errno));
}
/* Informs that the current session is interactive. Sets IP flags for that. */
void
packet_set_interactive(int interactive)
{
static int called = 0;
int lowdelay = IPTOS_LOWDELAY;
int throughput = IPTOS_THROUGHPUT;
if (called)
return;
@ -1328,30 +1423,9 @@ packet_set_interactive(int interactive)
/* Only set socket options if using a socket. */
if (!packet_connection_is_on_socket())
return;
/*
* IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only
*/
if (interactive) {
/*
* Set IP options for an interactive connection. Use
* IPTOS_LOWDELAY and TCP_NODELAY.
*/
if (packet_connection_is_ipv4()) {
if (setsockopt(connection_in, IPPROTO_IP, IP_TOS,
&lowdelay, sizeof(lowdelay)) < 0)
error("setsockopt IPTOS_LOWDELAY: %.100s",
strerror(errno));
}
if (interactive)
set_nodelay(connection_in);
} else if (packet_connection_is_ipv4()) {
/*
* Set IP options for a non-interactive connection. Use
* IPTOS_THROUGHPUT.
*/
if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &throughput,
sizeof(throughput)) < 0)
error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
}
packet_set_tos(interactive);
}
/* Returns true if the current connection is interactive. */
@ -1415,3 +1489,22 @@ packet_send_ignore(int nbytes)
rand >>= 8;
}
}
#define MAX_PACKETS (1<<31)
int
packet_need_rekeying(void)
{
if (datafellows & SSH_BUG_NOREKEY)
return 0;
return
(p_send.packets > MAX_PACKETS) ||
(p_read.packets > MAX_PACKETS) ||
(max_blocks_out && (p_send.blocks > max_blocks_out)) ||
(max_blocks_in && (p_read.blocks > max_blocks_in));
}
void
packet_set_rekey_limit(u_int32_t bytes)
{
rekey_limit = bytes;
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: packet.h,v 1.1.1.12 2002/06/24 05:25:52 itojun Exp $ */
/* $OpenBSD: packet.h,v 1.35 2002/06/19 18:01:00 markus Exp $ */
/* $NetBSD: packet.h,v 1.1.1.13 2003/04/03 05:57:27 itojun Exp $ */
/* $OpenBSD: packet.h,v 1.38 2003/04/02 09:48:07 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -63,8 +63,8 @@ int packet_get_keyiv_len(int);
void packet_get_keyiv(int, u_char *, u_int);
int packet_get_keycontext(int, u_char *);
void packet_set_keycontext(int, u_char *);
u_int32_t packet_get_seqnr(int);
void packet_set_seqnr(int, u_int32_t);
void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *);
void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t);
int packet_get_ssh1_cipher(void);
void packet_set_iv(int, u_char *);
@ -97,4 +97,7 @@ do { \
} \
} while (0)
int packet_need_rekeying(void);
void packet_set_rekey_limit(u_int32_t);
#endif /* PACKET_H */

259
crypto/dist/ssh/progressmeter.c vendored Normal file
View File

@ -0,0 +1,259 @@
/* $NetBSD: progressmeter.c,v 1.1.1.1 2003/04/03 05:57:27 itojun Exp $ */
/*
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
* Copyright (c) 1999 Aaron Campbell. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Parts from:
*
* Copyright (c) 1983, 1990, 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include "includes.h"
RCSID("$OpenBSD: progressmeter.c,v 1.3 2003/03/17 10:38:38 markus Exp $");
#include <libgen.h>
#include "atomicio.h"
#include "progressmeter.h"
/* Number of seconds before xfer considered "stalled". */
#define STALLTIME 5
/* alarm() interval for updating progress meter. */
#define PROGRESSTIME 1
/* Signal handler used for updating the progress meter. */
static void update_progress_meter(int);
/* Returns non-zero if we are the foreground process. */
static int foregroundproc(void);
/* Returns width of the terminal (for progress meter calculations). */
static int get_tty_width(void);
/* Visual statistics about files as they are transferred. */
static void draw_progress_meter(void);
/* Time a transfer started. */
static struct timeval start;
/* Number of bytes of current file transferred so far. */
static volatile off_t *statbytes;
/* Total size of current file. */
static off_t totalbytes;
/* Name of current file being transferred. */
static char *curfile;
/* Time of last update. */
static struct timeval lastupdate;
/* Size at the time of the last update. */
static off_t lastsize;
void
start_progress_meter(char *file, off_t filesize, off_t *counter)
{
if ((curfile = basename(file)) == NULL)
curfile = file;
totalbytes = filesize;
statbytes = counter;
(void) gettimeofday(&start, (struct timezone *) 0);
lastupdate = start;
lastsize = 0;
draw_progress_meter();
signal(SIGALRM, update_progress_meter);
alarm(PROGRESSTIME);
}
void
stop_progress_meter()
{
alarm(0);
draw_progress_meter();
if (foregroundproc() != 0)
atomicio(write, fileno(stdout), "\n", 1);
}
static void
update_progress_meter(int ignore)
{
int save_errno = errno;
draw_progress_meter();
signal(SIGALRM, update_progress_meter);
alarm(PROGRESSTIME);
errno = save_errno;
}
static int
foregroundproc(void)
{
static pid_t pgrp = -1;
int ctty_pgrp;
if (pgrp == -1)
pgrp = getpgrp();
return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
ctty_pgrp == pgrp));
}
static void
draw_progress_meter()
{
static const char spaces[] = " "
" "
" "
" "
" "
" ";
static const char prefixes[] = " KMGTP";
struct timeval now, td, wait;
off_t cursize, abbrevsize, bytespersec;
double elapsed;
int ratio, remaining, i, ai, bi, nspaces;
char buf[512];
if (foregroundproc() == 0)
return;
(void) gettimeofday(&now, (struct timezone *) 0);
cursize = *statbytes;
if (totalbytes != 0) {
ratio = 100.0 * cursize / totalbytes;
ratio = MAX(ratio, 0);
ratio = MIN(ratio, 100);
} else
ratio = 100;
abbrevsize = cursize;
for (ai = 0; abbrevsize >= 10000 && ai < sizeof(prefixes); ai++)
abbrevsize >>= 10;
timersub(&now, &lastupdate, &wait);
if (cursize > lastsize) {
lastupdate = now;
lastsize = cursize;
wait.tv_sec = 0;
}
timersub(&now, &start, &td);
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
bytespersec = 0;
if (cursize > 0) {
bytespersec = cursize;
if (elapsed > 0.0)
bytespersec /= elapsed;
}
for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++)
bytespersec >>= 10;
nspaces = MIN(get_tty_width() - 79, sizeof(spaces) - 1);
snprintf(buf, sizeof(buf),
"\r%-45.45s%.*s%3d%% %4lld%c%c %3lld.%01d%cB/s",
curfile,
nspaces,
spaces,
ratio,
(long long)abbrevsize,
prefixes[ai],
ai == 0 ? ' ' : 'B',
(long long)(bytespersec / 1024),
(int)((bytespersec % 1024) * 10 / 1024),
prefixes[bi]
);
if (cursize <= 0 || elapsed <= 0.0 || cursize > totalbytes) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
" --:-- ETA");
} else if (wait.tv_sec >= STALLTIME) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
" - stalled -");
} else {
if (cursize != totalbytes)
remaining = (int)(totalbytes / (cursize / elapsed) -
elapsed);
else
remaining = elapsed;
i = remaining / 3600;
if (i)
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"%2d:", i);
else
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
" ");
i = remaining % 3600;
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"%02d:%02d%s", i / 60, i % 60,
(cursize != totalbytes) ? " ETA" : " ");
}
atomicio(write, fileno(stdout), buf, strlen(buf));
}
static int
get_tty_width(void)
{
struct winsize winsize;
if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
return (winsize.ws_col ? winsize.ws_col : 80);
else
return (80);
}

28
crypto/dist/ssh/progressmeter.h vendored Normal file
View File

@ -0,0 +1,28 @@
/* $NetBSD: progressmeter.h,v 1.1.1.1 2003/04/03 05:57:27 itojun Exp $ */
/* $OpenBSD: progressmeter.h,v 1.1 2003/01/10 08:19:07 fgsch Exp $ */
/*
* Copyright (c) 2002 Nils Nordman. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
void start_progress_meter(char *, off_t, off_t *);
void stop_progress_meter(void);

View File

@ -1,4 +1,4 @@
/* $NetBSD: readconf.c,v 1.1.1.14 2002/06/24 05:25:53 itojun Exp $ */
/* $NetBSD: readconf.c,v 1.1.1.15 2003/04/03 05:57:27 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");
RCSID("$OpenBSD: readconf.c,v 1.105 2003/04/02 09:48:07 markus Exp $");
#include "ssh.h"
#include "xmalloc.h"
@ -115,6 +115,7 @@ typedef enum {
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
oEnableSSHKeysign, oRekeyLimit,
oDeprecated
} OpCodes;
@ -186,7 +187,9 @@ static struct {
{ "bindaddress", oBindAddress },
{ "smartcarddevice", oSmartcardDevice },
{ "clearallforwardings", oClearAllForwardings },
{ "enablesshkeysign", oEnableSSHKeysign },
{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
{ "rekeylimit", oRekeyLimit },
{ NULL, oBadOption }
};
@ -265,14 +268,16 @@ parse_token(const char *cp, const char *filename, int linenum)
* Processes a single option line as used in the configuration files. This
* only sets those values that have not already been set.
*/
#define WHITESPACE " \t\r\n"
int
process_config_line(Options *options, const char *host,
char *line, const char *filename, int linenum,
int *activep)
{
char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
int opcode, *intptr, value;
size_t len;
u_short fwd_port, fwd_host_port;
char sfwd_host_port[6];
@ -418,6 +423,31 @@ parse_flag:
intptr = &options->compression_level;
goto parse_int;
case oRekeyLimit:
intptr = &options->rekey_limit;
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (arg[0] < '0' || arg[0] > '9')
fatal("%.200s line %d: Bad number.", filename, linenum);
value = strtol(arg, &endofnumber, 10);
if (arg == endofnumber)
fatal("%.200s line %d: Bad number.", filename, linenum);
switch (toupper(*endofnumber)) {
case 'K':
value *= 1<<10;
break;
case 'M':
value *= 1<<20;
break;
case 'G':
value *= 1<<30;
break;
}
if (*activep && *intptr == -1)
*intptr = value;
break;
case oIdentityFile:
arg = strdelim(&s);
if (!arg || *arg == '\0')
@ -485,16 +515,9 @@ parse_string:
case oProxyCommand:
charptr = &options->proxy_command;
string = xstrdup("");
while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
string = xrealloc(string, strlen(string) + strlen(arg) + 2);
strcat(string, " ");
strcat(string, arg);
}
len = strspn(s, WHITESPACE "=");
if (*activep && *charptr == NULL)
*charptr = string;
else
xfree(string);
*charptr = xstrdup(s + len);
return 0;
case oPort:
@ -668,6 +691,10 @@ parse_int:
*intptr = value;
break;
case oEnableSSHKeysign:
intptr = &options->enable_ssh_keysign;
goto parse_flag;
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@ -791,7 +818,9 @@ initialize_options(Options * options)
options->preferred_authentications = NULL;
options->bind_address = NULL;
options->smartcard_device = NULL;
options->enable_ssh_keysign = - 1;
options->no_host_authentication_for_localhost = - 1;
options->rekey_limit = - 1;
}
/*
@ -906,6 +935,10 @@ fill_default_options(Options * options)
clear_forwardings(options);
if (options->no_host_authentication_for_localhost == - 1)
options->no_host_authentication_for_localhost = 0;
if (options->enable_ssh_keysign == -1)
options->enable_ssh_keysign = 0;
if (options->rekey_limit == -1)
options->rekey_limit = 0;
/* options->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */
/* options->hostname will be set in the main program if appropriate */

View File

@ -1,5 +1,5 @@
/* $NetBSD: readconf.h,v 1.1.1.12 2002/06/24 05:25:53 itojun Exp $ */
/* $OpenBSD: readconf.h,v 1.43 2002/06/08 05:17:01 markus Exp $ */
/* $NetBSD: readconf.h,v 1.1.1.13 2003/04/03 05:57:28 itojun Exp $ */
/* $OpenBSD: readconf.h,v 1.47 2003/04/02 09:48:07 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -100,6 +100,9 @@ typedef struct {
int num_remote_forwards;
Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
int clear_forwardings;
int enable_ssh_keysign;
int rekey_limit;
int no_host_authentication_for_localhost;
} Options;

View File

@ -1,4 +1,4 @@
/* $NetBSD: readpass.c,v 1.1.1.11 2002/04/22 07:37:34 itojun Exp $ */
/* $NetBSD: readpass.c,v 1.1.1.12 2003/04/03 05:57:28 itojun Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readpass.c,v 1.27 2002/03/26 15:58:46 markus Exp $");
RCSID("$OpenBSD: readpass.c,v 1.28 2003/01/23 13:50:27 markus Exp $");
#include <readpassphrase.h>
@ -49,11 +49,11 @@ ssh_askpass(char *askpass, const char *msg)
fatal("internal error: askpass undefined");
if (pipe(p) < 0) {
error("ssh_askpass: pipe: %s", strerror(errno));
return xstrdup("");
return NULL;
}
if ((pid = fork()) < 0) {
error("ssh_askpass: fork: %s", strerror(errno));
return xstrdup("");
return NULL;
}
if (pid == 0) {
seteuid(getuid());
@ -82,6 +82,11 @@ ssh_askpass(char *askpass, const char *msg)
if (errno != EINTR)
break;
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
memset(buf, 0, sizeof(buf));
return NULL;
}
buf[strcspn(buf, "\r\n")] = '\0';
pass = xstrdup(buf);
memset(buf, 0, sizeof(buf));
@ -118,7 +123,10 @@ read_passphrase(const char *prompt, int flags)
askpass = getenv(SSH_ASKPASS_ENV);
else
askpass = _PATH_SSH_ASKPASS_DEFAULT;
return ssh_askpass(askpass, prompt);
if ((ret = ssh_askpass(askpass, prompt)) == NULL)
if (!(flags & RP_ALLOW_EOF))
return xstrdup("");
return ret;
}
if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL) {

23
crypto/dist/ssh/scp.1 vendored
View File

@ -1,4 +1,4 @@
.\" $NetBSD: scp.1,v 1.1.1.7 2002/06/24 05:25:55 itojun Exp $
.\" $NetBSD: scp.1,v 1.1.1.8 2003/04/03 05:57:29 itojun Exp $
.\" -*- nroff -*-
.\"
.\" scp.1
@ -10,7 +10,7 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
.\" $OpenBSD: scp.1,v 1.23 2002/06/22 16:41:57 stevesk Exp $
.\" $OpenBSD: scp.1,v 1.27 2003/03/28 10:11:43 jmc Exp $
.\"
.Dd September 25, 1999
.Dt SCP 1
@ -20,12 +20,14 @@
.Nd secure copy (remote file copy program)
.Sh SYNOPSIS
.Nm scp
.Op Fl pqrvBC46
.Bk -words
.Op Fl pqrvBC1246
.Op Fl F Ar ssh_config
.Op Fl S Ar program
.Op Fl P Ar port
.Op Fl c Ar cipher
.Op Fl i Ar identity_file
.Op Fl l Ar limit
.Op Fl o Ar ssh_option
.Sm off
.Oo
@ -40,6 +42,7 @@
.Ar host2 No :
.Oc Ar file2
.Sm on
.Ek
.Sh DESCRIPTION
.Nm
copies files between hosts on a network.
@ -69,6 +72,8 @@ Selects the file from which the identity (private key) for RSA
authentication is read.
This option is directly passed to
.Xr ssh 1 .
.It Fl l Ar limit
Limits the used bandwidth, specified in Kbit/s.
.It Fl p
Preserves modification times, access times, and modes from the
original file.
@ -123,9 +128,15 @@ in the format used in
This is useful for specifying options
for which there is no separate
.Nm scp
command-line flag. For example, forcing the use of protocol
version 1 is specified using
.Ic scp -oProtocol=1 .
command-line flag.
.It Fl 1
Forces
.Nm
to use protocol 1.
.It Fl 2
Forces
.Nm
to use protocol 2.
.It Fl 4
Forces
.Nm

334
crypto/dist/ssh/scp.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: scp.c,v 1.1.1.15 2002/06/24 05:25:55 itojun Exp $ */
/* $NetBSD: scp.c,v 1.1.1.16 2003/04/03 05:57:30 itojun Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@ -76,37 +76,24 @@
*/
#include "includes.h"
RCSID("$OpenBSD: scp.c,v 1.91 2002/06/19 00:27:55 deraadt Exp $");
RCSID("$OpenBSD: scp.c,v 1.102 2003/03/05 22:33:43 markus Exp $");
#include "xmalloc.h"
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"
#include "misc.h"
#include "progressmeter.h"
/* For progressmeter() -- number of seconds before xfer considered "stalled" */
#define STALLTIME 5
/* alarm() interval for updating progress meter */
#define PROGRESSTIME 1
/* Visual statistics about files as they are transferred. */
void progressmeter(int);
/* Returns width of the terminal (for progress meter calculations). */
int getttywidth(void);
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);
void bwlimit(int);
/* Struct for addargs */
arglist args;
/* Time a transfer started. */
static struct timeval start;
/* Number of bytes of current file transferred so far. */
volatile off_t statbytes;
/* Total size of current file. */
off_t totalbytes = 0;
/* Bandwidth limit */
off_t limit = 0;
/* Name of current file being transferred. */
char *curfile;
@ -120,6 +107,9 @@ int showprogress = 1;
/* This is the program to execute for the secured connection. ("ssh" or -S) */
char *ssh_program = _PATH_SSH_PROGRAM;
/* This is used to store the pid of ssh_program */
pid_t do_cmd_pid;
/*
* This function executes the given command as the specified user on the
* given host. This returns < 0 if execution fails, and >= 0 otherwise. This
@ -154,7 +144,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
close(reserved[1]);
/* For a child to execute the command on the remote host using ssh. */
if (fork() == 0) {
do_cmd_pid = fork();
if (do_cmd_pid == 0) {
/* Child. */
close(pin[1]);
close(pout[0]);
@ -172,6 +163,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
execvp(ssh_program, args.list);
perror(ssh_program);
exit(1);
} else if (do_cmd_pid == -1) {
fatal("fork: %s", strerror(errno));
}
/* Parent. Close the other side, and return the local side. */
close(pin[0]);
@ -214,8 +207,9 @@ main(argc, argv)
int argc;
char *argv[];
{
int ch, fflag, tflag;
char *targ;
int ch, fflag, tflag, status;
double speed;
char *targ, *endp;
extern char *optarg;
extern int optind;
@ -226,9 +220,11 @@ main(argc, argv)
addargs(&args, "-oClearAllForwardings yes");
fflag = tflag = 0;
while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:F:")) != -1)
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
switch (ch) {
/* User-visible flags. */
case '1':
case '2':
case '4':
case '6':
case 'C':
@ -246,6 +242,12 @@ main(argc, argv)
case 'B':
addargs(&args, "-oBatchmode yes");
break;
case 'l':
speed = strtod(optarg, &endp);
if (speed <= 0 || *endp != '\0')
usage();
limit = speed * 1024;
break;
case 'p':
pflag = 1;
break;
@ -307,6 +309,7 @@ main(argc, argv)
targetshouldbedirectory = 1;
remin = remout = -1;
do_cmd_pid = -1;
/* Command to be executed on remote system using "ssh". */
(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s",
verbose_mode ? " -v" : "",
@ -322,6 +325,22 @@ main(argc, argv)
if (targetshouldbedirectory)
verifydir(argv[argc - 1]);
}
/*
* Finally check the exit status of the ssh process, if one was forked
* and no error has occured yet
*/
if (do_cmd_pid != -1 && errs == 0) {
if (remin != -1)
(void) close(remin);
if (remout != -1)
(void) close(remout);
if (waitpid(do_cmd_pid, &status, 0) == -1)
errs = 1;
else {
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errs = 1;
}
}
exit(errs != 0);
}
@ -337,14 +356,12 @@ toremote(targ, argc, argv)
if (*targ == 0)
targ = ".";
if ((thost = strchr(argv[argc - 1], '@'))) {
if ((thost = strrchr(argv[argc - 1], '@'))) {
/* user@host */
*thost++ = 0;
tuser = argv[argc - 1];
if (*tuser == '\0')
tuser = NULL;
else if (!okname(tuser))
exit(1);
} else {
thost = argv[argc - 1];
tuser = NULL;
@ -358,7 +375,7 @@ toremote(targ, argc, argv)
*src++ = 0;
if (*src == 0)
src = ".";
host = strchr(argv[i], '@');
host = strrchr(argv[i], '@');
len = strlen(ssh_program) + strlen(argv[i]) +
strlen(src) + (tuser ? strlen(tuser) : 0) +
strlen(thost) + strlen(targ) +
@ -370,8 +387,14 @@ toremote(targ, argc, argv)
suser = argv[i];
if (*suser == '\0')
suser = pwd->pw_name;
else if (!okname(suser))
else if (!okname(suser)) {
xfree(bp);
continue;
}
if (tuser && !okname(tuser)) {
xfree(bp);
continue;
}
snprintf(bp, len,
"%s%s %s -n "
"-l %s %s %s %s '%s%s%s:%s'",
@ -437,7 +460,7 @@ tolocal(argc, argv)
*src++ = 0;
if (*src == 0)
src = ".";
if ((host = strchr(argv[i], '@')) == NULL) {
if ((host = strrchr(argv[i], '@')) == NULL) {
host = argv[i];
suser = NULL;
} else {
@ -445,8 +468,6 @@ tolocal(argc, argv)
suser = argv[i];
if (*suser == '\0')
suser = pwd->pw_name;
else if (!okname(suser))
continue;
}
host = cleanhostname(host);
len = strlen(src) + CMDNEEDS + 20;
@ -472,7 +493,7 @@ source(argc, argv)
struct stat stb;
static BUF buffer;
BUF *bp;
off_t i, amt, result;
off_t i, amt, result, statbytes;
int fd, haderr, indx;
char *last, *name, buf[2048];
int len;
@ -530,7 +551,6 @@ syserr: run_err("%s: %s", name, strerror(errno));
(long long)stb.st_size, last);
if (verbose_mode) {
fprintf(stderr, "Sending file modes: %s", buf);
fflush(stderr);
}
(void) atomicio(write, remout, buf, strlen(buf));
if (response() < 0)
@ -539,10 +559,8 @@ syserr: run_err("%s: %s", name, strerror(errno));
next: (void) close(fd);
continue;
}
if (showprogress) {
totalbytes = stb.st_size;
progressmeter(-1);
}
if (showprogress)
start_progress_meter(curfile, stb.st_size, &statbytes);
/* Keep writing after an error so that we stay sync'd up. */
for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
amt = bp->cnt;
@ -561,9 +579,11 @@ next: (void) close(fd);
haderr = result >= 0 ? EIO : errno;
statbytes += result;
}
if (limit)
bwlimit(amt);
}
if (showprogress)
progressmeter(1);
stop_progress_meter();
if (close(fd) < 0 && !haderr)
haderr = errno;
@ -630,6 +650,60 @@ rsource(name, statp)
(void) response();
}
void
bwlimit(int amount)
{
static struct timeval bwstart, bwend;
static int lamt, thresh = 16384;
u_int64_t wait;
struct timespec ts, rm;
if (!timerisset(&bwstart)) {
gettimeofday(&bwstart, NULL);
return;
}
lamt += amount;
if (lamt < thresh)
return;
gettimeofday(&bwend, NULL);
timersub(&bwend, &bwstart, &bwend);
if (!timerisset(&bwend))
return;
lamt *= 8;
wait = (double)1000000L * lamt / limit;
bwstart.tv_sec = wait / 1000000L;
bwstart.tv_usec = wait % 1000000L;
if (timercmp(&bwstart, &bwend, >)) {
timersub(&bwstart, &bwend, &bwend);
/* Adjust the wait time */
if (bwend.tv_sec) {
thresh /= 2;
if (thresh < 2048)
thresh = 2048;
} else if (bwend.tv_usec < 100) {
thresh *= 2;
if (thresh > 32768)
thresh = 32768;
}
TIMEVAL_TO_TIMESPEC(&bwend, &ts);
while (nanosleep(&ts, &rm) == -1) {
if (errno != EINTR)
break;
ts = rm;
}
}
lamt = 0;
gettimeofday(&bwstart, NULL);
}
void
sink(argc, argv)
int argc;
@ -643,7 +717,7 @@ sink(argc, argv)
BUF *bp;
off_t i, j;
int amt, count, exists, first, mask, mode, ofd, omode;
off_t size;
off_t size, statbytes;
int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
struct timeval tv[2];
@ -805,11 +879,9 @@ bad: run_err("%s: %s", np, strerror(errno));
cp = bp->buf;
wrerr = NO;
if (showprogress) {
totalbytes = size;
progressmeter(-1);
}
statbytes = 0;
if (showprogress)
start_progress_meter(curfile, size, &statbytes);
for (count = i = 0; i < size; i += 4096) {
amt = 4096;
if (i + amt > size)
@ -829,6 +901,10 @@ bad: run_err("%s: %s", np, strerror(errno));
cp += j;
statbytes += j;
} while (amt > 0);
if (limit)
bwlimit(4096);
if (count == bp->cnt) {
/* Keep reading so we stay sync'd up. */
if (wrerr == NO) {
@ -843,13 +919,13 @@ bad: run_err("%s: %s", np, strerror(errno));
}
}
if (showprogress)
progressmeter(1);
stop_progress_meter();
if (count != 0 && wrerr == NO &&
(j = atomicio(write, ofd, bp->buf, count)) != count) {
wrerr = YES;
wrerrno = j >= 0 ? EIO : errno;
}
if (ftruncate(ofd, size)) {
if (wrerr == NO && ftruncate(ofd, size) != 0) {
run_err("%s: truncate: %s", np, strerror(errno));
wrerr = DISPLAYED;
}
@ -930,8 +1006,8 @@ void
usage(void)
{
(void) fprintf(stderr,
"usage: scp [-pqrvBC46] [-F config] [-S program] [-P port]\n"
" [-c cipher] [-i identity] [-o option]\n"
"usage: scp [-pqrvBC1246] [-F config] [-S program] [-P port]\n"
" [-c cipher] [-i identity] [-l limit] [-o option]\n"
" [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
exit(1);
}
@ -988,9 +1064,18 @@ okname(cp0)
c = (int)*cp;
if (c & 0200)
goto bad;
if (!isalpha(c) && !isdigit(c) &&
c != '_' && c != '-' && c != '.' && c != '+')
goto bad;
if (!isalpha(c) && !isdigit(c)) {
switch (c) {
case '\'':
case '"':
case '`':
case ' ':
case '#':
goto bad;
default:
break;
}
}
} while (*++cp);
return (1);
@ -1010,11 +1095,9 @@ allocbuf(bp, fd, blksize)
run_err("fstat: %s", strerror(errno));
return (0);
}
if (stb.st_blksize == 0)
size = roundup(stb.st_blksize, blksize);
if (size == 0)
size = blksize;
else
size = blksize + (stb.st_blksize - blksize % stb.st_blksize) %
stb.st_blksize;
if (bp->cnt >= size)
return (bp);
if (bp->buf == NULL)
@ -1037,144 +1120,3 @@ lostconn(signo)
else
exit(1);
}
static void
updateprogressmeter(int ignore)
{
int save_errno = errno;
progressmeter(0);
signal(SIGALRM, updateprogressmeter);
alarm(PROGRESSTIME);
errno = save_errno;
}
static int
foregroundproc(void)
{
static pid_t pgrp = -1;
int ctty_pgrp;
if (pgrp == -1)
pgrp = getpgrp();
return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
ctty_pgrp == pgrp));
}
void
progressmeter(int flag)
{
static const char prefixes[] = " KMGTP";
static struct timeval lastupdate;
static off_t lastsize;
struct timeval now, td, wait;
off_t cursize, abbrevsize;
double elapsed;
int ratio, barlength, i, remaining;
char buf[512];
if (flag == -1) {
(void) gettimeofday(&start, (struct timezone *) 0);
lastupdate = start;
lastsize = 0;
}
if (foregroundproc() == 0)
return;
(void) gettimeofday(&now, (struct timezone *) 0);
cursize = statbytes;
if (totalbytes != 0) {
ratio = 100.0 * cursize / totalbytes;
ratio = MAX(ratio, 0);
ratio = MIN(ratio, 100);
} else
ratio = 100;
snprintf(buf, sizeof(buf), "\r%-20.20s %3d%% ", curfile, ratio);
barlength = getttywidth() - 51;
if (barlength > 0) {
i = barlength * ratio / 100;
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"|%.*s%*s|", i,
"*******************************************************"
"*******************************************************"
"*******************************************************"
"*******************************************************"
"*******************************************************"
"*******************************************************"
"*******************************************************",
barlength - i, "");
}
i = 0;
abbrevsize = cursize;
while (abbrevsize >= 100000 && i < sizeof(prefixes)) {
i++;
abbrevsize >>= 10;
}
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5llu %c%c ",
(unsigned long long) abbrevsize, prefixes[i],
prefixes[i] == ' ' ? ' ' : 'B');
timersub(&now, &lastupdate, &wait);
if (cursize > lastsize) {
lastupdate = now;
lastsize = cursize;
if (wait.tv_sec >= STALLTIME) {
start.tv_sec += wait.tv_sec;
start.tv_usec += wait.tv_usec;
}
wait.tv_sec = 0;
}
timersub(&now, &start, &td);
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
if (flag != 1 &&
(statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes)) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
" --:-- ETA");
} else if (wait.tv_sec >= STALLTIME) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
" - stalled -");
} else {
if (flag != 1)
remaining = (int)(totalbytes / (statbytes / elapsed) -
elapsed);
else
remaining = elapsed;
i = remaining / 3600;
if (i)
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"%2d:", i);
else
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
" ");
i = remaining % 3600;
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"%02d:%02d%s", i / 60, i % 60,
(flag != 1) ? " ETA" : " ");
}
atomicio(write, fileno(stdout), buf, strlen(buf));
if (flag == -1) {
signal(SIGALRM, updateprogressmeter);
alarm(PROGRESSTIME);
} else if (flag == 1) {
alarm(0);
atomicio(write, fileno(stdout), "\n", 1);
statbytes = 0;
}
}
int
getttywidth(void)
{
struct winsize winsize;
if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
return (winsize.ws_col ? winsize.ws_col : 80);
else
return (80);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: servconf.c,v 1.1.1.16 2002/10/01 13:39:59 itojun Exp $ */
/* $NetBSD: servconf.c,v 1.1.1.17 2003/04/03 05:57:30 itojun Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -11,7 +11,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: servconf.c,v 1.115 2002/09/04 18:52:42 stevesk Exp $");
RCSID("$OpenBSD: servconf.c,v 1.116 2003/02/21 09:05:53 markus Exp $");
#if defined(KRB4) || defined(KRB5)
#include <krb.h>
@ -895,6 +895,7 @@ read_server_config(ServerOptions *options, const char *filename)
char line[1024];
FILE *f;
debug2("read_server_config: filename %s", filename);
f = fopen(filename, "r");
if (!f) {
perror(filename);

View File

@ -1,4 +1,4 @@
/* $NetBSD: serverloop.c,v 1.1.1.19 2002/10/01 13:39:59 itojun Exp $ */
/* $NetBSD: serverloop.c,v 1.1.1.20 2003/04/03 05:57:31 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: serverloop.c,v 1.104 2002/09/19 16:03:15 stevesk Exp $");
RCSID("$OpenBSD: serverloop.c,v 1.107 2003/04/02 09:48:07 markus Exp $");
#include "xmalloc.h"
#include "packet.h"
@ -770,8 +770,14 @@ server_loop2(Authctxt *authctxt)
&nalloc, 0);
collect_children();
if (!rekeying)
if (!rekeying) {
channel_after_select(readset, writeset);
if (packet_need_rekeying()) {
debug("need rekeying");
xxx_kex->done = 0;
kex_send_kexinit(xxx_kex);
}
}
process_input(readset);
if (connection_closed)
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: session.c,v 1.1.1.18 2002/10/01 13:39:59 itojun Exp $ */
/* $NetBSD: session.c,v 1.1.1.19 2003/04/03 05:57:32 itojun Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -34,7 +34,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: session.c,v 1.150 2002/09/16 19:55:33 stevesk Exp $");
RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -189,6 +189,8 @@ auth_input_request_forwarding(struct passwd * pw)
void
do_authenticated(Authctxt *authctxt)
{
setproctitle("%s", authctxt->pw->pw_name);
/*
* Cancel the alarm we set to limit the time taken for
* authentication.
@ -822,7 +824,7 @@ do_setup_env(Session *s, const char *shell)
{
char buf[256];
u_int i, envsize;
char **env;
char **env, *laddr;
struct passwd *pw = s->pw;
/* Initialize the environment. */
@ -877,9 +879,10 @@ do_setup_env(Session *s, const char *shell)
get_remote_ipaddr(), get_remote_port(), get_local_port());
child_set_env(&env, &envsize, "SSH_CLIENT", buf);
laddr = get_local_ipaddr(packet_get_connection_in());
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
get_remote_ipaddr(), get_remote_port(),
get_local_ipaddr(packet_get_connection_in()), get_local_port());
get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());
xfree(laddr);
child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
if (s->ttyfd != -1)
@ -967,8 +970,10 @@ do_rc_files(Session *s, const char *shell)
/* Add authority data to .Xauthority if appropriate. */
if (debug_flag) {
fprintf(stderr,
"Running %.500s add "
"%.100s %.100s %.100s\n",
"Running %.500s remove %.100s\n",
options.xauth_location, s->auth_display);
fprintf(stderr,
"%.500s add %.100s %.100s %.100s\n",
options.xauth_location, s->auth_display,
s->auth_proto, s->auth_data);
}
@ -976,6 +981,8 @@ do_rc_files(Session *s, const char *shell)
options.xauth_location);
f = popen(cmd, "w");
if (f) {
fprintf(f, "remove %s\n",
s->auth_display);
fprintf(f, "add %s %s %s\n",
s->auth_display, s->auth_proto,
s->auth_data);
@ -1095,12 +1102,17 @@ do_child(Session *s, const char *command)
* legal, and means /bin/sh.
*/
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
/*
* Make sure $SHELL points to the shell from the password file,
* even if shell is overridden from login.conf
*/
env = do_setup_env(s, shell);
#ifdef HAVE_LOGIN_CAP
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
#endif
env = do_setup_env(s, shell);
/* we have to stash the hostname before we close our socket. */
if (options.use_login)
hostname = get_remote_name_or_ip(utmp_len,

View File

@ -1,6 +1,6 @@
/* $NetBSD: sftp-client.c,v 1.1.1.12 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: sftp-client.c,v 1.1.1.13 2003/04/03 05:57:33 itojun Exp $ */
/*
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
* Copyright (c) 2001-2003 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -29,7 +29,7 @@
/* XXX: copy between two remote sites */
#include "includes.h"
RCSID("$OpenBSD: sftp-client.c,v 1.35 2002/09/11 22:41:49 djm Exp $");
RCSID("$OpenBSD: sftp-client.c,v 1.42 2003/03/05 22:33:43 markus Exp $");
#include <sys/queue.h>
@ -39,14 +39,20 @@ RCSID("$OpenBSD: sftp-client.c,v 1.35 2002/09/11 22:41:49 djm Exp $");
#include "xmalloc.h"
#include "log.h"
#include "atomicio.h"
#include "progressmeter.h"
#include "sftp.h"
#include "sftp-common.h"
#include "sftp-client.h"
extern int showprogress;
/* Minimum amount of data to read at at time */
#define MIN_READ_SIZE 512
/* Maximum packet size */
#define MAX_MSG_LENGTH (256 * 1024)
struct sftp_conn {
int fd_in;
int fd_out;
@ -59,48 +65,45 @@ struct sftp_conn {
static void
send_msg(int fd, Buffer *m)
{
int mlen = buffer_len(m);
int len;
Buffer oqueue;
u_char mlen[4];
buffer_init(&oqueue);
buffer_put_int(&oqueue, mlen);
buffer_append(&oqueue, buffer_ptr(m), mlen);
buffer_consume(m, mlen);
if (buffer_len(m) > MAX_MSG_LENGTH)
fatal("Outbound message too long %u", buffer_len(m));
len = atomicio(write, fd, buffer_ptr(&oqueue), buffer_len(&oqueue));
if (len <= 0)
/* Send length first */
PUT_32BIT(mlen, buffer_len(m));
if (atomicio(write, fd, mlen, sizeof(mlen)) <= 0)
fatal("Couldn't send packet: %s", strerror(errno));
buffer_free(&oqueue);
if (atomicio(write, fd, buffer_ptr(m), buffer_len(m)) <= 0)
fatal("Couldn't send packet: %s", strerror(errno));
buffer_clear(m);
}
static void
get_msg(int fd, Buffer *m)
{
u_int len, msg_len;
unsigned char buf[4096];
ssize_t len;
u_int msg_len;
len = atomicio(read, fd, buf, 4);
buffer_append_space(m, 4);
len = atomicio(read, fd, buffer_ptr(m), 4);
if (len == 0)
fatal("Connection closed");
else if (len == -1)
fatal("Couldn't read packet: %s", strerror(errno));
msg_len = GET_32BIT(buf);
if (msg_len > 256 * 1024)
msg_len = buffer_get_int(m);
if (msg_len > MAX_MSG_LENGTH)
fatal("Received message too long %u", msg_len);
while (msg_len) {
len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf)));
if (len == 0)
fatal("Connection closed");
else if (len == -1)
fatal("Couldn't read packet: %s", strerror(errno));
msg_len -= len;
buffer_append(m, buf, len);
}
buffer_append_space(m, msg_len);
len = atomicio(read, fd, buffer_ptr(m), msg_len);
if (len == 0)
fatal("Connection closed");
else if (len == -1)
fatal("Read packet: %s", strerror(errno));
}
static void
@ -372,6 +375,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
error("Couldn't read directory: %s",
fx2txt(status));
do_close(conn, handle, handle_len);
xfree(handle);
return(status);
}
} else if (type != SSH2_FXP_NAME)
@ -661,7 +665,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
newpath, fx2txt(status));
return(status);
@ -742,6 +746,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
int read_error, write_errno;
u_int64_t offset, size;
u_int handle_len, mode, type, id, buflen;
off_t progress_counter;
struct request {
u_int id;
u_int len;
@ -759,13 +764,13 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
/* XXX: should we preserve set[ug]id? */
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
mode = S_IWRITE | (a->perm & 0777);
mode = a->perm & 0777;
else
mode = 0666;
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
(a->perm & S_IFDIR)) {
error("Cannot download a directory: %s", remote_path);
(!S_ISREG(a->perm))) {
error("Cannot download non-regular file: %s", remote_path);
return(-1);
}
@ -794,7 +799,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
return(-1);
}
local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC,
mode | S_IWRITE);
if (local_fd == -1) {
error("Couldn't open local file \"%s\" for writing: %s",
local_path, strerror(errno));
@ -806,6 +812,16 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
/* Read from remote and write to local */
write_error = read_error = write_errno = num_req = offset = 0;
max_req = 1;
progress_counter = 0;
if (showprogress) {
if (size)
start_progress_meter(remote_path, size,
&progress_counter);
else
printf("Fetching %s to %s\n", remote_path, local_path);
}
while (num_req > 0 || max_req > 0) {
char *data;
u_int len;
@ -858,14 +874,15 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
(unsigned long long)req->offset + len - 1);
if (len > req->len)
fatal("Received more data than asked for "
"%u > %u", len, req->len);
"%u > %u", len, req->len);
if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
atomicio(write, local_fd, data, len) != len) &&
atomicio(write, local_fd, data, len) != len) &&
!write_error) {
write_errno = errno;
write_error = 1;
max_req = 0;
}
progress_counter += len;
xfree(data);
if (len == req->len) {
@ -908,6 +925,9 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
}
}
if (showprogress && size)
stop_progress_meter();
/* Sanity check */
if (TAILQ_FIRST(&requests) != NULL)
fatal("Transfer complete, but requests still in queue");
@ -927,7 +947,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
/* Override umask and utimes if asked */
if (pflag && fchmod(local_fd, mode) == -1)
error("Couldn't set mode on \"%s\": %s", local_path,
strerror(errno));
strerror(errno));
if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
struct timeval tv[2];
tv[0].tv_sec = a->atime;
@ -935,7 +955,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(local_path, tv) == -1)
error("Can't set times on \"%s\": %s",
local_path, strerror(errno));
local_path, strerror(errno));
}
}
close(local_fd);
@ -980,6 +1000,11 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
close(local_fd);
return(-1);
}
if (!S_ISREG(sb.st_mode)) {
error("%s is not a regular file", local_path);
close(local_fd);
return(-1);
}
stat_to_attrib(&sb, &a);
a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
@ -1014,6 +1039,11 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
/* Read from local and write to remote */
offset = 0;
if (showprogress)
start_progress_meter(local_path, sb.st_size, &offset);
else
printf("Uploading %s to %s\n", local_path, remote_path);
for (;;) {
int len;
@ -1044,7 +1074,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
buffer_put_string(&msg, data, len);
send_msg(conn->fd_out, &msg);
debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u",
id, (unsigned long long)offset, len);
id, (unsigned long long)offset, len);
} else if (TAILQ_FIRST(&acks) == NULL)
break;
@ -1078,9 +1108,11 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
if (status != SSH2_FX_OK) {
error("Couldn't write to remote file \"%s\": %s",
remote_path, fx2txt(status));
remote_path, fx2txt(status));
do_close(conn, handle, handle_len);
close(local_fd);
xfree(data);
xfree(ack);
goto done;
}
debug3("In write loop, ack for %u %u bytes at %llu",
@ -1090,6 +1122,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
}
offset += len;
}
if (showprogress)
stop_progress_meter();
xfree(data);
if (close(local_fd) == -1) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: sftp-common.c,v 1.1.1.6 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: sftp-common.c,v 1.1.1.7 2003/04/03 05:57:33 itojun Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Damien Miller. All rights reserved.
@ -25,7 +25,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sftp-common.c,v 1.7 2002/09/11 22:41:50 djm Exp $");
RCSID("$OpenBSD: sftp-common.c,v 1.8 2002/10/16 14:31:48 itojun Exp $");
#include "buffer.h"
#include "bufaux.h"
@ -209,6 +209,6 @@ ls_file(char *name, struct stat *st, int remote)
glen = MAX(strlen(group), 8);
snprintf(buf, sizeof buf, "%s %3d %-*s %-*s %8llu %s %s", mode,
st->st_nlink, ulen, user, glen, group,
(u_int64_t)st->st_size, tbuf, name);
(unsigned long long)st->st_size, tbuf, name);
return xstrdup(buf);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sftp-int.c,v 1.1.1.13 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: sftp-int.c,v 1.1.1.14 2003/04/03 05:57:34 itojun Exp $ */
/*
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
@ -26,7 +26,7 @@
/* XXX: recursive operations */
#include "includes.h"
RCSID("$OpenBSD: sftp-int.c,v 1.49 2002/09/12 00:13:06 djm Exp $");
RCSID("$OpenBSD: sftp-int.c,v 1.57 2003/03/05 22:33:43 markus Exp $");
#include <glob.h>
@ -50,6 +50,9 @@ extern size_t copy_buffer_len;
/* Number of concurrent outstanding requests */
extern int num_requests;
/* This is set to 0 if the progressmeter is not desired. */
int showprogress = 1;
/* Seperators for interactive commands */
#define WHITESPACE " \t\r\n"
@ -76,13 +79,14 @@ extern int num_requests;
#define I_SHELL 20
#define I_SYMLINK 21
#define I_VERSION 22
#define I_PROGRESS 23
struct CMD {
const char *c;
const int n;
};
const struct CMD cmds[] = {
static const struct CMD cmds[] = {
{ "bye", I_QUIT },
{ "cd", I_CHDIR },
{ "chdir", I_CHDIR },
@ -103,6 +107,7 @@ const struct CMD cmds[] = {
{ "ls", I_LS },
{ "lumask", I_LUMASK },
{ "mkdir", I_MKDIR },
{ "progress", I_PROGRESS },
{ "put", I_PUT },
{ "mput", I_PUT },
{ "pwd", I_PWD },
@ -135,6 +140,7 @@ help(void)
printf("ls [path] Display remote directory listing\n");
printf("lumask umask Set local umask to 'umask'\n");
printf("mkdir path Create remote directory\n");
printf("progress Toggle display of progress meter\n");
printf("put local-path [remote-path] Upload file\n");
printf("pwd Display remote working directory\n");
printf("exit Quit sftp\n");
@ -377,6 +383,17 @@ is_dir(char *path)
return(sb.st_mode & S_IFDIR);
}
static int
is_reg(char *path)
{
struct stat sb;
if (stat(path, &sb) == -1)
fatal("stat %s: %s", path, strerror(errno));
return(S_ISREG(sb.st_mode));
}
static int
remote_is_dir(struct sftp_conn *conn, char *path)
{
@ -428,7 +445,6 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
err = -1;
goto out;
}
printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);
goto out;
}
@ -492,6 +508,12 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
/* Only one match, dst may be file, directory or unspecified */
if (g.gl_pathv[0] && g.gl_matchc == 1) {
if (!is_reg(g.gl_pathv[0])) {
error("Can't upload %s: not a regular file",
g.gl_pathv[0]);
err = 1;
goto out;
}
if (tmp_dst) {
/* If directory specified, append filename */
if (remote_is_dir(conn, tmp_dst)) {
@ -510,7 +532,6 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
}
abs_dst = make_absolute(abs_dst, pwd);
}
printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
err = do_upload(conn, g.gl_pathv[0], abs_dst, pflag);
goto out;
}
@ -524,6 +545,11 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
}
for (i = 0; g.gl_pathv[i]; i++) {
if (!is_reg(g.gl_pathv[i])) {
error("skipping non-regular file %s",
g.gl_pathv[i]);
continue;
}
if (infer_path(g.gl_pathv[i], &tmp)) {
err = -1;
goto out;
@ -553,7 +579,7 @@ sdirent_comp(const void *aa, const void *bb)
SFTP_DIRENT *a = *(SFTP_DIRENT **)aa;
SFTP_DIRENT *b = *(SFTP_DIRENT **)bb;
return (strcmp(a->filename, b->filename));
return (strcmp(a->filename, b->filename));
}
/* sftp ls.1 replacement for directories */
@ -566,7 +592,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
if ((n = do_readdir(conn, path, &d)) != 0)
return (n);
/* Count entries for sort */
/* Count entries for sort */
for (n = 0; d[n] != NULL; n++)
;
@ -574,7 +600,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
for (n = 0; d[n] != NULL; n++) {
char *tmp, *fname;
tmp = path_append(path, d[n]->filename);
fname = path_strip(tmp, strip_path);
xfree(tmp);
@ -592,7 +618,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
/* XXX - multicolumn display would be nice here */
printf("%s\n", fname);
}
xfree(fname);
}
@ -602,7 +628,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
/* sftp ls.1 replacement which handles path globs */
static int
do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
int lflag)
{
glob_t g;
@ -612,23 +638,23 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
memset(&g, 0, sizeof(g));
if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE,
if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE,
NULL, &g)) {
error("Can't ls: \"%s\" not found", path);
return (-1);
}
/*
* If the glob returns a single match, which is the same as the
* If the glob returns a single match, which is the same as the
* input glob, and it is a directory, then just list its contents
*/
if (g.gl_pathc == 1 &&
if (g.gl_pathc == 1 &&
strncmp(path, g.gl_pathv[0], strlen(g.gl_pathv[0]) - 1) == 0) {
if ((a = do_lstat(conn, path, 1)) == NULL) {
globfree(&g);
return (-1);
}
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
S_ISDIR(a->perm)) {
globfree(&g);
return (do_ls_dir(conn, path, strip_path, lflag));
@ -643,8 +669,8 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
if (lflag) {
/*
* XXX: this is slow - 1 roundtrip per path
* A solution to this is to fork glob() and
* build a sftp specific version which keeps the
* A solution to this is to fork glob() and
* build a sftp specific version which keeps the
* attribs (which currently get thrown away)
* that the server returns as well as the filenames.
*/
@ -669,7 +695,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
}
static int
parse_args(const char **cpp, int *pflag, int *lflag,
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
unsigned long *n_arg, char **path1, char **path2)
{
const char *cmd, *cp = *cpp;
@ -681,10 +707,17 @@ parse_args(const char **cpp, int *pflag, int *lflag,
/* Skip leading whitespace */
cp = cp + strspn(cp, WHITESPACE);
/* Ignore blank lines */
if (!*cp)
return(-1);
/* Ignore blank lines and lines which begin with comment '#' char */
if (*cp == '\0' || *cp == '#')
return (0);
/* Check for leading '-' (disable error processing) */
*iflag = 0;
if (*cp == '-') {
*iflag = 1;
cp++;
}
/* Figure out which command we have */
for (i = 0; cmds[i].c; i++) {
int cmdlen = strlen(cmds[i].c);
@ -706,7 +739,7 @@ parse_args(const char **cpp, int *pflag, int *lflag,
cmdnum = I_SHELL;
} else if (cmdnum == -1) {
error("Invalid command.");
return(-1);
return (-1);
}
/* Get arguments and parse flags */
@ -806,6 +839,7 @@ parse_args(const char **cpp, int *pflag, int *lflag,
case I_LPWD:
case I_HELP:
case I_VERSION:
case I_PROGRESS:
break;
default:
fatal("Command not implemented");
@ -816,10 +850,11 @@ parse_args(const char **cpp, int *pflag, int *lflag,
}
static int
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
int err_abort)
{
char *path1, *path2, *tmp;
int pflag, lflag, cmdnum, i;
int pflag, lflag, iflag, cmdnum, i;
unsigned long n_arg;
Attrib a, *aa;
char path_buf[MAXPATHLEN];
@ -827,14 +862,22 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
glob_t g;
path1 = path2 = NULL;
cmdnum = parse_args(&cmd, &pflag, &lflag, &n_arg,
cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,
&path1, &path2);
if (iflag != 0)
err_abort = 0;
memset(&g, 0, sizeof(g));
/* Perform command */
switch (cmdnum) {
case 0:
/* Blank line */
break;
case -1:
/* Unrecognized command */
err = -1;
break;
case I_GET:
err = process_get(conn, path1, path2, *pwd, pflag);
@ -856,8 +899,9 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i]; i++) {
printf("Removing %s\n", g.gl_pathv[i]);
if (do_rm(conn, g.gl_pathv[i]) == -1)
err = -1;
err = do_rm(conn, g.gl_pathv[i]);
if (err != 0 && err_abort)
break;
}
break;
case I_MKDIR:
@ -903,15 +947,14 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
do_globbed_ls(conn, *pwd, *pwd, lflag);
break;
}
/* Strip pwd off beginning of non-absolute paths */
tmp = NULL;
if (*path1 != '/')
tmp = *pwd;
path1 = make_absolute(path1, *pwd);
do_globbed_ls(conn, path1, tmp, lflag);
err = do_globbed_ls(conn, path1, tmp, lflag);
break;
case I_LCHDIR:
if (chdir(path1) == -1) {
@ -945,62 +988,70 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i]; i++) {
printf("Changing mode on %s\n", g.gl_pathv[i]);
do_setstat(conn, g.gl_pathv[i], &a);
err = do_setstat(conn, g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
}
break;
case I_CHOWN:
path1 = make_absolute(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i]; i++) {
if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
continue;
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", g.gl_pathv[i]);
continue;
}
printf("Changing owner on %s\n", g.gl_pathv[i]);
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
aa->uid = n_arg;
do_setstat(conn, g.gl_pathv[i], aa);
}
break;
case I_CHGRP:
path1 = make_absolute(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i]; i++) {
if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
continue;
if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
if (err != 0 && err_abort)
break;
else
continue;
}
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", g.gl_pathv[i]);
continue;
if (err != 0 && err_abort)
break;
else
continue;
}
printf("Changing group on %s\n", g.gl_pathv[i]);
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
aa->gid = n_arg;
do_setstat(conn, g.gl_pathv[i], aa);
if (cmdnum == I_CHOWN) {
printf("Changing owner on %s\n", g.gl_pathv[i]);
aa->uid = n_arg;
} else {
printf("Changing group on %s\n", g.gl_pathv[i]);
aa->gid = n_arg;
}
err = do_setstat(conn, g.gl_pathv[i], aa);
if (err != 0 && err_abort)
break;
}
break;
case I_PWD:
printf("Remote working directory: %s\n", *pwd);
break;
case I_LPWD:
if (!getcwd(path_buf, sizeof(path_buf)))
error("Couldn't get local cwd: %s",
strerror(errno));
else
printf("Local working directory: %s\n",
path_buf);
if (!getcwd(path_buf, sizeof(path_buf))) {
error("Couldn't get local cwd: %s", strerror(errno));
err = -1;
break;
}
printf("Local working directory: %s\n", path_buf);
break;
case I_QUIT:
return(-1);
/* Processed below */
break;
case I_HELP:
help();
break;
case I_VERSION:
printf("SFTP protocol version %u\n", sftp_proto_version(conn));
break;
case I_PROGRESS:
showprogress = !showprogress;
if (showprogress)
printf("Progress meter enabled\n");
else
printf("Progress meter disabled\n");
break;
default:
fatal("%d is not implemented", cmdnum);
}
@ -1012,20 +1063,23 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
if (path2)
xfree(path2);
/* If an error occurs in batch mode we should abort. */
if (infile != stdin && err > 0)
return -1;
/* If an unignored error occurs in batch mode we should abort. */
if (err_abort && err != 0)
return (-1);
else if (cmdnum == I_QUIT)
return (1);
return(0);
return (0);
}
void
int
interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
{
char *pwd;
char *dir = NULL;
char cmd[2048];
struct sftp_conn *conn;
int err;
conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
if (conn == NULL)
@ -1042,7 +1096,8 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
if (remote_is_dir(conn, dir) && file2 == NULL) {
printf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
parse_dispatch_command(conn, cmd, &pwd);
if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0)
return (-1);
} else {
if (file2 == NULL)
snprintf(cmd, sizeof cmd, "get %s", dir);
@ -1050,15 +1105,18 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
snprintf(cmd, sizeof cmd, "get %s %s", dir,
file2);
parse_dispatch_command(conn, cmd, &pwd);
err = parse_dispatch_command(conn, cmd, &pwd, 1);
xfree(dir);
return;
xfree(pwd);
return (err);
}
xfree(dir);
}
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
err = 0;
for (;;) {
char *cp;
@ -1075,8 +1133,13 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
if (cp)
*cp = '\0';
if (parse_dispatch_command(conn, cmd, &pwd))
err = parse_dispatch_command(conn, cmd, &pwd, infile != stdin);
if (err != 0)
break;
}
xfree(pwd);
/* err == 1 signifies normal "quit" exit */
return (err >= 0 ? 0 : -1);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: sftp-int.h,v 1.1.1.5 2002/03/08 01:21:21 itojun Exp $ */
/* $OpenBSD: sftp-int.h,v 1.5 2002/02/13 00:59:23 djm Exp $ */
/* $NetBSD: sftp-int.h,v 1.1.1.6 2003/04/03 05:57:34 itojun Exp $ */
/* $OpenBSD: sftp-int.h,v 1.6 2003/01/08 23:53:26 djm Exp $ */
/*
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
@ -25,4 +25,4 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
void interactive_loop(int, int, char *, char *);
int interactive_loop(int, int, char *, char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: sftp-server.c,v 1.1.1.13 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: sftp-server.c,v 1.1.1.14 2003/04/03 05:57:34 itojun Exp $ */
/*
* Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: sftp-server.c,v 1.38 2002/09/11 22:41:50 djm Exp $");
RCSID("$OpenBSD: sftp-server.c,v 1.41 2003/03/26 04:02:51 deraadt Exp $");
#include "buffer.h"
#include "bufaux.h"
@ -153,7 +153,7 @@ handle_new(int use, char *name, int fd, DIR *dirp)
handles[i].use = use;
handles[i].dirp = dirp;
handles[i].fd = fd;
handles[i].name = name;
handles[i].name = xstrdup(name);
return i;
}
}
@ -225,9 +225,11 @@ handle_close(int handle)
if (handle_is_ok(handle, HANDLE_FILE)) {
ret = close(handles[handle].fd);
handles[handle].use = HANDLE_UNUSED;
xfree(handles[handle].name);
} else if (handle_is_ok(handle, HANDLE_DIR)) {
ret = closedir(handles[handle].dirp);
handles[handle].use = HANDLE_UNUSED;
xfree(handles[handle].name);
} else {
errno = ENOENT;
}
@ -391,7 +393,7 @@ process_open(void)
if (fd < 0) {
status = errno_to_portable(errno);
} else {
handle = handle_new(HANDLE_FILE, xstrdup(name), fd, NULL);
handle = handle_new(HANDLE_FILE, name, fd, NULL);
if (handle < 0) {
close(fd);
} else {
@ -662,7 +664,7 @@ process_opendir(void)
if (dirp == NULL) {
status = errno_to_portable(errno);
} else {
handle = handle_new(HANDLE_DIR, xstrdup(path), 0, dirp);
handle = handle_new(HANDLE_DIR, path, 0, dirp);
if (handle < 0) {
closedir(dirp);
} else {
@ -813,18 +815,32 @@ static void
process_rename(void)
{
u_int32_t id;
struct stat st;
char *oldpath, *newpath;
int ret, status = SSH2_FX_FAILURE;
int status;
struct stat sb;
id = get_int();
oldpath = get_string(NULL);
newpath = get_string(NULL);
TRACE("rename id %u old %s new %s", id, oldpath, newpath);
/* fail if 'newpath' exists */
if (stat(newpath, &st) == -1) {
ret = rename(oldpath, newpath);
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
status = SSH2_FX_FAILURE;
if (lstat(oldpath, &sb) == -1)
status = errno_to_portable(errno);
else if (S_ISREG(sb.st_mode)) {
/* Race-free rename of regular files */
if (link(oldpath, newpath) == -1)
status = errno_to_portable(errno);
else if (unlink(oldpath) == -1) {
status = errno_to_portable(errno);
/* clean spare link */
unlink(newpath);
} else
status = SSH2_FX_OK;
} else if (stat(newpath, &sb) == -1) {
if (rename(oldpath, newpath) == -1)
status = errno_to_portable(errno);
else
status = SSH2_FX_OK;
}
send_status(id, status);
xfree(oldpath);
@ -859,19 +875,16 @@ static void
process_symlink(void)
{
u_int32_t id;
struct stat st;
char *oldpath, *newpath;
int ret, status = SSH2_FX_FAILURE;
int ret, status;
id = get_int();
oldpath = get_string(NULL);
newpath = get_string(NULL);
TRACE("symlink id %u old %s new %s", id, oldpath, newpath);
/* fail if 'newpath' exists */
if (stat(newpath, &st) == -1) {
ret = symlink(oldpath, newpath);
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
}
/* this will fail if 'newpath' exists */
ret = symlink(oldpath, newpath);
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
xfree(oldpath);
xfree(newpath);

View File

@ -1,5 +1,5 @@
.\" $NetBSD: sftp.1,v 1.1.1.13 2002/10/01 13:40:00 itojun Exp $
.\" $OpenBSD: sftp.1,v 1.36 2002/09/11 22:41:50 djm Exp $
.\" $NetBSD: sftp.1,v 1.1.1.14 2003/04/03 05:57:34 itojun Exp $
.\" $OpenBSD: sftp.1,v 1.41 2003/03/28 10:11:43 jmc Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@ -31,6 +31,7 @@
.Nd Secure file transfer program
.Sh SYNOPSIS
.Nm sftp
.Bk -words
.Op Fl vC1
.Op Fl b Ar batchfile
.Op Fl o Ar ssh_option
@ -41,10 +42,15 @@
.Op Fl R Ar num_requests
.Op Fl S Ar program
.Ar host
.Ek
.Nm sftp
.Op [\fIuser\fR@]\fIhost\fR[:\fIfile\fR [\fIfile\fR]]
.Oo Oo Ar user Ns No @ Oc Ns
.Ar host Ns Oo : Ns Ar file Oo
.Ar file Oc Oc Oc
.Nm sftp
.Op [\fIuser\fR@]\fIhost\fR[:\fIdir\fR[\fI/\fR]]
.Oo Oo Ar user Ns No @ Oc Ns
.Ar host Ns Oo : Ns Ar dir Ns
.Oo Ar / Oc Oc Oc
.Sh DESCRIPTION
.Nm
is an interactive file transfer program, similar to
@ -78,9 +84,16 @@ non-interactive authentication.
will abort if any of the following
commands fail:
.Ic get , put , rename , ln ,
.Ic rm , mkdir , chdir , lchdir
.Ic rm , mkdir , chdir , ls ,
.Ic lchdir , chmod , chown , chgrp , lpwd
and
.Ic lmkdir .
Termination on error can be suppressed on a command by command basis by
prefixing the command with a
.Ic '-'
character (For example,
.Ic -rm /tmp/blah*
).
.It Fl o Ar ssh_option
Can be used to pass options to
.Nm ssh
@ -89,19 +102,19 @@ in the format used in
This is useful for specifying options
for which there is no separate
.Nm sftp
command-line flag. For example, to specify an alternate
command-line flag. For example, to specify an alternate
port use:
.Ic sftp -oPort=24 .
.It Fl s Ar subsystem | sftp_server
Specifies the SSH2 subsystem or the path for an sftp server
on the remote host. A path is useful for using sftp over
on the remote host. A path is useful for using sftp over
protocol version 1, or when the remote
.Nm sshd
does not have an sftp subsystem configured.
.It Fl v
Raise logging level. This option is also passed to ssh.
.It Fl B Ar buffer_size
Specify the size of the buffer that
Specify the size of the buffer that
.Nm
uses when transferring files. Larger buffers require fewer round trips at
the cost of higher memory consumption. The default is 32768 bytes.
@ -222,10 +235,12 @@ Set local umask to
.It Ic mkdir Ar path
Create remote directory specified by
.Ar path .
.It Ic progress
Toggle display of progress meter.
.It Xo Ic put
.Op Ar flags
.Ar local-path
.Op Ar local-path
.Op Ar remote-path
.Xc
Upload
.Ar local-path
@ -254,6 +269,10 @@ Create a symbolic link from
.Ar oldpath
to
.Ar newpath .
.It Ic version
Display the
.Nm
protocol version.
.It Ic ! Ar command
Execute
.Ar command

View File

@ -1,4 +1,4 @@
/* $NetBSD: sftp.c,v 1.1.1.11 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: sftp.c,v 1.1.1.12 2003/04/03 05:57:34 itojun Exp $ */
/*
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
@ -25,7 +25,7 @@
#include "includes.h"
RCSID("$OpenBSD: sftp.c,v 1.31 2002/07/25 01:16:59 mouring Exp $");
RCSID("$OpenBSD: sftp.c,v 1.34 2003/01/10 08:19:07 fgsch Exp $");
/* XXX: short-form remote directory listings (like 'ls -C') */
@ -44,6 +44,8 @@ FILE* infile;
size_t copy_buffer_len = 32768;
size_t num_requests = 16;
extern int showprogress;
static void
connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid)
{
@ -103,7 +105,7 @@ usage(void)
int
main(int argc, char **argv)
{
int in, out, ch;
int in, out, ch, err;
pid_t sshpid;
char *host, *userhost, *cp, *file2;
int debug_level = 0, sshver = 2;
@ -156,6 +158,7 @@ main(int argc, char **argv)
fatal("%s (%s).", strerror(errno), optarg);
} else
fatal("Filename already specified.");
showprogress = 0;
break;
case 'P':
sftp_direct = optarg;
@ -191,7 +194,7 @@ main(int argc, char **argv)
file1 = cp;
}
if ((host = strchr(userhost, '@')) == NULL)
if ((host = strrchr(userhost, '@')) == NULL)
host = userhost;
else {
*host++ = '\0';
@ -231,7 +234,7 @@ main(int argc, char **argv)
&sshpid);
}
interactive_loop(in, out, file1, file2);
err = interactive_loop(in, out, file1, file2);
close(in);
close(out);
@ -243,5 +246,5 @@ main(int argc, char **argv)
fatal("Couldn't wait for ssh process: %s",
strerror(errno));
exit(0);
exit(err == 0 ? 0 : 1);
}

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-add.1,v 1.1.1.10 2002/06/24 05:26:00 itojun Exp $
.\" $OpenBSD: ssh-add.1,v 1.35 2002/06/19 00:27:55 deraadt Exp $
.\" $NetBSD: ssh-add.1,v 1.1.1.11 2003/04/03 05:57:35 itojun Exp $
.\" $OpenBSD: ssh-add.1,v 1.38 2003/03/28 10:11:43 jmc Exp $
.\"
.\" -*- nroff -*-
.\"
@ -46,7 +46,7 @@
.Nd adds RSA or DSA identities to the authentication agent
.Sh SYNOPSIS
.Nm ssh-add
.Op Fl lLdDxX
.Op Fl lLdDxXc
.Op Fl t Ar life
.Op Ar
.Nm ssh-add
@ -93,7 +93,16 @@ Unlock the agent.
Set a maximum lifetime when adding identities to an agent.
The lifetime may be specified in seconds or in a time format
specified in
.Xr sshd 8 .
.Xr sshd_config 5 .
.It Fl c
Indicates that added identities should be subject to confirmation before
being used for authentication.
Confirmation is performed by the
.Ev SSH_ASKPASS
program mentioned below.
Successful confirmation is signaled by a zero exit status from the
.Ev SSH_ASKPASS
program, rather than text entered into the requester.
.It Fl s Ar reader
Add key in smartcard
.Ar reader .

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-add.c,v 1.1.1.13 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: ssh-add.c,v 1.1.1.14 2003/04/03 05:57:35 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-add.c,v 1.63 2002/09/19 15:51:23 markus Exp $");
RCSID("$OpenBSD: ssh-add.c,v 1.66 2003/03/05 22:33:43 markus Exp $");
#include <openssl/evp.h>
@ -65,6 +65,9 @@ static char *default_files[] = {
/* Default lifetime (0 == forever) */
static int lifetime = 0;
/* User has to confirm key use */
static int confirm = 0;
/* we keep a cache of one passphrases */
static char *pass = NULL;
static void
@ -160,12 +163,16 @@ add_file(AuthenticationConnection *ac, const char *filename)
}
}
if (ssh_add_identity_constrained(ac, private, comment, lifetime)) {
if (ssh_add_identity_constrained(ac, private, comment, lifetime,
confirm)) {
fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
ret = 0;
if (lifetime != 0)
fprintf(stderr,
fprintf(stderr,
"Lifetime set to %d seconds\n", lifetime);
if (confirm != 0)
fprintf(stderr,
"The user has to confirm each use of the key\n");
} else if (ssh_add_identity(ac, private, comment)) {
fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
ret = 0;
@ -183,6 +190,7 @@ static int
update_card(AuthenticationConnection *ac, int add, const char *id)
{
char *pin;
int ret = -1;
pin = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
if (pin == NULL)
@ -191,12 +199,14 @@ update_card(AuthenticationConnection *ac, int add, const char *id)
if (ssh_update_card(ac, add, id, pin)) {
fprintf(stderr, "Card %s: %s\n",
add ? "added" : "removed", id);
return 0;
ret = 0;
} else {
fprintf(stderr, "Could not %s card: %s\n",
add ? "add" : "remove", id);
return -1;
ret = -1;
}
xfree(pin);
return ret;
}
static int
@ -287,6 +297,7 @@ usage(void)
fprintf(stderr, " -x Lock agent.\n");
fprintf(stderr, " -X Unlock agent.\n");
fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n");
fprintf(stderr, " -c Require confirmation to sign using identities\n");
#ifdef SMARTCARD
fprintf(stderr, " -s reader Add key in smartcard reader.\n");
fprintf(stderr, " -e reader Remove key in smartcard reader.\n");
@ -310,7 +321,7 @@ main(int argc, char **argv)
fprintf(stderr, "Could not open a connection to your authentication agent.\n");
exit(2);
}
while ((ch = getopt(argc, argv, "lLdDxXe:s:t:")) != -1) {
while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
switch (ch) {
case 'l':
case 'L':
@ -324,6 +335,9 @@ main(int argc, char **argv)
ret = 1;
goto done;
break;
case 'c':
confirm = 1;
break;
case 'd':
deleting = 1;
break;

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-agent.1,v 1.1.1.12 2002/06/26 14:03:09 itojun Exp $
.\" $OpenBSD: ssh-agent.1,v 1.35 2002/06/24 13:12:23 markus Exp $
.\" $NetBSD: ssh-agent.1,v 1.1.1.13 2003/04/03 05:57:35 itojun Exp $
.\" $OpenBSD: ssh-agent.1,v 1.37 2003/03/28 10:11:43 jmc Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -45,6 +45,7 @@
.Nm ssh-agent
.Op Fl a Ar bind_address
.Op Fl c Li | Fl s
.Op Fl t Ar life
.Op Fl d
.Op Ar command Op Ar args ...
.Nm ssh-agent
@ -87,8 +88,17 @@ does not look like it's a csh style of shell.
Kill the current agent (given by the
.Ev SSH_AGENT_PID
environment variable).
.It Fl t Ar life
Set a default value for the maximum lifetime of identities added to the agent.
The lifetime may be specified in seconds or in a time format specified in
.Xr sshd 8 .
A lifetime specified for an identity with
.Xr ssh-add 1
overrides this value.
Without this option the default maximum lifetime is forever.
.It Fl d
Debug mode. When this option is specified
Debug mode.
When this option is specified
.Nm
will not fork.
.El

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-agent.c,v 1.1.1.15 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: ssh-agent.c,v 1.1.1.16 2003/04/03 05:57:36 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
#include "includes.h"
#include <sys/queue.h>
RCSID("$OpenBSD: ssh-agent.c,v 1.104 2002/09/12 19:11:52 stevesk Exp $");
RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $");
#include <openssl/evp.h>
#include <openssl/md5.h>
@ -51,6 +51,8 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.104 2002/09/12 19:11:52 stevesk Exp $");
#include "authfd.h"
#include "compat.h"
#include "log.h"
#include "readpass.h"
#include "misc.h"
#ifdef SMARTCARD
#include "scard.h"
@ -78,6 +80,7 @@ typedef struct identity {
Key *key;
char *comment;
u_int death;
u_int confirm;
} Identity;
typedef struct {
@ -103,6 +106,9 @@ char *lock_passwd = NULL;
extern char *__progname;
/* Default lifetime (0 == forever) */
static int lifetime = 0;
static void
close_socket(SocketEntry *e)
{
@ -156,6 +162,30 @@ lookup_identity(Key *key, int version)
return (NULL);
}
/* Check confirmation of keysign request */
static int
confirm_key(Identity *id)
{
char *p, prompt[1024];
int ret = -1;
p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
snprintf(prompt, sizeof(prompt), "Allow use of key %s?\n"
"Key fingerprint %s.", id->comment, p);
xfree(p);
p = read_passphrase(prompt, RP_ALLOW_EOF);
if (p != NULL) {
/*
* Accept empty responses and responses consisting
* of the word "yes" as affirmative.
*/
if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0)
ret = 0;
xfree(p);
}
return (ret);
}
/* send list of supported public keys to 'client' */
static void
process_request_identities(SocketEntry *e, int version)
@ -219,7 +249,7 @@ process_authentication_challenge1(SocketEntry *e)
goto failure;
id = lookup_identity(key, 1);
if (id != NULL) {
if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
Key *private = id->key;
/* Decrypt the challenge using the private key. */
if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
@ -279,7 +309,7 @@ process_sign_request2(SocketEntry *e)
key = key_from_blob(blob, blen);
if (key != NULL) {
Identity *id = lookup_identity(key, 2);
if (id != NULL)
if (id != NULL && (!id->confirm || confirm_key(id) == 0))
ok = key_sign(id->key, &signature, &slen, data, dlen);
}
key_free(key);
@ -399,7 +429,7 @@ static void
process_add_identity(SocketEntry *e, int version)
{
Idtab *tab = idtab_lookup(version);
int type, success = 0, death = 0;
int type, success = 0, death = 0, confirm = 0;
char *type_name, *comment;
Key *k = NULL;
@ -450,6 +480,17 @@ process_add_identity(SocketEntry *e, int version)
}
break;
}
/* enable blinding */
switch (k->type) {
case KEY_RSA:
case KEY_RSA1:
if (RSA_blinding_on(k->rsa, NULL) != 1) {
error("process_add_identity: RSA_blinding_on failed");
key_free(k);
goto send;
}
break;
}
comment = buffer_get_string(&e->request, NULL);
if (k == NULL) {
xfree(comment);
@ -461,15 +502,21 @@ process_add_identity(SocketEntry *e, int version)
case SSH_AGENT_CONSTRAIN_LIFETIME:
death = time(NULL) + buffer_get_int(&e->request);
break;
case SSH_AGENT_CONSTRAIN_CONFIRM:
confirm = 1;
break;
default:
break;
}
}
if (lifetime && !death)
death = time(NULL) + lifetime;
if (lookup_identity(k, version) == NULL) {
Identity *id = xmalloc(sizeof(Identity));
id->key = k;
id->comment = comment;
id->death = death;
id->confirm = confirm;
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
/* Increment the number of identities. */
tab->nentries++;
@ -554,6 +601,7 @@ process_add_smartcard_key (SocketEntry *e)
id->key = k;
id->comment = xstrdup("smartcard key");
id->death = 0;
id->confirm = 0;
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
tab->nentries++;
success = 1;
@ -830,7 +878,7 @@ after_select(fd_set *readset, fd_set *writeset)
close(sock);
break;
}
if (getuid() != euid) {
if ((euid != 0) && (getuid() != euid)) {
error("uid mismatch: "
"peer euid %u != uid %u",
(u_int) euid, (u_int) getuid());
@ -927,13 +975,15 @@ usage(void)
fprintf(stderr, " -k Kill the current agent.\n");
fprintf(stderr, " -d Debug mode.\n");
fprintf(stderr, " -a socket Bind agent socket to given name.\n");
fprintf(stderr, " -t life Default identity lifetime (seconds).\n");
exit(1);
}
int
main(int ac, char **av)
{
int sock, c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, ch, nalloc;
int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
int sock, fd, ch, nalloc;
char *shell, *format, *pidstr, *agentsocket = NULL;
fd_set *readsetp = NULL, *writesetp = NULL;
struct sockaddr_un sunaddr;
@ -949,7 +999,7 @@ main(int ac, char **av)
SSLeay_add_all_algorithms();
while ((ch = getopt(ac, av, "cdksa:")) != -1) {
while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
switch (ch) {
case 'c':
if (s_flag)
@ -972,6 +1022,12 @@ main(int ac, char **av)
case 'a':
agentsocket = optarg;
break;
case 't':
if ((lifetime = convtime(optarg)) == -1) {
fprintf(stderr, "Invalid lifetime\n");
usage();
}
break;
default:
usage();
}
@ -1095,9 +1151,14 @@ main(int ac, char **av)
}
(void)chdir("/");
close(0);
close(1);
close(2);
if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
/* XXX might close listen socket */
(void)dup2(fd, STDIN_FILENO);
(void)dup2(fd, STDOUT_FILENO);
(void)dup2(fd, STDERR_FILENO);
if (fd > 2)
close(fd);
}
/* deny core dumps, since memory contains unencrypted private keys */
rlim.rlim_cur = rlim.rlim_max = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-dss.c,v 1.1.1.11 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: ssh-dss.c,v 1.1.1.12 2003/04/03 05:57:36 itojun Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-dss.c,v 1.17 2002/07/04 10:41:47 markus Exp $");
RCSID("$OpenBSD: ssh-dss.c,v 1.18 2003/02/12 09:33:04 markus Exp $");
#include <openssl/bn.h>
#include <openssl/evp.h>
@ -35,7 +35,6 @@ RCSID("$OpenBSD: ssh-dss.c,v 1.17 2002/07/04 10:41:47 markus Exp $");
#include "compat.h"
#include "log.h"
#include "key.h"
#include "ssh-dss.h"
#define INTBLOB_LEN 20
#define SIGBLOB_LEN (2*INTBLOB_LEN)

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-keygen.1,v 1.1.1.13 2002/06/24 05:26:02 itojun Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.54 2002/06/19 00:27:55 deraadt Exp $
.\" $NetBSD: ssh-keygen.1,v 1.1.1.14 2003/04/03 05:57:36 itojun Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.56 2003/03/28 10:11:43 jmc Exp $
.\"
.\" -*- nroff -*-
.\"
@ -46,12 +46,14 @@
.Nd authentication key generation, management and conversion
.Sh SYNOPSIS
.Nm ssh-keygen
.Bk -words
.Op Fl q
.Op Fl b Ar bits
.Fl t Ar type
.Op Fl N Ar new_passphrase
.Op Fl C Ar comment
.Op Fl f Ar output_keyfile
.Ek
.Nm ssh-keygen
.Fl p
.Op Fl P Ar old_passphrase
@ -148,8 +150,7 @@ The options are as follows:
.It Fl b Ar bits
Specifies the number of bits in the key to create.
Minimum is 512 bits.
Generally 1024 bits is considered sufficient, and key sizes
above that no longer improve security but make things slower.
Generally, 1024 bits is considered sufficient.
The default is 1024 bits.
.It Fl c
Requests changing the comment in the private and public key files.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-keygen.c,v 1.1.1.15 2002/06/24 05:26:02 itojun Exp $ */
/* $NetBSD: ssh-keygen.c,v 1.1.1.16 2003/04/03 05:57:37 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keygen.c,v 1.101 2002/06/23 09:39:55 deraadt Exp $");
RCSID("$OpenBSD: ssh-keygen.c,v 1.102 2002/11/26 00:45:03 wcobb Exp $");
#include <openssl/evp.h>
#include <openssl/pem.h>
@ -106,7 +106,6 @@ ask_filename(struct passwd *pw, const char *prompt)
snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
fprintf(stderr, "%s (%s): ", prompt, identity_file);
fflush(stderr);
if (fgets(buf, sizeof(buf), stdin) == NULL)
exit(1);
if (strchr(buf, '\n'))

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-keyscan.1,v 1.1.1.8 2002/03/08 01:21:26 itojun Exp $
.\" $OpenBSD: ssh-keyscan.1,v 1.14 2002/02/13 08:33:47 mpech Exp $
.\" $NetBSD: ssh-keyscan.1,v 1.1.1.9 2003/04/03 05:57:37 itojun Exp $
.\" $OpenBSD: ssh-keyscan.1,v 1.15 2003/03/28 10:11:43 jmc Exp $
.\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
.\"
@ -15,6 +15,7 @@
.Nd gather ssh public keys
.Sh SYNOPSIS
.Nm ssh-keyscan
.Bk -words
.Op Fl v46
.Op Fl p Ar port
.Op Fl T Ar timeout
@ -22,10 +23,12 @@
.Op Fl f Ar file
.Op Ar host | addrlist namelist
.Op Ar ...
.Ek
.Sh DESCRIPTION
.Nm
is a utility for gathering the public ssh host keys of a number of
hosts. It was designed to aid in building and verifying
hosts.
It was designed to aid in building and verifying
.Pa ssh_known_hosts
files.
.Nm
@ -34,9 +37,11 @@ scripts.
.Pp
.Nm
uses non-blocking socket I/O to contact as many hosts as possible in
parallel, so it is very efficient. The keys from a domain of 1,000
parallel, so it is very efficient.
The keys from a domain of 1,000
hosts can be collected in tens of seconds, even when some of those
hosts are down or do not run ssh. For scanning, one does not need
hosts are down or do not run ssh.
For scanning, one does not need
login access to the machines that are being scanned, nor does the
scanning process involve any encryption.
.Pp
@ -45,12 +50,13 @@ The options are as follows:
.It Fl p Ar port
Port to connect to on the remote host.
.It Fl T Ar timeout
Set the timeout for connection attempts. If
Set the timeout for connection attempts.
If
.Pa timeout
seconds have elapsed since a connection was initiated to a host or since the
last time anything was read from that host, then the connection is
closed and the host in question considered unavailable. Default is 5
seconds.
closed and the host in question considered unavailable.
Default is 5 seconds.
.It Fl t Ar type
Specifies the type of the key to fetch from the scanned hosts.
The possible values are

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-keyscan.c,v 1.1.1.13 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: ssh-keyscan.c,v 1.1.1.14 2003/04/03 05:57:37 itojun Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -8,7 +8,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keyscan.c,v 1.40 2002/07/06 17:47:58 stevesk Exp $");
RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $");
#include <sys/queue.h>
#include <errno.h>
@ -336,6 +336,8 @@ keygrab_ssh2(con *c)
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA?
"ssh-dss": "ssh-rsa";
c->c_kex = kex_setup(myproposal);
c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
c->c_kex->verify_host_key = hostjump;
if (!(j = setjmp(kexjmp))) {

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-keysign.8,v 1.1.1.2 2002/10/01 13:40:03 itojun Exp $
.\" $OpenBSD: ssh-keysign.8,v 1.3 2002/07/03 14:21:05 markus Exp $
.\" $NetBSD: ssh-keysign.8,v 1.1.1.3 2003/04/03 05:57:37 itojun Exp $
.\" $OpenBSD: ssh-keysign.8,v 1.6 2003/03/28 10:11:43 jmc Exp $
.\"
.\" Copyright (c) 2002 Markus Friedl. All rights reserved.
.\"
@ -40,10 +40,10 @@ required during hostbased authentication with SSH protocol version 2.
.Pp
.Nm
is disabled by default and can only be enabled in the
the global client configuration file
global client configuration file
.Pa /etc/ssh/ssh_config
by setting
.Cm HostbasedAuthentication
.Cm EnableSSHKeysign
to
.Dq yes .
.Pp
@ -63,8 +63,8 @@ Controls whether
is enabled.
.It Pa /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key
These files contain the private parts of the host keys used to
generate the digital signature. They
should be owned by root, readable only by root, and not
generate the digital signature.
They should be owned by root, readable only by root, and not
accessible to others.
Since they are readable only by root,
.Nm

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-keysign.c,v 1.1.1.2 2002/10/01 13:40:03 itojun Exp $ */
/* $NetBSD: ssh-keysign.c,v 1.1.1.3 2003/04/03 05:57:37 itojun Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keysign.c,v 1.7 2002/07/03 14:21:05 markus Exp $");
RCSID("$OpenBSD: ssh-keysign.c,v 1.11 2003/04/02 14:36:26 markus Exp $");
#include <openssl/evp.h>
#include <openssl/rand.h>
@ -50,7 +50,7 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
u_int datalen)
{
Buffer b;
Key *key;
Key *key = NULL;
u_char *pkblob;
u_int blen, len;
char *pkalg, *p;
@ -159,8 +159,8 @@ main(int argc, char **argv)
initialize_options(&options);
(void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options);
fill_default_options(&options);
if (options.hostbased_authentication != 1)
fatal("Hostbased authentication not enabled in %s",
if (options.enable_ssh_keysign != 1)
fatal("ssh-keysign not enabled in %s",
_PATH_HOST_CONFIG_FILE);
if (key_fd[0] == -1 && key_fd[1] == -1)
@ -183,13 +183,6 @@ main(int argc, char **argv)
keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC,
NULL, NULL);
close(key_fd[i]);
if (keys[i] != NULL && keys[i]->type == KEY_RSA) {
if (RSA_blinding_on(keys[i]->rsa, NULL) != 1) {
error("RSA_blinding_on failed");
key_free(keys[i]);
keys[i] = NULL;
}
}
if (keys[i] != NULL)
found = 1;
}
@ -197,8 +190,8 @@ main(int argc, char **argv)
fatal("no hostkey found");
buffer_init(&b);
if (msg_recv(STDIN_FILENO, &b) < 0)
fatal("msg_recv failed");
if (ssh_msg_recv(STDIN_FILENO, &b) < 0)
fatal("ssh_msg_recv failed");
if (buffer_get_char(&b) != version)
fatal("bad version");
fd = buffer_get_int(&b);
@ -230,7 +223,7 @@ main(int argc, char **argv)
/* send reply */
buffer_clear(&b);
buffer_put_string(&b, signature, slen);
msg_send(STDOUT_FILENO, version, &b);
ssh_msg_send(STDOUT_FILENO, version, &b);
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-rsa.c,v 1.1.1.12 2002/10/01 13:40:00 itojun Exp $ */
/* $NetBSD: ssh-rsa.c,v 1.1.1.13 2003/04/03 05:57:37 itojun Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-rsa.c,v 1.26 2002/08/27 17:13:56 stevesk Exp $");
RCSID("$OpenBSD: ssh-rsa.c,v 1.28 2003/02/12 09:33:04 markus Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@ -34,11 +34,10 @@ RCSID("$OpenBSD: ssh-rsa.c,v 1.26 2002/08/27 17:13:56 stevesk Exp $");
#include "buffer.h"
#include "bufaux.h"
#include "key.h"
#include "ssh-rsa.h"
#include "compat.h"
#include "ssh.h"
static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int , RSA *);
static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
int

36
crypto/dist/ssh/ssh.1 vendored
View File

@ -1,4 +1,4 @@
.\" $NetBSD: ssh.1,v 1.1.1.16 2002/10/01 13:40:01 itojun Exp $
.\" $NetBSD: ssh.1,v 1.1.1.17 2003/04/03 05:57:38 itojun Exp $
.\" -*- nroff -*-
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh.1,v 1.167 2002/09/27 15:46:21 stevesk Exp $
.\" $OpenBSD: ssh.1,v 1.168 2003/03/28 10:11:43 jmc Exp $
.Dd September 25, 1999
.Dt SSH 1
.Os
@ -49,6 +49,7 @@
.Op Ar command
.Pp
.Nm ssh
.Bk -words
.Op Fl afgknqstvxACNTX1246
.Op Fl b Ar bind_address
.Op Fl c Ar cipher_spec
@ -67,6 +68,8 @@
.Sm on
.Xc
.Oc
.Ek
.Bk -words
.Oo Fl R Xo
.Sm off
.Ar port :
@ -78,6 +81,7 @@
.Op Fl D Ar port
.Ar hostname | user@hostname
.Op Ar command
.Ek
.Sh DESCRIPTION
.Nm
(SSH client) is a program for logging into a remote machine and for
@ -362,7 +366,7 @@ variable is set to
.Fl A
and
.Fl a
options described later) and
options described later) and
the user is using an authentication agent, the connection to the agent
is automatically forwarded to the remote side.
.Pp
@ -404,10 +408,11 @@ Disables forwarding of the authentication agent connection.
Enables forwarding of the authentication agent connection.
This can also be specified on a per-host basis in a configuration file.
.Pp
Agent forwarding should be enabled with caution. Users with the
ability to bypass file permissions on the remote host (for the agent's
Unix-domain socket) can access the local agent through the forwarded
connection. An attacker cannot obtain key material from the agent,
Agent forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the agent's Unix-domain socket)
can access the local agent through the forwarded connection.
An attacker cannot obtain key material from the agent,
however they can perform operations on the keys that enable them to
authenticate using the identities loaded into the agent.
.It Fl b Ar bind_address
@ -429,8 +434,8 @@ is only supported in the
client for interoperability with legacy protocol 1 implementations
that do not support the
.Ar 3des
cipher. Its use is strongly discouraged due to cryptographic
weaknesses.
cipher.
Its use is strongly discouraged due to cryptographic weaknesses.
.It Fl c Ar cipher_spec
Additionally, for protocol version 2 a comma-separated list of ciphers can
be specified in order of preference.
@ -567,11 +572,11 @@ Disables X11 forwarding.
Enables X11 forwarding.
This can also be specified on a per-host basis in a configuration file.
.Pp
X11 forwarding should be enabled with caution. Users with the ability
to bypass file permissions on the remote host (for the user's X
authorization database) can access the local X11 display through the
forwarded connection. An attacker may then be able to perform
activities such as keystroke monitoring.
X11 forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the user's X authorization database)
can access the local X11 display through the forwarded connection.
An attacker may then be able to perform activities such as keystroke monitoring.
.It Fl C
Requests compression of all data (including stdin, stdout, stderr, and
data for forwarded X11 and TCP/IP connections).
@ -638,7 +643,8 @@ This works by allocating a socket to listen to
on the local side, and whenever a connection is made to this port, the
connection is forwarded over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine. Currently the SOCKS4 protocol is supported, and
remote machine.
Currently the SOCKS4 protocol is supported, and
.Nm
will act as a SOCKS4 server.
Only root can forward privileged ports.

21
crypto/dist/ssh/ssh.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh.c,v 1.1.1.17 2002/10/01 13:40:01 itojun Exp $ */
/* $NetBSD: ssh.c,v 1.1.1.18 2003/04/03 05:57:39 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -41,7 +41,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh.c,v 1.186 2002/09/19 01:58:18 djm Exp $");
RCSID("$OpenBSD: ssh.c,v 1.190 2003/02/06 09:27:29 markus Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@ -483,9 +483,9 @@ again:
av += optind;
if (ac > 0 && !host && **av != '-') {
if (strchr(*av, '@')) {
if (strrchr(*av, '@')) {
p = xstrdup(*av);
cp = strchr(p, '@');
cp = strrchr(p, '@');
if (cp == NULL || cp == p)
usage();
options.user = p;
@ -493,12 +493,11 @@ again:
host = ++cp;
} else
host = *av;
ac--, av++;
if (ac > 0) {
optind = 0;
optreset = 1;
if (ac > 1) {
optind = optreset = 1;
goto again;
}
ac--, av++;
}
/* Check that we got a host name. */
@ -588,6 +587,10 @@ again:
if (options.hostname != NULL)
host = options.hostname;
if (options.proxy_command != NULL &&
strcmp(options.proxy_command, "none") == 0)
options.proxy_command = NULL;
/* Disable rhosts authentication if not running as root. */
if (original_effective_uid != 0 || !options.use_privileged_port) {
debug("Rhosts Authentication disabled, "
@ -1003,7 +1006,7 @@ ssh_session2_setup(int id, void *arg)
int interactive = 0;
struct termios tio;
debug("ssh_session2_setup: id %d", id);
debug2("ssh_session2_setup: id %d", id);
if (tty_flag) {
struct winsize ws;

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ssh_config.5,v 1.1.1.2 2002/10/01 13:40:03 itojun Exp $
.\" $NetBSD: ssh_config.5,v 1.1.1.3 2003/04/03 05:57:39 itojun Exp $
.\" -*- nroff -*-
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh_config.5,v 1.5 2002/08/29 22:54:10 stevesk Exp $
.\" $OpenBSD: ssh_config.5,v 1.7 2003/03/28 10:11:43 jmc Exp $
.Dd September 25, 1999
.Dt SSH_CONFIG 5
.Os
@ -177,8 +177,8 @@ is only supported in the
client for interoperability with legacy protocol 1 implementations
that do not support the
.Ar 3des
cipher. Its use is strongly discouraged due to cryptographic
weaknesses.
cipher.
Its use is strongly discouraged due to cryptographic weaknesses.
The default is
.Dq 3des .
.It Cm Ciphers
@ -194,7 +194,8 @@ The default is
.It Cm ClearAllForwardings
Specifies that all local, remote and dynamic port forwardings
specified in the configuration files or on the command line be
cleared. This option is primarily useful when used from the
cleared.
This option is primarily useful when used from the
.Nm ssh
command line to clear port forwardings set in
configuration files, and is automatically set by
@ -231,13 +232,14 @@ The default is 1.
Specifies that a TCP/IP port on the local machine be forwarded
over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine. The argument must be a port number.
remote machine.
The argument must be a port number.
Currently the SOCKS4 protocol is supported, and
.Nm ssh
will act as a SOCKS4 server.
Multiple forwardings may be specified, and
additional forwardings can be given on the command line. Only
the superuser can forward privileged ports.
additional forwardings can be given on the command line.
Only the superuser can forward privileged ports.
.It Cm EscapeChar
Sets the escape character (default:
.Ql ~ ) .
@ -260,10 +262,11 @@ or
The default is
.Dq no .
.Pp
Agent forwarding should be enabled with caution. Users with the
ability to bypass file permissions on the remote host (for the agent's
Unix-domain socket) can access the local agent through the forwarded
connection. An attacker cannot obtain key material from the agent,
Agent forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the agent's Unix-domain socket)
can access the local agent through the forwarded connection.
An attacker cannot obtain key material from the agent,
however they can perform operations on the keys that enable them to
authenticate using the identities loaded into the agent.
.It Cm ForwardX11
@ -278,18 +281,18 @@ or
The default is
.Dq no .
.Pp
X11 forwarding should be enabled with caution. Users with the ability
to bypass file permissions on the remote host (for the user's X
authorization database) can access the local X11 display through the
forwarded connection. An attacker may then be able to perform
activities such as keystroke monitoring.
X11 forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the user's X authorization database)
can access the local X11 display through the forwarded connection.
An attacker may then be able to perform activities such as keystroke monitoring.
.It Cm GatewayPorts
Specifies whether remote hosts are allowed to connect to local
forwarded ports.
By default,
.Nm ssh
binds local port forwardings to the loopback address. This
prevents other remote hosts from connecting to forwarded ports.
binds local port forwardings to the loopback address.
This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts
can be used to specify that
.Nm ssh
@ -396,8 +399,9 @@ Gives the verbosity level that is used when logging messages from
.Nm ssh .
The possible values are:
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2
and DEBUG3 each specify higher levels of verbose output.
The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of verbose output.
.It Cm MACs
Specifies the MAC (message authentication code) algorithms
in order of preference.
@ -475,6 +479,9 @@ somewhere.
Host key management will be done using the
HostName of the host being connected (defaulting to the name typed by
the user).
Setting the command to
.Dq none
disables this option entirely.
Note that
.Cm CheckHostIP
is not available for connects with a proxy command.

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshconnect.c,v 1.1.1.16 2002/10/01 13:40:01 itojun Exp $ */
/* $NetBSD: sshconnect.c,v 1.1.1.17 2003/04/03 05:57:40 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect.c,v 1.135 2002/09/19 01:58:18 djm Exp $");
RCSID("$OpenBSD: sshconnect.c,v 1.137 2002/11/21 23:03:51 deraadt Exp $");
#include <openssl/bn.h>
@ -244,7 +244,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
*/
int full_failure = 1;
debug("ssh_connect: needpriv %d", needpriv);
debug2("ssh_connect: needpriv %d", needpriv);
/* Get default port if port has not been set. */
if (port == 0) {
@ -642,10 +642,10 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
"%s key fingerprint is %s.\n"
"Are you sure you want to continue connecting "
"(yes/no)? ",
host, ip,
has_keys ? ",\nbut keys of different type are already "
"known for this host." : ".",
type, fp);
host, ip,
has_keys ? ",\nbut keys of different type are already "
"known for this host." : ".",
type, fp);
xfree(fp);
if (!confirm(msg))
goto fail;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshconnect2.c,v 1.1.1.18 2002/10/01 13:40:01 itojun Exp $ */
/* $NetBSD: sshconnect2.c,v 1.1.1.19 2003/04/03 05:57:42 itojun Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect2.c,v 1.107 2002/07/01 19:48:46 markus Exp $");
RCSID("$OpenBSD: sshconnect2.c,v 1.115 2003/04/02 09:48:07 markus Exp $");
#include "ssh.h"
#include "ssh2.h"
@ -109,8 +109,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
options.hostkeyalgorithms;
if (options.rekey_limit)
packet_set_rekey_limit(options.rekey_limit);
/* start key exchange */
kex = kex_setup(myproposal);
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
kex->client_version_string=client_version_string;
kex->server_version_string=server_version_string;
kex->verify_host_key=&verify_host_key_callback;
@ -129,7 +134,6 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
packet_send();
packet_write_wait();
#endif
debug("done: ssh_kex2.");
}
/*
@ -225,24 +229,23 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1;
debug("send SSH2_MSG_SERVICE_REQUEST");
packet_start(SSH2_MSG_SERVICE_REQUEST);
packet_put_cstring("ssh-userauth");
packet_send();
debug("SSH2_MSG_SERVICE_REQUEST sent");
packet_write_wait();
type = packet_read();
if (type != SSH2_MSG_SERVICE_ACCEPT) {
fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
}
if (type != SSH2_MSG_SERVICE_ACCEPT)
fatal("Server denied authentication request: %d", type);
if (packet_remaining() > 0) {
char *reply = packet_get_string(NULL);
debug("service_accept: %s", reply);
debug2("service_accept: %s", reply);
xfree(reply);
} else {
debug("buggy server: service_accept w/o service");
debug2("buggy server: service_accept w/o service");
}
packet_check_eom();
debug("got SSH2_MSG_SERVICE_ACCEPT");
debug("SSH2_MSG_SERVICE_ACCEPT received");
if (options.preferred_authentications == NULL)
options.preferred_authentications = authmethods_get();
@ -274,7 +277,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
if (authctxt.agent != NULL)
ssh_close_authentication_connection(authctxt.agent);
debug("ssh-userauth2 successful: method %s", authctxt.method->name);
debug("Authentication succeeded (%s).", authctxt.method->name);
}
void
userauth(Authctxt *authctxt, char *authlist)
@ -348,7 +351,7 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
if (partial != 0)
log("Authenticated with partial success.");
debug("authentications that can continue: %s", authlist);
debug("Authentications that can continue: %s", authlist);
clear_auth_state(authctxt);
userauth(authctxt, authlist);
@ -380,7 +383,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
}
packet_check_eom();
debug("input_userauth_pk_ok: pkalg %s blen %u lastkey %p hint %d",
debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
do {
@ -765,7 +768,7 @@ userauth_pubkey_agent(Authctxt *authctxt)
if (k == NULL) {
debug2("userauth_pubkey_agent: no more keys");
} else {
debug("userauth_pubkey_agent: testing agent key %s", comment);
debug("Offering agent key: %s", comment);
xfree(comment);
ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
if (ret == 0)
@ -793,7 +796,7 @@ userauth_pubkey(Authctxt *authctxt)
key = options.identity_keys[idx];
filename = options.identity_files[idx];
if (key == NULL) {
debug("try privkey: %s", filename);
debug("Trying private key: %s", filename);
key = load_identity_file(filename);
if (key != NULL) {
sent = sign_and_send_pubkey(authctxt, key,
@ -801,7 +804,7 @@ userauth_pubkey(Authctxt *authctxt)
key_free(key);
}
} else if (key->type != KEY_RSA1) {
debug("try pubkey: %s", filename);
debug("Offering public key: %s", filename);
sent = send_pubkey_test(authctxt, key,
identity_sign_cb, idx);
}
@ -907,7 +910,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
pid_t pid;
int to[2], from[2], status, version = 2;
debug("ssh_keysign called");
debug2("ssh_keysign called");
if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
error("ssh_keysign: no installed: %s", strerror(errno));
@ -948,9 +951,9 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
buffer_init(&b);
buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
buffer_put_string(&b, data, datalen);
msg_send(to[1], version, &b);
ssh_msg_send(to[1], version, &b);
if (msg_recv(from[0], &b) < 0) {
if (ssh_msg_recv(from[0], &b) < 0) {
error("ssh_keysign: no reply");
buffer_clear(&b);
return -1;
@ -996,7 +999,7 @@ userauth_hostbased(Authctxt *authctxt)
}
}
if (!found) {
debug("userauth_hostbased: no more client hostkeys");
debug("No more client hostkeys for hostbased authentication.");
return 0;
}
if (key_to_blob(private, &blob, &blen) == 0) {
@ -1015,6 +1018,7 @@ userauth_hostbased(Authctxt *authctxt)
strlcpy(chost, p, len);
strlcat(chost, ".", len);
debug2("userauth_hostbased: chost %s", chost);
xfree(p);
service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
authctxt->service;
@ -1110,7 +1114,6 @@ static char *preferred = NULL;
static Authmethod *
authmethod_get(char *authlist)
{
char *name = NULL;
u_int next;
@ -1131,7 +1134,7 @@ authmethod_get(char *authlist)
for (;;) {
if ((name = match_list(preferred, supported, &next)) == NULL) {
debug("no more auth methods to try");
debug("No more authentication methods to try.");
current = NULL;
return NULL;
}
@ -1141,7 +1144,7 @@ authmethod_get(char *authlist)
if ((current = authmethod_lookup(name)) != NULL &&
authmethod_is_enabled(current)) {
debug3("authmethod_is_enabled %s", name);
debug("next auth method to try is %s", name);
debug("Next authentication method: %s", name);
return current;
}
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sshd.8,v 1.1.1.18 2002/10/01 13:40:02 itojun Exp $
.\" $NetBSD: sshd.8,v 1.1.1.19 2003/04/03 05:57:43 itojun Exp $
.\" -*- nroff -*-
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd.8,v 1.193 2002/09/24 20:59:44 todd Exp $
.\" $OpenBSD: sshd.8,v 1.194 2003/01/31 21:54:40 jmc Exp $
.Dd September 25, 1999
.Dt SSHD 8
.Os
@ -44,6 +44,7 @@
.Nd OpenSSH SSH daemon
.Sh SYNOPSIS
.Nm sshd
.Bk -words
.Op Fl deiqtD46
.Op Fl b Ar bits
.Op Fl f Ar config_file
@ -53,6 +54,7 @@
.Op Fl o Ar option
.Op Fl p Ar port
.Op Fl u Ar len
.Ek
.Sh DESCRIPTION
.Nm
(SSH Daemon) is the daemon program for
@ -76,7 +78,7 @@ This implementation of
.Nm
supports both SSH protocol version 1 and 2 simultaneously.
.Nm
works as follows.
works as follows:
.Pp
.Ss SSH protocol version 1
.Pp
@ -87,7 +89,7 @@ the daemon starts, it generates a server RSA key (normally 768 bits).
This key is normally regenerated every hour if it has been used, and
is never stored on disk.
.Pp
Whenever a client connects the daemon responds with its public
Whenever a client connects, the daemon responds with its public
host and server keys.
The client compares the
RSA host key against its own database to verify that it has not changed.
@ -120,7 +122,7 @@ System security is not improved unless
.Nm rshd ,
.Nm rlogind ,
and
.Xr rexecd
.Nm rexecd
are disabled (thus completely disabling
.Xr rlogin
and
@ -190,7 +192,9 @@ The server sends verbose debug output to the system
log, and does not put itself in the background.
The server also will not fork and will only process one connection.
This option is only intended for debugging for the server.
Multiple -d options increase the debugging level.
Multiple
.Fl d
options increase the debugging level.
Maximum is 3.
.It Fl e
When this option is specified,
@ -226,7 +230,8 @@ the different protocol versions and host key algorithms.
.It Fl i
Specifies that
.Nm
is being run from inetd.
is being run from
.Xr inetd 8 .
.Nm
is normally not run
from inetd because it needs to generate the server key before it can
@ -283,7 +288,7 @@ should be put into the
.Pa utmp
file.
.Fl u0
is also be used to prevent
may also be used to prevent
.Nm
from making DNS requests unless the authentication
mechanism or configuration requires it.
@ -447,7 +452,7 @@ authentication.
The command supplied by the user (if any) is ignored.
The command is run on a pty if the client requests a pty;
otherwise it is run without a tty.
If a 8-bit clean channel is required,
If an 8-bit clean channel is required,
one must not request a pty or should specify
.Cm no-pty .
A quote may be included in the command by quoting it with a backslash.
@ -507,7 +512,7 @@ command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hu
permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23.\|.\|.\|2323
.Sh SSH_KNOWN_HOSTS FILE FORMAT
The
.Pa /etc/ssh/ssh_known_hosts ,
.Pa /etc/ssh/ssh_known_hosts
and
.Pa $HOME/.ssh/known_hosts
files contain host public keys for all known hosts.
@ -628,7 +633,7 @@ These files should be writable only by root/the owner.
.Pa /etc/ssh/ssh_known_hosts
should be world-readable, and
.Pa $HOME/.ssh/known_hosts
can but need not be world-readable.
can, but need not be, world-readable.
.It Pa /etc/nologin
If this file exists,
.Nm
@ -645,7 +650,7 @@ Further details are described in
This file contains host-username pairs, separated by a space, one per
line.
The given user on the corresponding host is permitted to log in
without password.
without a password.
The same file is used by rlogind and rshd.
The file must
be writable only by the user; it is recommended that it not be
@ -714,7 +719,9 @@ controlled via the
.Cm PermitUserEnvironment
option.
.It Pa $HOME/.ssh/rc
If this file exists, it is run with /bin/sh after reading the
If this file exists, it is run with
.Pa /bin/sh
after reading the
environment files but before starting the user's shell or command.
It must not produce any output on stdout; stderr must be used
instead.

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshd.c,v 1.1.1.19 2002/10/01 13:40:02 itojun Exp $ */
/* $NetBSD: sshd.c,v 1.1.1.20 2003/04/03 05:57:45 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -43,7 +43,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshd.c,v 1.260 2002/09/27 10:42:09 mickey Exp $");
RCSID("$OpenBSD: sshd.c,v 1.263 2003/02/16 17:09:57 markus Exp $");
#include <openssl/dh.h>
#include <openssl/bn.h>
@ -190,8 +190,8 @@ int *startup_pipes = NULL;
int startup_pipe; /* in child */
/* variables used for privilege separation */
extern struct monitor *pmonitor;
extern int use_privsep;
int use_privsep;
struct monitor *pmonitor;
/* Prototypes for various functions defined later in this file. */
void destroy_sensitive_data(void);
@ -921,7 +921,7 @@ main(int ac, char **av)
SYSLOG_LEVEL_INFO : options.log_level,
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
SYSLOG_FACILITY_AUTH : options.log_facility,
!inetd_flag);
log_stderr || !inetd_flag);
/* Read server configuration options from the configuration file. */
read_server_config(&options, config_file_name);
@ -1019,8 +1019,8 @@ main(int ac, char **av)
fatal("Missing privilege separation directory: %s",
_PATH_PRIVSEP_CHROOT_DIR);
if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)
fatal("Bad owner or mode for %s",
_PATH_PRIVSEP_CHROOT_DIR);
fatal("%s must be owned by root and not group or "
"world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
}
/* Configuration looks good, so exit if in test mode. */
@ -1747,6 +1747,8 @@ do_ssh2_kex(void)
/* start key exchange */
kex = kex_setup(myproposal);
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
kex->server = 1;
kex->client_version_string=client_version_string;
kex->server_version_string=server_version_string;

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sshd_config.5,v 1.1.1.2 2002/10/01 13:40:03 itojun Exp $
.\" $NetBSD: sshd_config.5,v 1.1.1.3 2003/04/03 05:57:45 itojun Exp $
.\" -*- nroff -*-
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.13 2002/09/16 20:12:11 stevesk Exp $
.\" $OpenBSD: sshd_config.5,v 1.15 2003/03/28 10:11:43 jmc Exp $
.Dd September 25, 1999
.Dt SSHD_CONFIG 5
.Os
@ -90,7 +90,7 @@ own forwarders.
.It Cm AllowUsers
This keyword can be followed by a list of user name patterns, separated
by spaces.
If specified, login is allowed only for users names that
If specified, login is allowed only for user names that
match one of the patterns.
.Ql \&*
and
@ -212,8 +212,8 @@ Specifies whether remote hosts are allowed to connect to ports
forwarded for the client.
By default,
.Nm sshd
binds remote port forwardings to the loopback address. This
prevents other remote hosts from connecting to forwarded ports.
binds remote port forwardings to the loopback address.
This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts
can be used to specify that
.Nm sshd
@ -371,7 +371,8 @@ is not specified,
will listen on the address and all prior
.Cm Port
options specified. The default is to listen on all local
addresses. Multiple
addresses.
Multiple
.Cm ListenAddress
options are permitted. Additionally, any
.Cm Port
@ -386,10 +387,10 @@ Gives the verbosity level that is used when logging messages from
.Nm sshd .
The possible values are:
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2
and DEBUG3 each specify higher levels of debugging output.
Logging with a DEBUG level violates the privacy of users
and is not recommended.
The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
Logging with a DEBUG level violates the privacy of users and is not recommended.
.It Cm MACs
Specifies the available MAC (message authentication code) algorithms.
The MAC algorithm is used in protocol version 2
@ -594,16 +595,18 @@ will be disabled because
.Xr login 1
does not know how to handle
.Xr xauth 1
cookies. If
cookies.
If
.Cm UsePrivilegeSeparation
is specified, it will be disabled after authentication.
.It Cm UsePrivilegeSeparation
Specifies whether
.Nm sshd
separates privileges by creating an unprivileged child process
to deal with incoming network traffic. After successful authentication,
another process will be created that has the privilege of the authenticated
user. The goal of privilege separation is to prevent privilege
to deal with incoming network traffic.
After successful authentication, another process will be created that has
the privilege of the authenticated user.
The goal of privilege separation is to prevent privilege
escalation by containing any corruption within the unprivileged processes.
The default is
.Dq yes .
@ -661,7 +664,8 @@ is enabled.
Specifies whether
.Nm sshd
should bind the X11 forwarding server to the loopback address or to
the wildcard address. By default,
the wildcard address.
By default,
.Nm sshd
binds the forwarding server to the loopback address and sets the
hostname part of the

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshpty.c,v 1.1.1.6 2002/06/26 14:03:16 itojun Exp $ */
/* $NetBSD: sshpty.c,v 1.1.1.7 2003/04/03 05:57:46 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshpty.c,v 1.7 2002/06/24 17:57:20 deraadt Exp $");
RCSID("$OpenBSD: sshpty.c,v 1.8 2003/02/03 08:56:16 markus Exp $");
#include <util.h>
#include "sshpty.h"
@ -276,7 +276,7 @@ pty_setowner(struct passwd *pw, const char *ttyname)
if (chown(ttyname, pw->pw_uid, gid) < 0) {
if (errno == EROFS &&
(st.st_uid == pw->pw_uid || st.st_uid == 0))
error("chown(%.100s, %u, %u) failed: %.100s",
debug("chown(%.100s, %u, %u) failed: %.100s",
ttyname, (u_int)pw->pw_uid, (u_int)gid,
strerror(errno));
else
@ -290,7 +290,7 @@ pty_setowner(struct passwd *pw, const char *ttyname)
if (chmod(ttyname, mode) < 0) {
if (errno == EROFS &&
(st.st_mode & (S_IRGRP | S_IROTH)) == 0)
error("chmod(%.100s, 0%o) failed: %.100s",
debug("chmod(%.100s, 0%o) failed: %.100s",
ttyname, mode, strerror(errno));
else
fatal("chmod(%.100s, 0%o) failed: %.100s",

View File

@ -1,4 +1,4 @@
/* $NetBSD: version.h,v 1.1.1.19 2002/10/01 13:40:02 itojun Exp $ */
/* $OpenBSD: version.h,v 1.35 2002/10/01 13:24:50 markus Exp $ */
/* $NetBSD: version.h,v 1.1.1.20 2003/04/03 05:57:46 itojun Exp $ */
/* $OpenBSD: version.h,v 1.37 2003/04/01 10:56:46 markus Exp $ */
#define SSH_VERSION "OpenSSH_3.5"
#define SSH_VERSION "OpenSSH_3.6.1"