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:
parent
d0a69bd4ab
commit
14012871d8
|
@ -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:
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 .
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue