NetBSD Secure Shell, based on OpenSSH 2.3.0 around 1/5/2001
This commit is contained in:
parent
6f0dfa5049
commit
bfbf0e0d31
6
crypto/dist/ssh/atomicio.c
vendored
6
crypto/dist/ssh/atomicio.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: atomicio.c,v 1.1.1.1 2000/09/28 22:09:38 thorpej Exp $ */
|
||||
/* $NetBSD: atomicio.c,v 1.1.1.2 2001/01/14 04:49:56 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995,1999 Theo de Raadt
|
||||
@ -25,11 +25,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: atomicio.c,v 1.5 2000/09/07 20:27:49 deraadt Exp */
|
||||
/* from OpenBSD: atomicio.c,v 1.7 2000/10/18 18:04:02 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: atomicio.c,v 1.1.1.1 2000/09/28 22:09:38 thorpej Exp $");
|
||||
__RCSID("$NetBSD: atomicio.c,v 1.1.1.2 2001/01/14 04:49:56 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
22
crypto/dist/ssh/auth-krb4.c
vendored
22
crypto/dist/ssh/auth-krb4.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth-krb4.c,v 1.1.1.1 2000/09/28 22:09:38 thorpej Exp $ */
|
||||
/* $NetBSD: auth-krb4.c,v 1.1.1.2 2001/01/14 04:49:57 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Dug Song. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from: OpenBSD: auth-krb4.c,v 1.18 2000/09/07 20:27:49 deraadt Exp */
|
||||
/* from: OpenBSD: auth-krb4.c,v 1.20 2000/12/19 23:17:54 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: auth-krb4.c,v 1.1.1.1 2000/09/28 22:09:38 thorpej Exp $");
|
||||
__RCSID("$NetBSD: auth-krb4.c,v 1.1.1.2 2001/01/14 04:49:57 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -53,7 +53,7 @@ auth_krb4_password(struct passwd * pw, const char *password)
|
||||
AUTH_DAT adata;
|
||||
KTEXT_ST tkt;
|
||||
struct hostent *hp;
|
||||
unsigned long faddr;
|
||||
u_long faddr;
|
||||
char localhost[MAXHOSTNAMELEN];
|
||||
char phost[INST_SZ];
|
||||
char realm[REALM_SZ];
|
||||
@ -287,6 +287,8 @@ auth_kerberos_tgt(struct passwd *pw, const char *string)
|
||||
{
|
||||
CREDENTIALS creds;
|
||||
|
||||
if (pw == NULL)
|
||||
goto auth_kerberos_tgt_failure;
|
||||
if (!radix_to_creds(string, &creds)) {
|
||||
log("Protocol error decoding Kerberos V4 tgt");
|
||||
packet_send_debug("Protocol error decoding Kerberos V4 tgt");
|
||||
@ -341,8 +343,16 @@ int
|
||||
auth_afs_token(struct passwd *pw, const char *token_string)
|
||||
{
|
||||
CREDENTIALS creds;
|
||||
uid_t uid = pw->pw_uid;
|
||||
uid_t uid;
|
||||
|
||||
if (pw == NULL) {
|
||||
/* XXX fake protocol error */
|
||||
packet_send_debug("Protocol error decoding AFS token");
|
||||
packet_start(SSH_SMSG_FAILURE);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
return 0;
|
||||
}
|
||||
if (!radix_to_creds(token_string, &creds)) {
|
||||
log("Protocol error decoding AFS token");
|
||||
packet_send_debug("Protocol error decoding AFS token");
|
||||
@ -356,6 +366,8 @@ auth_afs_token(struct passwd *pw, const char *token_string)
|
||||
|
||||
if (strncmp(creds.pname, "AFS ID ", 7) == 0)
|
||||
uid = atoi(creds.pname + 7);
|
||||
else
|
||||
uid = pw->pw_uid;
|
||||
|
||||
if (kafs_settoken(creds.realm, uid, &creds)) {
|
||||
log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm,
|
||||
|
68
crypto/dist/ssh/auth-options.c
vendored
68
crypto/dist/ssh/auth-options.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth-options.c,v 1.1.1.1 2000/09/28 22:09:39 thorpej Exp $ */
|
||||
/* $NetBSD: auth-options.c,v 1.1.1.2 2001/01/14 04:49:57 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -15,11 +15,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: auth-options.c,v 1.4 2000/09/07 21:13:36 markus Exp */
|
||||
/* from OpenBSD: auth-options.c,v 1.7 2000/12/19 23:17:54 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: auth-options.c,v 1.1.1.1 2000/09/28 22:09:39 thorpej Exp $");
|
||||
__RCSID("$NetBSD: auth-options.c,v 1.1.1.2 2001/01/14 04:49:57 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -43,44 +43,67 @@ char *forced_command = NULL;
|
||||
/* "environment=" options. */
|
||||
struct envstring *custom_environment = NULL;
|
||||
|
||||
void
|
||||
auth_clear_options(void)
|
||||
{
|
||||
no_agent_forwarding_flag = 0;
|
||||
no_port_forwarding_flag = 0;
|
||||
no_pty_flag = 0;
|
||||
no_x11_forwarding_flag = 0;
|
||||
while (custom_environment) {
|
||||
struct envstring *ce = custom_environment;
|
||||
custom_environment = ce->next;
|
||||
xfree(ce->s);
|
||||
xfree(ce);
|
||||
}
|
||||
if (forced_command) {
|
||||
xfree(forced_command);
|
||||
forced_command = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* return 1 if access is granted, 0 if not. side effect: sets key option flags */
|
||||
int
|
||||
auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
|
||||
auth_parse_options(struct passwd *pw, char *options, u_long linenum)
|
||||
{
|
||||
const char *cp;
|
||||
if (!options)
|
||||
return 1;
|
||||
|
||||
/* reset options */
|
||||
auth_clear_options();
|
||||
|
||||
while (*options && *options != ' ' && *options != '\t') {
|
||||
cp = "no-port-forwarding";
|
||||
if (strncmp(options, cp, strlen(cp)) == 0) {
|
||||
if (strncasecmp(options, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("Port forwarding disabled.");
|
||||
no_port_forwarding_flag = 1;
|
||||
options += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-agent-forwarding";
|
||||
if (strncmp(options, cp, strlen(cp)) == 0) {
|
||||
if (strncasecmp(options, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("Agent forwarding disabled.");
|
||||
no_agent_forwarding_flag = 1;
|
||||
options += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-X11-forwarding";
|
||||
if (strncmp(options, cp, strlen(cp)) == 0) {
|
||||
if (strncasecmp(options, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("X11 forwarding disabled.");
|
||||
no_x11_forwarding_flag = 1;
|
||||
options += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-pty";
|
||||
if (strncmp(options, cp, strlen(cp)) == 0) {
|
||||
if (strncasecmp(options, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("Pty allocation disabled.");
|
||||
no_pty_flag = 1;
|
||||
options += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "command=\"";
|
||||
if (strncmp(options, cp, strlen(cp)) == 0) {
|
||||
if (strncasecmp(options, cp, strlen(cp)) == 0) {
|
||||
int i;
|
||||
options += strlen(cp);
|
||||
forced_command = xmalloc(strlen(options) + 1);
|
||||
@ -97,9 +120,9 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
|
||||
}
|
||||
if (!*options) {
|
||||
debug("%.100s, line %lu: missing end quote",
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
packet_send_debug("%.100s, line %lu: missing end quote",
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
continue;
|
||||
}
|
||||
forced_command[i] = 0;
|
||||
@ -108,7 +131,7 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
|
||||
goto next_option;
|
||||
}
|
||||
cp = "environment=\"";
|
||||
if (strncmp(options, cp, strlen(cp)) == 0) {
|
||||
if (strncasecmp(options, cp, strlen(cp)) == 0) {
|
||||
int i;
|
||||
char *s;
|
||||
struct envstring *new_envstring;
|
||||
@ -127,9 +150,9 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
|
||||
}
|
||||
if (!*options) {
|
||||
debug("%.100s, line %lu: missing end quote",
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
packet_send_debug("%.100s, line %lu: missing end quote",
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
_PATH_SSH_USER_PERMITTED_KEYS, linenum);
|
||||
continue;
|
||||
}
|
||||
s[i] = 0;
|
||||
@ -143,7 +166,7 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
|
||||
goto next_option;
|
||||
}
|
||||
cp = "from=\"";
|
||||
if (strncmp(options, cp, strlen(cp)) == 0) {
|
||||
if (strncasecmp(options, cp, strlen(cp)) == 0) {
|
||||
int mname, mip;
|
||||
char *patterns = xmalloc(strlen(options) + 1);
|
||||
int i;
|
||||
@ -185,21 +208,6 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
|
||||
get_remote_ipaddr());
|
||||
packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
|
||||
get_canonical_hostname());
|
||||
/* key invalid for this host, reset flags */
|
||||
no_agent_forwarding_flag = 0;
|
||||
no_port_forwarding_flag = 0;
|
||||
no_pty_flag = 0;
|
||||
no_x11_forwarding_flag = 0;
|
||||
while (custom_environment) {
|
||||
struct envstring *ce = custom_environment;
|
||||
custom_environment = ce->next;
|
||||
xfree(ce->s);
|
||||
xfree(ce);
|
||||
}
|
||||
if (forced_command) {
|
||||
xfree(forced_command);
|
||||
forced_command = NULL;
|
||||
}
|
||||
/* deny access */
|
||||
return 0;
|
||||
}
|
||||
|
7
crypto/dist/ssh/auth-options.h
vendored
7
crypto/dist/ssh/auth-options.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth-options.h,v 1.1.1.1 2000/09/28 22:09:39 thorpej Exp $ */
|
||||
/* $NetBSD: auth-options.h,v 1.1.1.2 2001/01/14 04:49:57 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -24,5 +24,8 @@ extern char *forced_command;
|
||||
extern struct envstring *custom_environment;
|
||||
|
||||
/* return 1 if access is granted, 0 if not. side effect: sets key option flags */
|
||||
int auth_parse_options(struct passwd *pw, char *options, unsigned long linenum);
|
||||
int auth_parse_options(struct passwd *pw, char *options, u_long linenum);
|
||||
/* reset options flags */
|
||||
void auth_clear_options(void);
|
||||
|
||||
#endif
|
||||
|
8
crypto/dist/ssh/auth-passwd.c
vendored
8
crypto/dist/ssh/auth-passwd.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth-passwd.c,v 1.1.1.1 2000/09/28 22:09:39 thorpej Exp $ */
|
||||
/* $NetBSD: auth-passwd.c,v 1.1.1.2 2001/01/14 04:49:58 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -60,11 +60,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: auth-passwd.c,v 1.17 2000/09/07 20:27:49 deraadt Exp */
|
||||
/* from OpenBSD: auth-passwd.c,v 1.18 2000/10/03 18:03:03 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: auth-passwd.c,v 1.1.1.1 2000/09/28 22:09:39 thorpej Exp $");
|
||||
__RCSID("$NetBSD: auth-passwd.c,v 1.1.1.2 2001/01/14 04:49:58 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -92,7 +92,7 @@ auth_password(struct passwd * pw, const char *password)
|
||||
if (*password == '\0' && options.permit_empty_passwd == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef SKEY
|
||||
#ifdef SKEY_VIA_PASSWD_IS_DISABLED
|
||||
if (options.skey_authentication == 1) {
|
||||
int ret = auth_skey_password(pw, password);
|
||||
if (ret == 1 || ret == 0)
|
||||
|
18
crypto/dist/ssh/auth-rh-rsa.c
vendored
18
crypto/dist/ssh/auth-rh-rsa.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth-rh-rsa.c,v 1.1.1.1 2000/09/28 22:09:39 thorpej Exp $ */
|
||||
/* $NetBSD: auth-rh-rsa.c,v 1.1.1.2 2001/01/14 04:49:58 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -14,11 +14,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: auth-rh-rsa.c,v 1.16 2000/09/07 21:13:36 markus Exp */
|
||||
/* from OpenBSD: auth-rh-rsa.c,v 1.19 2000/12/21 15:10:16 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: auth-rh-rsa.c,v 1.1.1.1 2000/09/28 22:09:39 thorpej Exp $");
|
||||
__RCSID("$NetBSD: auth-rh-rsa.c,v 1.1.1.2 2001/01/14 04:49:58 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -48,9 +48,9 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key
|
||||
HostStatus host_status;
|
||||
Key *client_key, *found;
|
||||
|
||||
debug("Trying rhosts with RSA host authentication for %.100s", client_user);
|
||||
debug("Trying rhosts with RSA host authentication for client user %.100s", client_user);
|
||||
|
||||
if (client_host_key == NULL)
|
||||
if (pw == NULL || client_host_key == NULL)
|
||||
return 0;
|
||||
|
||||
/* Check if we would accept it using rhosts authentication. */
|
||||
@ -62,14 +62,14 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key
|
||||
debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname);
|
||||
|
||||
/* wrap the RSA key into a 'generic' key */
|
||||
client_key = key_new(KEY_RSA);
|
||||
client_key = key_new(KEY_RSA1);
|
||||
BN_copy(client_key->rsa->e, client_host_key->e);
|
||||
BN_copy(client_key->rsa->n, client_host_key->n);
|
||||
found = key_new(KEY_RSA);
|
||||
found = key_new(KEY_RSA1);
|
||||
|
||||
/* Check if we know the host and its host key. */
|
||||
host_status = check_host_in_hostfile(_PATH_SSH_SYSTEM_HOSTFILE, canonical_hostname,
|
||||
client_key, found);
|
||||
client_key, found, NULL);
|
||||
|
||||
/* Check user host file unless ignored. */
|
||||
if (host_status != HOST_OK && !options.ignore_user_known_hosts) {
|
||||
@ -89,7 +89,7 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key
|
||||
/* XXX race between stat and the following open() */
|
||||
temporarily_use_uid(pw->pw_uid);
|
||||
host_status = check_host_in_hostfile(user_hostfile, canonical_hostname,
|
||||
client_key, found);
|
||||
client_key, found, NULL);
|
||||
restore_uid();
|
||||
}
|
||||
xfree(user_hostfile);
|
||||
|
38
crypto/dist/ssh/auth-rsa.c
vendored
38
crypto/dist/ssh/auth-rsa.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth-rsa.c,v 1.1.1.1 2000/09/28 22:09:40 thorpej Exp $ */
|
||||
/* $NetBSD: auth-rsa.c,v 1.1.1.2 2001/01/14 04:49:59 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -15,11 +15,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: auth-rsa.c,v 1.29 2000/09/07 21:13:36 markus Exp */
|
||||
/* from OpenBSD: auth-rsa.c,v 1.34 2000/12/19 23:17:55 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: auth-rsa.c,v 1.1.1.1 2000/09/28 22:09:40 thorpej Exp $");
|
||||
__RCSID("$NetBSD: auth-rsa.c,v 1.1.1.2 2001/01/14 04:49:59 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -38,11 +38,15 @@ __RCSID("$NetBSD: auth-rsa.c,v 1.1.1.1 2000/09/28 22:09:40 thorpej Exp $");
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
/*
|
||||
* Session identifier that is used to bind key exchange and authentication
|
||||
* responses to a particular session.
|
||||
*/
|
||||
extern unsigned char session_id[16];
|
||||
extern u_char session_id[16];
|
||||
|
||||
/*
|
||||
* The .ssh/authorized_keys file contains public keys, one per line, in the
|
||||
@ -65,9 +69,9 @@ auth_rsa_challenge_dialog(RSA *pk)
|
||||
{
|
||||
BIGNUM *challenge, *encrypted_challenge;
|
||||
BN_CTX *ctx;
|
||||
unsigned char buf[32], mdbuf[16], response[16];
|
||||
u_char buf[32], mdbuf[16], response[16];
|
||||
MD5_CTX md;
|
||||
unsigned int i;
|
||||
u_int i;
|
||||
int plen, len;
|
||||
|
||||
encrypted_challenge = BN_new();
|
||||
@ -125,15 +129,18 @@ auth_rsa_challenge_dialog(RSA *pk)
|
||||
int
|
||||
auth_rsa(struct passwd *pw, BIGNUM *client_n)
|
||||
{
|
||||
extern ServerOptions options;
|
||||
char line[8192], file[1024];
|
||||
int authenticated;
|
||||
unsigned int bits;
|
||||
u_int bits;
|
||||
FILE *f;
|
||||
unsigned long linenum = 0;
|
||||
u_long linenum = 0;
|
||||
struct stat st;
|
||||
RSA *pk;
|
||||
|
||||
/* no user given */
|
||||
if (pw == NULL)
|
||||
return 0;
|
||||
|
||||
/* Temporarily use the user's uid. */
|
||||
temporarily_use_uid(pw->pw_uid);
|
||||
|
||||
@ -255,6 +262,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
|
||||
file, linenum, BN_num_bits(pk->n), bits);
|
||||
|
||||
/* We have found the desired key. */
|
||||
/*
|
||||
* If our options do not allow this key to be used,
|
||||
* do not send challenge.
|
||||
*/
|
||||
if (!auth_parse_options(pw, options, linenum))
|
||||
continue;
|
||||
|
||||
/* Perform the challenge-response dialog for this key. */
|
||||
if (!auth_rsa_challenge_dialog(pk)) {
|
||||
@ -271,9 +284,8 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
|
||||
* Break out of the loop if authentication was successful;
|
||||
* otherwise continue searching.
|
||||
*/
|
||||
authenticated = auth_parse_options(pw, options, linenum);
|
||||
if (authenticated)
|
||||
break;
|
||||
authenticated = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Restore the privileged uid. */
|
||||
@ -286,6 +298,8 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
|
||||
|
||||
if (authenticated)
|
||||
packet_send_debug("RSA authentication accepted.");
|
||||
else
|
||||
auth_clear_options();
|
||||
|
||||
/* Return authentication result. */
|
||||
return authenticated;
|
||||
|
7
crypto/dist/ssh/auth.c
vendored
7
crypto/dist/ssh/auth.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth.c,v 1.1.1.1 2000/09/28 22:09:41 thorpej Exp $ */
|
||||
/* $NetBSD: auth.c,v 1.1.1.2 2001/01/14 04:50:00 itojun Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -70,11 +70,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: auth.c,v 1.10 2000/09/07 21:13:36 markus Exp */
|
||||
/* from OpenBSD: auth.c,v 1.11 2000/10/11 20:27:23 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: auth.c,v 1.1.1.1 2000/09/28 22:09:41 thorpej Exp $");
|
||||
__RCSID("$NetBSD: auth.c,v 1.1.1.2 2001/01/14 04:50:00 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -85,7 +85,6 @@ __RCSID("$NetBSD: auth.c,v 1.1.1.1 2000/09/28 22:09:41 thorpej Exp $");
|
||||
#include "pty.h"
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "cipher.h"
|
||||
#include "mpaux.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
|
23
crypto/dist/ssh/auth.h
vendored
23
crypto/dist/ssh/auth.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth.h,v 1.1.1.1 2000/09/28 22:09:41 thorpej Exp $ */
|
||||
/* $NetBSD: auth.h,v 1.1.1.2 2001/01/14 04:50:00 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -22,22 +22,37 @@
|
||||
* 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.
|
||||
*
|
||||
* $OpenBSD: auth.h,v 1.8 2000/12/28 14:25:51 markus Exp $
|
||||
*/
|
||||
|
||||
#ifndef AUTH_H
|
||||
#define AUTH_H
|
||||
|
||||
typedef struct Authctxt Authctxt;
|
||||
struct Authctxt {
|
||||
int success;
|
||||
int valid;
|
||||
int attempt;
|
||||
int failures;
|
||||
char *user;
|
||||
char *service;
|
||||
struct passwd *pw;
|
||||
};
|
||||
|
||||
void do_authentication(void);
|
||||
void do_authentication2(void);
|
||||
|
||||
struct passwd *
|
||||
auth_get_user(void);
|
||||
void userauth_log(Authctxt *authctxt, int authenticated, char *method);
|
||||
void userauth_reply(Authctxt *authctxt, int authenticated);
|
||||
|
||||
int auth2_skey(Authctxt *authctxt);
|
||||
|
||||
int allowed_user(struct passwd *);
|
||||
struct passwd * auth_get_user(void);
|
||||
|
||||
#define AUTH_FAIL_MAX 6
|
||||
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
|
||||
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
|
||||
|
||||
#endif
|
||||
|
||||
|
104
crypto/dist/ssh/auth2-skey.c
vendored
Normal file
104
crypto/dist/ssh/auth2-skey.c
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
#include "includes.h"
|
||||
/* from OpenBSD: auth2-skey.c,v 1.2 2000/12/19 23:17:55 markus Exp */
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "dispatch.h"
|
||||
|
||||
void send_userauth_into_request(Authctxt *authctxt, int echo);
|
||||
void input_userauth_info_response(int type, int plen, void *ctxt);
|
||||
|
||||
/*
|
||||
* try skey authentication, always return -1 (= postponed) since we have to
|
||||
* wait for the s/key response.
|
||||
*/
|
||||
int
|
||||
auth2_skey(Authctxt *authctxt)
|
||||
{
|
||||
send_userauth_into_request(authctxt, 0);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &input_userauth_info_response);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
send_userauth_into_request(Authctxt *authctxt, int echo)
|
||||
{
|
||||
int retval = -1;
|
||||
struct skey skey;
|
||||
char challenge[SKEY_MAX_CHALLENGE];
|
||||
char *fake;
|
||||
|
||||
if (authctxt->user == NULL)
|
||||
fatal("send_userauth_into_request: internal error: no user");
|
||||
|
||||
/* get skey challenge */
|
||||
if (authctxt->valid)
|
||||
retval = skeychallenge(&skey, authctxt->user, challenge, sizeof(challenge));
|
||||
|
||||
if (retval == -1) {
|
||||
fake = skey_fake_keyinfo(authctxt->user);
|
||||
strlcpy(challenge, fake, sizeof challenge);
|
||||
}
|
||||
/* send our info request */
|
||||
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
|
||||
packet_put_cstring("S/Key Authentication"); /* Name */
|
||||
packet_put_cstring(challenge); /* Instruction */
|
||||
packet_put_cstring(""); /* Language */
|
||||
packet_put_int(1); /* Number of prompts */
|
||||
packet_put_cstring(echo ?
|
||||
"Response [Echo]: ": "Response: "); /* Prompt */
|
||||
packet_put_char(echo); /* Echo */
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
memset(challenge, 'c', sizeof challenge);
|
||||
}
|
||||
|
||||
void
|
||||
input_userauth_info_response(int type, int plen, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
int authenticated = 0;
|
||||
u_int nresp, rlen;
|
||||
char *resp, *method;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_response: no authentication context");
|
||||
|
||||
if (authctxt->attempt++ >= AUTH_FAIL_MAX)
|
||||
packet_disconnect("too many failed userauth_requests");
|
||||
|
||||
nresp = packet_get_int();
|
||||
if (nresp == 1) {
|
||||
/* we only support s/key and assume s/key for nresp == 1 */
|
||||
method = "s/key";
|
||||
resp = packet_get_string(&rlen);
|
||||
packet_done();
|
||||
if (strlen(resp) == 0) {
|
||||
/*
|
||||
* if we received a null response, resend prompt with
|
||||
* echo enabled
|
||||
*/
|
||||
authenticated = -1;
|
||||
userauth_log(authctxt, authenticated, method);
|
||||
send_userauth_into_request(authctxt, 1);
|
||||
} else {
|
||||
/* verify skey response */
|
||||
if (authctxt->valid &&
|
||||
skey_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
skey_passcheck(authctxt->pw->pw_name, resp) != -1) {
|
||||
authenticated = 1;
|
||||
} else {
|
||||
authenticated = 0;
|
||||
}
|
||||
memset(resp, 'r', rlen);
|
||||
/* unregister callback */
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
|
||||
userauth_log(authctxt, authenticated, method);
|
||||
userauth_reply(authctxt, authenticated);
|
||||
}
|
||||
xfree(resp);
|
||||
}
|
||||
}
|
434
crypto/dist/ssh/auth2.c
vendored
434
crypto/dist/ssh/auth2.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auth2.c,v 1.1.1.1 2000/09/28 22:09:43 thorpej Exp $ */
|
||||
/* $NetBSD: auth2.c,v 1.1.1.2 2001/01/14 04:50:02 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: auth2.c,v 1.16 2000/09/27 21:41:34 markus Exp */
|
||||
/* from OpenBSD: auth2.c,v 1.24 2000/12/28 14:25:51 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: auth2.c,v 1.1.1.1 2000/09/28 22:09:43 thorpej Exp $");
|
||||
__RCSID("$NetBSD: auth2.c,v 1.1.1.2 2001/01/14 04:50:02 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -44,7 +44,6 @@ __RCSID("$NetBSD: auth2.c,v 1.1.1.1 2000/09/28 22:09:43 thorpej Exp $");
|
||||
#include "pty.h"
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "cipher.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "channels.h"
|
||||
@ -57,59 +56,81 @@ __RCSID("$NetBSD: auth2.c,v 1.1.1.1 2000/09/28 22:09:43 thorpej Exp $");
|
||||
#include "key.h"
|
||||
#include "kex.h"
|
||||
|
||||
#include "dsa.h"
|
||||
#include "uidswap.h"
|
||||
#include "auth-options.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern unsigned char *session_id2;
|
||||
extern u_char *session_id2;
|
||||
extern int session_id2_len;
|
||||
|
||||
static Authctxt *x_authctxt = NULL;
|
||||
static int one = 1;
|
||||
|
||||
typedef struct Authmethod Authmethod;
|
||||
struct Authmethod {
|
||||
char *name;
|
||||
int (*userauth)(Authctxt *authctxt);
|
||||
int *enabled;
|
||||
};
|
||||
|
||||
/* protocol */
|
||||
|
||||
void input_service_request(int type, int plen, void *ctxt);
|
||||
void input_userauth_request(int type, int plen, void *ctxt);
|
||||
void protocol_error(int type, int plen, void *ctxt);
|
||||
|
||||
/* auth */
|
||||
int ssh2_auth_none(struct passwd *pw);
|
||||
int ssh2_auth_password(struct passwd *pw);
|
||||
int ssh2_auth_pubkey(struct passwd *pw, char *service);
|
||||
|
||||
/* helper */
|
||||
struct passwd* auth_set_user(char *u, char *s);
|
||||
int user_dsa_key_allowed(struct passwd *pw, Key *key);
|
||||
Authmethod *authmethod_lookup(const char *name);
|
||||
struct passwd *pwcopy(struct passwd *pw);
|
||||
int user_key_allowed(struct passwd *pw, Key *key);
|
||||
char *authmethods_get(void);
|
||||
|
||||
typedef struct Authctxt Authctxt;
|
||||
struct Authctxt {
|
||||
char *user;
|
||||
char *service;
|
||||
struct passwd pw;
|
||||
int valid;
|
||||
/* auth */
|
||||
int userauth_none(Authctxt *authctxt);
|
||||
int userauth_passwd(Authctxt *authctxt);
|
||||
int userauth_pubkey(Authctxt *authctxt);
|
||||
int userauth_kbdint(Authctxt *authctxt);
|
||||
|
||||
Authmethod authmethods[] = {
|
||||
{"none",
|
||||
userauth_none,
|
||||
&one},
|
||||
{"publickey",
|
||||
userauth_pubkey,
|
||||
&options.pubkey_authentication},
|
||||
{"keyboard-interactive",
|
||||
userauth_kbdint,
|
||||
&options.kbd_interactive_authentication},
|
||||
{"password",
|
||||
userauth_passwd,
|
||||
&options.password_authentication},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
static Authctxt *authctxt = NULL;
|
||||
static int userauth_success = 0;
|
||||
|
||||
/*
|
||||
* loop until userauth_success == TRUE
|
||||
* loop until authctxt->success == TRUE
|
||||
*/
|
||||
|
||||
void
|
||||
do_authentication2(void)
|
||||
{
|
||||
Authctxt *authctxt = xmalloc(sizeof(*authctxt));
|
||||
memset(authctxt, 'a', sizeof(*authctxt));
|
||||
authctxt->valid = 0;
|
||||
authctxt->attempt = 0;
|
||||
authctxt->failures = 0;
|
||||
authctxt->success = 0;
|
||||
x_authctxt = authctxt; /*XXX*/
|
||||
|
||||
/* turn off skey/kerberos, not supported by SSH2 */
|
||||
#ifdef SKEY
|
||||
options.skey_authentication = 0;
|
||||
#endif
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
/* turn off kerberos, not supported by SSH2 */
|
||||
options.kerberos_authentication = 0;
|
||||
#endif
|
||||
|
||||
dispatch_init(&protocol_error);
|
||||
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
|
||||
dispatch_run(DISPATCH_BLOCK, &userauth_success, NULL);
|
||||
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
|
||||
do_authenticated2();
|
||||
}
|
||||
|
||||
@ -126,13 +147,17 @@ protocol_error(int type, int plen, void *ctxt)
|
||||
void
|
||||
input_service_request(int type, int plen, void *ctxt)
|
||||
{
|
||||
unsigned int len;
|
||||
Authctxt *authctxt = ctxt;
|
||||
u_int len;
|
||||
int accept = 0;
|
||||
char *service = packet_get_string(&len);
|
||||
packet_done();
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_service_request: no authctxt");
|
||||
|
||||
if (strcmp(service, "ssh-userauth") == 0) {
|
||||
if (!userauth_success) {
|
||||
if (!authctxt->success) {
|
||||
accept = 1;
|
||||
/* now we can handle user-auth requests */
|
||||
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
|
||||
@ -155,45 +180,85 @@ input_service_request(int type, int plen, void *ctxt)
|
||||
void
|
||||
input_userauth_request(int type, int plen, void *ctxt)
|
||||
{
|
||||
static void (*authlog) (const char *fmt,...) = verbose;
|
||||
static int attempt = 0;
|
||||
unsigned int len;
|
||||
Authctxt *authctxt = ctxt;
|
||||
Authmethod *m = NULL;
|
||||
char *user, *service, *method;
|
||||
int authenticated = 0;
|
||||
char *user, *service, *method, *authmsg = NULL;
|
||||
struct passwd *pw;
|
||||
|
||||
if (++attempt == AUTH_FAIL_MAX)
|
||||
packet_disconnect("too many failed userauth_requests");
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_request: no authctxt");
|
||||
|
||||
user = packet_get_string(&len);
|
||||
service = packet_get_string(&len);
|
||||
method = packet_get_string(&len);
|
||||
user = packet_get_string(NULL);
|
||||
service = packet_get_string(NULL);
|
||||
method = packet_get_string(NULL);
|
||||
debug("userauth-request for user %s service %s method %s", user, service, method);
|
||||
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
|
||||
|
||||
/* XXX we only allow the ssh-connection service */
|
||||
pw = auth_set_user(user, service);
|
||||
if (pw && strcmp(service, "ssh-connection")==0) {
|
||||
if (strcmp(method, "none") == 0) {
|
||||
authenticated = ssh2_auth_none(pw);
|
||||
} else if (strcmp(method, "password") == 0) {
|
||||
authenticated = ssh2_auth_password(pw);
|
||||
} else if (strcmp(method, "publickey") == 0) {
|
||||
authenticated = ssh2_auth_pubkey(pw, service);
|
||||
if (authctxt->attempt++ == 0) {
|
||||
/* setup auth context */
|
||||
struct passwd *pw = NULL;
|
||||
setproctitle("%s", user);
|
||||
pw = getpwnam(user);
|
||||
if (pw && allowed_user(pw) && strcmp(service, "ssh-connection")==0) {
|
||||
authctxt->pw = pwcopy(pw);
|
||||
authctxt->valid = 1;
|
||||
debug2("input_userauth_request: setting up authctxt for %s", user);
|
||||
} else {
|
||||
log("input_userauth_request: illegal user %s", user);
|
||||
}
|
||||
authctxt->user = xstrdup(user);
|
||||
authctxt->service = xstrdup(service);
|
||||
} else if (authctxt->valid) {
|
||||
if (strcmp(user, authctxt->user) != 0 ||
|
||||
strcmp(service, authctxt->service) != 0) {
|
||||
log("input_userauth_request: missmatch: (%s,%s)!=(%s,%s)",
|
||||
user, service, authctxt->user, authctxt->service);
|
||||
authctxt->valid = 0;
|
||||
}
|
||||
}
|
||||
if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
|
||||
authenticated = 0;
|
||||
log("ROOT LOGIN REFUSED FROM %.200s",
|
||||
get_canonical_hostname());
|
||||
|
||||
m = authmethod_lookup(method);
|
||||
if (m != NULL) {
|
||||
debug2("input_userauth_request: try method %s", method);
|
||||
authenticated = m->userauth(authctxt);
|
||||
} else {
|
||||
debug2("input_userauth_request: unsupported method %s", method);
|
||||
}
|
||||
if (!authctxt->valid && authenticated == 1) {
|
||||
log("input_userauth_request: INTERNAL ERROR: authenticated invalid user %s service %s", user, method);
|
||||
authenticated = 0;
|
||||
}
|
||||
|
||||
/* Special handling for root */
|
||||
if (authenticated == 1 &&
|
||||
authctxt->valid && authctxt->pw->pw_uid == 0 && !options.permit_root_login) {
|
||||
authenticated = 0;
|
||||
log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
|
||||
}
|
||||
|
||||
/* Log before sending the reply */
|
||||
userauth_log(authctxt, authenticated, method);
|
||||
userauth_reply(authctxt, authenticated);
|
||||
|
||||
xfree(service);
|
||||
xfree(user);
|
||||
xfree(method);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
userauth_log(Authctxt *authctxt, int authenticated, char *method)
|
||||
{
|
||||
void (*authlog) (const char *fmt,...) = verbose;
|
||||
char *user = NULL, *authmsg = NULL;
|
||||
|
||||
/* Raise logging level */
|
||||
if (authenticated == 1 ||
|
||||
attempt == AUTH_FAIL_LOG ||
|
||||
!authctxt->valid ||
|
||||
authctxt->failures >= AUTH_FAIL_LOG ||
|
||||
strcmp(method, "password") == 0)
|
||||
authlog = log;
|
||||
|
||||
/* Log before sending the reply */
|
||||
if (authenticated == 1) {
|
||||
authmsg = "Accepted";
|
||||
} else if (authenticated == 0) {
|
||||
@ -201,13 +266,25 @@ input_userauth_request(int type, int plen, void *ctxt)
|
||||
} else {
|
||||
authmsg = "Postponed";
|
||||
}
|
||||
authlog("%s %s for %.200s from %.200s port %d ssh2",
|
||||
authmsg,
|
||||
method,
|
||||
pw && pw->pw_uid == 0 ? "ROOT" : user,
|
||||
get_remote_ipaddr(),
|
||||
get_remote_port());
|
||||
|
||||
if (authctxt->valid) {
|
||||
user = authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user;
|
||||
} else {
|
||||
user = "NOUSER";
|
||||
}
|
||||
|
||||
authlog("%s %s for %.200s from %.200s port %d ssh2",
|
||||
authmsg,
|
||||
method,
|
||||
user,
|
||||
get_remote_ipaddr(),
|
||||
get_remote_port());
|
||||
}
|
||||
|
||||
void
|
||||
userauth_reply(Authctxt *authctxt, int authenticated)
|
||||
{
|
||||
char *methods;
|
||||
/* XXX todo: check if multiple auth methods are needed */
|
||||
if (authenticated == 1) {
|
||||
/* turn off userauth */
|
||||
@ -216,102 +293,150 @@ input_userauth_request(int type, int plen, void *ctxt)
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
/* now we can break out */
|
||||
userauth_success = 1;
|
||||
authctxt->success = 1;
|
||||
} else if (authenticated == 0) {
|
||||
if (authctxt->failures++ >= AUTH_FAIL_MAX)
|
||||
packet_disconnect("too many failed userauth_requests");
|
||||
methods = authmethods_get();
|
||||
packet_start(SSH2_MSG_USERAUTH_FAILURE);
|
||||
packet_put_cstring("publickey,password"); /* XXX dynamic */
|
||||
packet_put_char(0); /* XXX partial success, unused */
|
||||
packet_put_cstring(methods);
|
||||
packet_put_char(0); /* XXX partial success, unused */
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
xfree(methods);
|
||||
} else {
|
||||
/* do nothing, we did already send a reply */
|
||||
}
|
||||
|
||||
xfree(service);
|
||||
xfree(user);
|
||||
xfree(method);
|
||||
}
|
||||
|
||||
int
|
||||
ssh2_auth_none(struct passwd *pw)
|
||||
userauth_none(Authctxt *authctxt)
|
||||
{
|
||||
/* disable method "none", only allowed one time */
|
||||
Authmethod *m = authmethod_lookup("none");
|
||||
if (m != NULL)
|
||||
m->enabled = NULL;
|
||||
packet_done();
|
||||
return auth_password(pw, "");
|
||||
return authctxt->valid ? auth_password(authctxt->pw, "") : 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh2_auth_password(struct passwd *pw)
|
||||
userauth_passwd(Authctxt *authctxt)
|
||||
{
|
||||
char *password;
|
||||
int authenticated = 0;
|
||||
int change;
|
||||
unsigned int len;
|
||||
u_int len;
|
||||
change = packet_get_char();
|
||||
if (change)
|
||||
log("password change not supported");
|
||||
password = packet_get_string(&len);
|
||||
packet_done();
|
||||
if (options.password_authentication &&
|
||||
auth_password(pw, password) == 1)
|
||||
if (authctxt->valid &&
|
||||
auth_password(authctxt->pw, password) == 1)
|
||||
authenticated = 1;
|
||||
memset(password, 0, len);
|
||||
xfree(password);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
int
|
||||
ssh2_auth_pubkey(struct passwd *pw, char *service)
|
||||
userauth_kbdint(Authctxt *authctxt)
|
||||
{
|
||||
int authenticated = 0;
|
||||
char *lang = NULL;
|
||||
char *devs = NULL;
|
||||
|
||||
lang = packet_get_string(NULL);
|
||||
devs = packet_get_string(NULL);
|
||||
packet_done();
|
||||
|
||||
debug("keyboard-interactive language %s devs %s", lang, devs);
|
||||
#ifdef SKEY
|
||||
/* XXX hardcoded, we should look at devs */
|
||||
if (options.skey_authentication != 0)
|
||||
authenticated = auth2_skey(authctxt);
|
||||
#endif
|
||||
xfree(lang);
|
||||
xfree(devs);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
int
|
||||
userauth_pubkey(Authctxt *authctxt)
|
||||
{
|
||||
Buffer b;
|
||||
Key *key;
|
||||
char *pkalg, *pkblob, *sig;
|
||||
unsigned int alen, blen, slen;
|
||||
int have_sig;
|
||||
u_int alen, blen, slen;
|
||||
int have_sig, pktype;
|
||||
int authenticated = 0;
|
||||
|
||||
if (options.dsa_authentication == 0) {
|
||||
debug("pubkey auth disabled");
|
||||
if (!authctxt->valid) {
|
||||
debug2("userauth_pubkey: disabled because of invalid user");
|
||||
return 0;
|
||||
}
|
||||
have_sig = packet_get_char();
|
||||
pkalg = packet_get_string(&alen);
|
||||
if (strcmp(pkalg, KEX_DSS) != 0) {
|
||||
if (datafellows & SSH_BUG_PKAUTH) {
|
||||
debug2("userauth_pubkey: SSH_BUG_PKAUTH");
|
||||
/* no explicit pkalg given */
|
||||
pkblob = packet_get_string(&blen);
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, pkblob, blen);
|
||||
/* so we have to extract the pkalg from the pkblob */
|
||||
pkalg = buffer_get_string(&b, &alen);
|
||||
buffer_free(&b);
|
||||
} else {
|
||||
pkalg = packet_get_string(&alen);
|
||||
pkblob = packet_get_string(&blen);
|
||||
}
|
||||
pktype = key_type_from_name(pkalg);
|
||||
if (pktype == KEY_UNSPEC) {
|
||||
/* this is perfectly legal */
|
||||
log("userauth_pubkey: unsupported public key algorithm: %s", pkalg);
|
||||
xfree(pkalg);
|
||||
log("bad pkalg %s", pkalg); /*XXX*/
|
||||
xfree(pkblob);
|
||||
return 0;
|
||||
}
|
||||
pkblob = packet_get_string(&blen);
|
||||
key = dsa_key_from_blob(pkblob, blen);
|
||||
key = key_from_blob(pkblob, blen);
|
||||
if (key != NULL) {
|
||||
if (have_sig) {
|
||||
sig = packet_get_string(&slen);
|
||||
packet_done();
|
||||
buffer_init(&b);
|
||||
if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) {
|
||||
buffer_put_string(&b, session_id2, session_id2_len);
|
||||
} else {
|
||||
if (datafellows & SSH_OLD_SESSIONID) {
|
||||
buffer_append(&b, session_id2, session_id2_len);
|
||||
} else {
|
||||
buffer_put_string(&b, session_id2, session_id2_len);
|
||||
}
|
||||
/* reconstruct packet */
|
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
||||
buffer_put_cstring(&b, pw->pw_name);
|
||||
buffer_put_cstring(&b, authctxt->user);
|
||||
buffer_put_cstring(&b,
|
||||
datafellows & SSH_BUG_PUBKEYAUTH ?
|
||||
datafellows & SSH_BUG_PKSERVICE ?
|
||||
"ssh-userauth" :
|
||||
service);
|
||||
buffer_put_cstring(&b, "publickey");
|
||||
buffer_put_char(&b, have_sig);
|
||||
buffer_put_cstring(&b, KEX_DSS);
|
||||
authctxt->service);
|
||||
if (datafellows & SSH_BUG_PKAUTH) {
|
||||
buffer_put_char(&b, have_sig);
|
||||
} else {
|
||||
buffer_put_cstring(&b, "publickey");
|
||||
buffer_put_char(&b, have_sig);
|
||||
buffer_put_cstring(&b, key_ssh_name(key));
|
||||
}
|
||||
buffer_put_string(&b, pkblob, blen);
|
||||
#ifdef DEBUG_DSS
|
||||
#ifdef DEBUG_PK
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
/* test for correct signature */
|
||||
if (user_dsa_key_allowed(pw, key) &&
|
||||
dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
|
||||
if (user_key_allowed(authctxt->pw, key) &&
|
||||
key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
|
||||
authenticated = 1;
|
||||
buffer_clear(&b);
|
||||
xfree(sig);
|
||||
} else {
|
||||
debug("test whether pkalg/pkblob are acceptable");
|
||||
packet_done();
|
||||
debug("test key...");
|
||||
/* test whether pkalg/pkblob are acceptable */
|
||||
|
||||
/* XXX fake reply and always send PK_OK ? */
|
||||
/*
|
||||
* XXX this allows testing whether a user is allowed
|
||||
@ -320,7 +445,7 @@ ssh2_auth_pubkey(struct passwd *pw, char *service)
|
||||
* if a user is not allowed to login. is this an
|
||||
* issue? -markus
|
||||
*/
|
||||
if (user_dsa_key_allowed(pw, key)) {
|
||||
if (user_key_allowed(authctxt->pw, key)) {
|
||||
packet_start(SSH2_MSG_USERAUTH_PK_OK);
|
||||
packet_put_string(pkalg, alen);
|
||||
packet_put_string(pkblob, blen);
|
||||
@ -329,70 +454,86 @@ ssh2_auth_pubkey(struct passwd *pw, char *service)
|
||||
authenticated = -1;
|
||||
}
|
||||
}
|
||||
if (authenticated != 1)
|
||||
auth_clear_options();
|
||||
key_free(key);
|
||||
}
|
||||
debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
|
||||
xfree(pkalg);
|
||||
xfree(pkblob);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
/* set and get current user */
|
||||
/* get current user */
|
||||
|
||||
struct passwd*
|
||||
auth_get_user(void)
|
||||
{
|
||||
return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL;
|
||||
return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL;
|
||||
}
|
||||
|
||||
struct passwd*
|
||||
auth_set_user(char *u, char *s)
|
||||
{
|
||||
struct passwd *pw, *copy;
|
||||
#define DELIM ","
|
||||
|
||||
if (authctxt == NULL) {
|
||||
authctxt = xmalloc(sizeof(*authctxt));
|
||||
authctxt->valid = 0;
|
||||
authctxt->user = xstrdup(u);
|
||||
authctxt->service = xstrdup(s);
|
||||
setproctitle("%s", u);
|
||||
pw = getpwnam(u);
|
||||
if (!pw || !allowed_user(pw)) {
|
||||
log("auth_set_user: illegal user %s", u);
|
||||
return NULL;
|
||||
}
|
||||
copy = &authctxt->pw;
|
||||
memset(copy, 0, sizeof(*copy));
|
||||
copy->pw_name = xstrdup(pw->pw_name);
|
||||
copy->pw_passwd = xstrdup(pw->pw_passwd);
|
||||
copy->pw_uid = pw->pw_uid;
|
||||
copy->pw_gid = pw->pw_gid;
|
||||
copy->pw_class = xstrdup(pw->pw_class);
|
||||
copy->pw_dir = xstrdup(pw->pw_dir);
|
||||
copy->pw_shell = xstrdup(pw->pw_shell);
|
||||
authctxt->valid = 1;
|
||||
} else {
|
||||
if (strcmp(u, authctxt->user) != 0 ||
|
||||
strcmp(s, authctxt->service) != 0) {
|
||||
log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)",
|
||||
u, s, authctxt->user, authctxt->service);
|
||||
return NULL;
|
||||
char *
|
||||
authmethods_get(void)
|
||||
{
|
||||
Authmethod *method = NULL;
|
||||
u_int size = 0;
|
||||
char *list;
|
||||
|
||||
for (method = authmethods; method->name != NULL; method++) {
|
||||
if (strcmp(method->name, "none") == 0)
|
||||
continue;
|
||||
if (method->enabled != NULL && *(method->enabled) != 0) {
|
||||
if (size != 0)
|
||||
size += strlen(DELIM);
|
||||
size += strlen(method->name);
|
||||
}
|
||||
}
|
||||
return auth_get_user();
|
||||
size++; /* trailing '\0' */
|
||||
list = xmalloc(size);
|
||||
list[0] = '\0';
|
||||
|
||||
for (method = authmethods; method->name != NULL; method++) {
|
||||
if (strcmp(method->name, "none") == 0)
|
||||
continue;
|
||||
if (method->enabled != NULL && *(method->enabled) != 0) {
|
||||
if (list[0] != '\0')
|
||||
strlcat(list, DELIM, size);
|
||||
strlcat(list, method->name, size);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Authmethod *
|
||||
authmethod_lookup(const char *name)
|
||||
{
|
||||
Authmethod *method = NULL;
|
||||
if (name != NULL)
|
||||
for (method = authmethods; method->name != NULL; method++)
|
||||
if (method->enabled != NULL &&
|
||||
*(method->enabled) != 0 &&
|
||||
strcmp(name, method->name) == 0)
|
||||
return method;
|
||||
debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* return 1 if user allows given key */
|
||||
int
|
||||
user_dsa_key_allowed(struct passwd *pw, Key *key)
|
||||
user_key_allowed(struct passwd *pw, Key *key)
|
||||
{
|
||||
char line[8192], file[1024];
|
||||
int found_key = 0;
|
||||
unsigned int bits = -1;
|
||||
FILE *f;
|
||||
unsigned long linenum = 0;
|
||||
u_long linenum = 0;
|
||||
struct stat st;
|
||||
Key *found;
|
||||
|
||||
if (pw == NULL)
|
||||
return 0;
|
||||
|
||||
/* Temporarily use the user's uid. */
|
||||
temporarily_use_uid(pw->pw_uid);
|
||||
|
||||
@ -465,10 +606,10 @@ user_dsa_key_allowed(struct passwd *pw, Key *key)
|
||||
if (!*cp || *cp == '\n' || *cp == '#')
|
||||
continue;
|
||||
|
||||
bits = key_read(found, &cp);
|
||||
if (bits == 0) {
|
||||
if (key_read(found, &cp) == -1) {
|
||||
/* no key? check if there are options for this key */
|
||||
int quoted = 0;
|
||||
debug2("user_key_allowed: check options: '%s'", cp);
|
||||
options = cp;
|
||||
for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
|
||||
if (*cp == '\\' && cp[1] == '"')
|
||||
@ -479,8 +620,8 @@ user_dsa_key_allowed(struct passwd *pw, Key *key)
|
||||
/* Skip remaining whitespace. */
|
||||
for (; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
bits = key_read(found, &cp);
|
||||
if (bits == 0) {
|
||||
if (key_read(found, &cp) == -1) {
|
||||
debug2("user_key_allowed: advance: '%s'", cp);
|
||||
/* still no key? advance to next line*/
|
||||
continue;
|
||||
}
|
||||
@ -498,3 +639,18 @@ user_dsa_key_allowed(struct passwd *pw, Key *key)
|
||||
key_free(found);
|
||||
return found_key;
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
pwcopy(struct passwd *pw)
|
||||
{
|
||||
struct passwd *copy = xmalloc(sizeof(*copy));
|
||||
memset(copy, 0, sizeof(*copy));
|
||||
copy->pw_name = xstrdup(pw->pw_name);
|
||||
copy->pw_passwd = xstrdup(pw->pw_passwd);
|
||||
copy->pw_uid = pw->pw_uid;
|
||||
copy->pw_gid = pw->pw_gid;
|
||||
copy->pw_class = xstrdup(pw->pw_class);
|
||||
copy->pw_dir = xstrdup(pw->pw_dir);
|
||||
copy->pw_shell = xstrdup(pw->pw_shell);
|
||||
return copy;
|
||||
}
|
||||
|
119
crypto/dist/ssh/authfd.c
vendored
119
crypto/dist/ssh/authfd.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: authfd.c,v 1.1.1.1 2000/09/28 22:09:44 thorpej Exp $ */
|
||||
/* $NetBSD: authfd.c,v 1.1.1.2 2001/01/14 04:50:03 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -36,11 +36,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: authfd.c,v 1.28 2000/09/21 11:07:50 markus Exp */
|
||||
/* from OpenBSD: authfd.c,v 1.32 2000/12/20 19:37:21 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: authfd.c,v 1.1.1.1 2000/09/28 22:09:44 thorpej Exp $");
|
||||
__RCSID("$NetBSD: authfd.c,v 1.1.1.2 2001/01/14 04:50:03 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -58,16 +58,19 @@ __RCSID("$NetBSD: authfd.c,v 1.1.1.1 2000/09/28 22:09:44 thorpej Exp $");
|
||||
#include "key.h"
|
||||
#include "authfd.h"
|
||||
#include "kex.h"
|
||||
#include "dsa.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* helper */
|
||||
int decode_reply(int type);
|
||||
|
||||
/* macro to check for "agent failure" message */
|
||||
#define agent_failed(x) \
|
||||
((x == SSH_AGENT_FAILURE) || (x == SSH_COM_AGENT2_FAILURE))
|
||||
|
||||
/* Returns the number of the authentication fd, or -1 if there is none. */
|
||||
|
||||
int
|
||||
ssh_get_authentication_socket()
|
||||
ssh_get_authentication_socket(void)
|
||||
{
|
||||
const char *authsocket;
|
||||
int sock, len;
|
||||
@ -172,7 +175,7 @@ ssh_close_authentication_socket(int sock)
|
||||
*/
|
||||
|
||||
AuthenticationConnection *
|
||||
ssh_get_authentication_connection()
|
||||
ssh_get_authentication_connection(void)
|
||||
{
|
||||
AuthenticationConnection *auth;
|
||||
int sock;
|
||||
@ -211,8 +214,8 @@ ssh_close_authentication_connection(AuthenticationConnection *auth)
|
||||
* Returns the first authentication identity held by the agent.
|
||||
*/
|
||||
|
||||
Key *
|
||||
ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version)
|
||||
int
|
||||
ssh_get_num_identities(AuthenticationConnection *auth, int version)
|
||||
{
|
||||
int type, code1 = 0, code2 = 0;
|
||||
Buffer request;
|
||||
@ -227,7 +230,7 @@ ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int versi
|
||||
code2 = SSH2_AGENT_IDENTITIES_ANSWER;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -240,14 +243,14 @@ ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int versi
|
||||
buffer_clear(&auth->identities);
|
||||
if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
|
||||
buffer_free(&request);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
buffer_free(&request);
|
||||
|
||||
/* Get message type, and verify that we got a proper answer. */
|
||||
type = buffer_get_char(&auth->identities);
|
||||
if (type == SSH_AGENT_FAILURE) {
|
||||
return NULL;
|
||||
if (agent_failed(type)) {
|
||||
return 0;
|
||||
} else if (type != code2) {
|
||||
fatal("Bad authentication reply message type: %d", type);
|
||||
}
|
||||
@ -258,16 +261,24 @@ ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int versi
|
||||
fatal("Too many identities in authentication reply: %d\n",
|
||||
auth->howmany);
|
||||
|
||||
/* Return the first entry (if any). */
|
||||
return ssh_get_next_identity(auth, comment, version);
|
||||
return auth->howmany;
|
||||
}
|
||||
|
||||
Key *
|
||||
ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version)
|
||||
{
|
||||
/* get number of identities and return the first entry (if any). */
|
||||
if (ssh_get_num_identities(auth, version) > 0)
|
||||
return ssh_get_next_identity(auth, comment, version);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Key *
|
||||
ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version)
|
||||
{
|
||||
unsigned int bits;
|
||||
unsigned char *blob;
|
||||
unsigned int blen;
|
||||
u_int bits;
|
||||
u_char *blob;
|
||||
u_int blen;
|
||||
Key *key = NULL;
|
||||
|
||||
/* Return failure if no more entries. */
|
||||
@ -280,7 +291,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
|
||||
*/
|
||||
switch(version){
|
||||
case 1:
|
||||
key = key_new(KEY_RSA);
|
||||
key = key_new(KEY_RSA1);
|
||||
bits = buffer_get_int(&auth->identities);
|
||||
buffer_get_bignum(&auth->identities, key->rsa->e);
|
||||
buffer_get_bignum(&auth->identities, key->rsa->n);
|
||||
@ -292,7 +303,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
|
||||
case 2:
|
||||
blob = buffer_get_string(&auth->identities, &blen);
|
||||
*comment = buffer_get_string(&auth->identities, NULL);
|
||||
key = dsa_key_from_blob(blob, blen);
|
||||
key = key_from_blob(blob, blen);
|
||||
xfree(blob);
|
||||
break;
|
||||
default:
|
||||
@ -315,16 +326,16 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
|
||||
int
|
||||
ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||
Key* key, BIGNUM *challenge,
|
||||
unsigned char session_id[16],
|
||||
unsigned int response_type,
|
||||
unsigned char response[16])
|
||||
u_char session_id[16],
|
||||
u_int response_type,
|
||||
u_char response[16])
|
||||
{
|
||||
Buffer buffer;
|
||||
int success = 0;
|
||||
int i;
|
||||
int type;
|
||||
|
||||
if (key->type != KEY_RSA)
|
||||
if (key->type != KEY_RSA1)
|
||||
return 0;
|
||||
if (response_type == 0) {
|
||||
log("Compatibility with ssh protocol version 1.0 no longer supported.");
|
||||
@ -345,7 +356,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||
}
|
||||
type = buffer_get_char(&buffer);
|
||||
|
||||
if (type == SSH_AGENT_FAILURE) {
|
||||
if (agent_failed(type)) {
|
||||
log("Agent admitted failure to authenticate using the key.");
|
||||
} else if (type != SSH_AGENT_RSA_RESPONSE) {
|
||||
fatal("Bad authentication response: %d", type);
|
||||
@ -366,17 +377,17 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||
int
|
||||
ssh_agent_sign(AuthenticationConnection *auth,
|
||||
Key *key,
|
||||
unsigned char **sigp, int *lenp,
|
||||
unsigned char *data, int datalen)
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
extern int datafellows;
|
||||
Buffer msg;
|
||||
unsigned char *blob;
|
||||
unsigned int blen;
|
||||
u_char *blob;
|
||||
u_int blen;
|
||||
int type, flags = 0;
|
||||
int ret = -1;
|
||||
|
||||
if (dsa_make_key_blob(key, &blob, &blen) == 0)
|
||||
if (key_to_blob(key, &blob, &blen) == 0)
|
||||
return -1;
|
||||
|
||||
if (datafellows & SSH_BUG_SIGBLOB)
|
||||
@ -394,7 +405,7 @@ ssh_agent_sign(AuthenticationConnection *auth,
|
||||
return -1;
|
||||
}
|
||||
type = buffer_get_char(&msg);
|
||||
if (type == SSH_AGENT_FAILURE) {
|
||||
if (agent_failed(type)) {
|
||||
log("Agent admitted failure to sign using the key.");
|
||||
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
|
||||
fatal("Bad authentication response: %d", type);
|
||||
@ -409,7 +420,7 @@ ssh_agent_sign(AuthenticationConnection *auth,
|
||||
/* Encode key for a message to the agent. */
|
||||
|
||||
static void
|
||||
ssh_encode_identity_rsa(Buffer *b, RSA *key, const char *comment)
|
||||
ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment)
|
||||
{
|
||||
buffer_clear(b);
|
||||
buffer_put_char(b, SSH_AGENTC_ADD_RSA_IDENTITY);
|
||||
@ -425,17 +436,29 @@ ssh_encode_identity_rsa(Buffer *b, RSA *key, const char *comment)
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_encode_identity_dsa(Buffer *b, DSA *key, const char *comment)
|
||||
ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
|
||||
{
|
||||
buffer_clear(b);
|
||||
buffer_put_char(b, SSH2_AGENTC_ADD_IDENTITY);
|
||||
buffer_put_cstring(b, KEX_DSS);
|
||||
buffer_put_bignum2(b, key->p);
|
||||
buffer_put_bignum2(b, key->q);
|
||||
buffer_put_bignum2(b, key->g);
|
||||
buffer_put_bignum2(b, key->pub_key);
|
||||
buffer_put_bignum2(b, key->priv_key);
|
||||
buffer_put_string(b, comment, strlen(comment));
|
||||
buffer_put_cstring(b, key_ssh_name(key));
|
||||
switch(key->type){
|
||||
case KEY_RSA:
|
||||
buffer_put_bignum2(b, key->rsa->n);
|
||||
buffer_put_bignum2(b, key->rsa->e);
|
||||
buffer_put_bignum2(b, key->rsa->d);
|
||||
buffer_put_bignum2(b, key->rsa->iqmp);
|
||||
buffer_put_bignum2(b, key->rsa->p);
|
||||
buffer_put_bignum2(b, key->rsa->q);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
buffer_put_bignum2(b, key->dsa->p);
|
||||
buffer_put_bignum2(b, key->dsa->q);
|
||||
buffer_put_bignum2(b, key->dsa->g);
|
||||
buffer_put_bignum2(b, key->dsa->pub_key);
|
||||
buffer_put_bignum2(b, key->dsa->priv_key);
|
||||
break;
|
||||
}
|
||||
buffer_put_cstring(b, comment);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -452,11 +475,12 @@ ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
|
||||
buffer_init(&msg);
|
||||
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
ssh_encode_identity_rsa(&msg, key->rsa, comment);
|
||||
case KEY_RSA1:
|
||||
ssh_encode_identity_rsa1(&msg, key->rsa, comment);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
ssh_encode_identity_dsa(&msg, key->dsa, comment);
|
||||
ssh_encode_identity_ssh2(&msg, key, comment);
|
||||
break;
|
||||
default:
|
||||
buffer_free(&msg);
|
||||
@ -482,18 +506,18 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
|
||||
{
|
||||
Buffer msg;
|
||||
int type;
|
||||
unsigned char *blob;
|
||||
unsigned int blen;
|
||||
u_char *blob;
|
||||
u_int blen;
|
||||
|
||||
buffer_init(&msg);
|
||||
|
||||
if (key->type == KEY_RSA) {
|
||||
if (key->type == KEY_RSA1) {
|
||||
buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
|
||||
buffer_put_int(&msg, BN_num_bits(key->rsa->n));
|
||||
buffer_put_bignum(&msg, key->rsa->e);
|
||||
buffer_put_bignum(&msg, key->rsa->n);
|
||||
} else if (key->type == KEY_DSA) {
|
||||
dsa_make_key_blob(key, &blob, &blen);
|
||||
} else if (key->type == KEY_DSA || key->type == KEY_RSA) {
|
||||
key_to_blob(key, &blob, &blen);
|
||||
buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
|
||||
buffer_put_string(&msg, blob, blen);
|
||||
xfree(blob);
|
||||
@ -541,6 +565,7 @@ decode_reply(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case SSH_AGENT_FAILURE:
|
||||
case SSH_COM_AGENT2_FAILURE:
|
||||
log("SSH_AGENT_FAILURE");
|
||||
return 0;
|
||||
case SSH_AGENT_SUCCESS:
|
||||
|
23
crypto/dist/ssh/authfd.h
vendored
23
crypto/dist/ssh/authfd.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: authfd.h,v 1.1.1.1 2000/09/28 22:09:44 thorpej Exp $ */
|
||||
/* $NetBSD: authfd.h,v 1.1.1.2 2001/01/14 04:50:03 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,7 +13,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: authfd.h,v 1.12 2000/09/21 11:07:51 markus Exp */
|
||||
/* from OpenBSD: authfd.h,v 1.16 2000/12/20 19:37:21 markus Exp */
|
||||
|
||||
#ifndef AUTHFD_H
|
||||
#define AUTHFD_H
|
||||
@ -31,6 +31,7 @@
|
||||
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
|
||||
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
|
||||
|
||||
/* private OpenSSH extensions for SSH2 */
|
||||
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
|
||||
#define SSH2_AGENT_IDENTITIES_ANSWER 12
|
||||
#define SSH2_AGENTC_SIGN_REQUEST 13
|
||||
@ -39,6 +40,9 @@
|
||||
#define SSH2_AGENTC_REMOVE_IDENTITY 18
|
||||
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
|
||||
|
||||
/* additional error code for ssh.com's ssh-agent2 */
|
||||
#define SSH_COM_AGENT2_FAILURE 102
|
||||
|
||||
#define SSH_AGENT_OLD_SIGNATURE 0x01
|
||||
|
||||
|
||||
@ -72,6 +76,11 @@ AuthenticationConnection *ssh_get_authentication_connection(void);
|
||||
*/
|
||||
void ssh_close_authentication_connection(AuthenticationConnection *auth);
|
||||
|
||||
/*
|
||||
* Returns the number authentication identity held by the agent.
|
||||
*/
|
||||
int ssh_get_num_identities(AuthenticationConnection *auth, int version);
|
||||
|
||||
/*
|
||||
* Returns the first authentication identity held by the agent or NULL if
|
||||
* no identies are available. Caller must free comment and key.
|
||||
@ -94,16 +103,16 @@ Key *ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int v
|
||||
int
|
||||
ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||
Key *key, BIGNUM * challenge,
|
||||
unsigned char session_id[16],
|
||||
unsigned int response_type,
|
||||
unsigned char response[16]);
|
||||
u_char session_id[16],
|
||||
u_int response_type,
|
||||
u_char response[16]);
|
||||
|
||||
/* Requests the agent to sign data using key */
|
||||
int
|
||||
ssh_agent_sign(AuthenticationConnection *auth,
|
||||
Key *key,
|
||||
unsigned char **sigp, int *lenp,
|
||||
unsigned char *data, int datalen);
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen);
|
||||
|
||||
/*
|
||||
* Adds an identity to the authentication server. This call is not meant to
|
||||
|
194
crypto/dist/ssh/authfile.c
vendored
194
crypto/dist/ssh/authfile.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: authfile.c,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $ */
|
||||
/* $NetBSD: authfile.c,v 1.1.1.2 2001/01/14 04:50:04 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -37,11 +37,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: authfile.c,v 1.19 2000/09/07 20:27:49 deraadt Exp */
|
||||
/* from OpenBSD: authfile.c,v 1.24 2000/12/20 19:26:56 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: authfile.c,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $");
|
||||
__RCSID("$NetBSD: authfile.c,v 1.1.1.2 2001/01/14 04:50:04 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -49,6 +49,7 @@ __RCSID("$NetBSD: authfile.c,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $");
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
@ -56,7 +57,6 @@ __RCSID("$NetBSD: authfile.c,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $");
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "cipher.h"
|
||||
#include "ssh.h"
|
||||
#include "key.h"
|
||||
#include "authfile.h"
|
||||
@ -72,14 +72,14 @@ __RCSID("$NetBSD: authfile.c,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $");
|
||||
*/
|
||||
|
||||
static int
|
||||
save_private_key_rsa(const char *filename, const char *passphrase,
|
||||
save_private_key_rsa1(const char *filename, const char *passphrase,
|
||||
RSA *key, const char *comment)
|
||||
{
|
||||
Buffer buffer, encrypted;
|
||||
char buf[100], *cp;
|
||||
int fd, i;
|
||||
CipherContext cipher;
|
||||
int cipher_type;
|
||||
CipherContext ciphercontext;
|
||||
Cipher *cipher;
|
||||
u_int32_t rand;
|
||||
|
||||
/*
|
||||
@ -87,9 +87,11 @@ save_private_key_rsa(const char *filename, const char *passphrase,
|
||||
* to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
|
||||
*/
|
||||
if (strcmp(passphrase, "") == 0)
|
||||
cipher_type = SSH_CIPHER_NONE;
|
||||
cipher = cipher_by_number(SSH_CIPHER_NONE);
|
||||
else
|
||||
cipher_type = SSH_AUTHFILE_CIPHER;
|
||||
cipher = cipher_by_number(SSH_AUTHFILE_CIPHER);
|
||||
if (cipher == NULL)
|
||||
fatal("save_private_key_rsa: bad cipher");
|
||||
|
||||
/* This buffer is used to built the secret part of the private key. */
|
||||
buffer_init(&buffer);
|
||||
@ -127,7 +129,7 @@ save_private_key_rsa(const char *filename, const char *passphrase,
|
||||
buffer_put_char(&encrypted, 0);
|
||||
|
||||
/* Store cipher type. */
|
||||
buffer_put_char(&encrypted, cipher_type);
|
||||
buffer_put_char(&encrypted, cipher->number);
|
||||
buffer_put_int(&encrypted, 0); /* For future extension */
|
||||
|
||||
/* Store public key. This will be in plain text. */
|
||||
@ -139,11 +141,10 @@ save_private_key_rsa(const char *filename, const char *passphrase,
|
||||
/* Allocate space for the private part of the key in the buffer. */
|
||||
buffer_append_space(&encrypted, &cp, buffer_len(&buffer));
|
||||
|
||||
cipher_set_key_string(&cipher, cipher_type, passphrase);
|
||||
cipher_encrypt(&cipher, (unsigned char *) cp,
|
||||
(unsigned char *) buffer_ptr(&buffer),
|
||||
buffer_len(&buffer));
|
||||
memset(&cipher, 0, sizeof(cipher));
|
||||
cipher_set_key_string(&ciphercontext, cipher, passphrase);
|
||||
cipher_encrypt(&ciphercontext, (u_char *) cp,
|
||||
(u_char *) buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
|
||||
/* Destroy temporary data. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
@ -158,7 +159,7 @@ save_private_key_rsa(const char *filename, const char *passphrase,
|
||||
strerror(errno));
|
||||
buffer_free(&encrypted);
|
||||
close(fd);
|
||||
remove(filename);
|
||||
unlink(filename);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
@ -166,16 +167,17 @@ save_private_key_rsa(const char *filename, const char *passphrase,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save DSA key in OpenSSL PEM format */
|
||||
|
||||
/* save SSH2 key in OpenSSL PEM format */
|
||||
static int
|
||||
save_private_key_dsa(const char *filename, const char *passphrase,
|
||||
DSA *dsa, const char *comment)
|
||||
save_private_key_ssh2(const char *filename, const char *_passphrase,
|
||||
Key *key, const char *comment)
|
||||
{
|
||||
FILE *fp;
|
||||
int fd;
|
||||
int success = 1;
|
||||
int len = strlen(passphrase);
|
||||
int success = 0;
|
||||
int len = strlen(_passphrase);
|
||||
char *passphrase = (len > 0) ? (char *)_passphrase : NULL;
|
||||
EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
|
||||
|
||||
if (len > 0 && len <= 4) {
|
||||
error("passphrase too short: %d bytes", len);
|
||||
@ -193,14 +195,15 @@ save_private_key_dsa(const char *filename, const char *passphrase,
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (len > 0) {
|
||||
if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(),
|
||||
(char *)passphrase, strlen(passphrase), NULL, NULL))
|
||||
success = 0;
|
||||
} else {
|
||||
if (!PEM_write_DSAPrivateKey(fp, dsa, NULL,
|
||||
NULL, 0, NULL, NULL))
|
||||
success = 0;
|
||||
switch (key->type) {
|
||||
case KEY_DSA:
|
||||
success = PEM_write_DSAPrivateKey(fp, key->dsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
success = PEM_write_RSAPrivateKey(fp, key->rsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
return success;
|
||||
@ -211,11 +214,12 @@ save_private_key(const char *filename, const char *passphrase, Key *key,
|
||||
const char *comment)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
return save_private_key_rsa(filename, passphrase, key->rsa, comment);
|
||||
case KEY_RSA1:
|
||||
return save_private_key_rsa1(filename, passphrase, key->rsa, comment);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
return save_private_key_dsa(filename, passphrase, key->dsa, comment);
|
||||
case KEY_RSA:
|
||||
return save_private_key_ssh2(filename, passphrase, key, comment);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -257,7 +261,7 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
|
||||
|
||||
/* Check that it is at least big enought to contain the ID string. */
|
||||
if (len < strlen(AUTHFILE_ID_STRING) + 1) {
|
||||
debug("Bad key file %.200s.", filename);
|
||||
debug3("Bad RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return 0;
|
||||
}
|
||||
@ -265,9 +269,9 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
|
||||
for (i = 0; i < (u_int) strlen(AUTHFILE_ID_STRING) + 1; i++)
|
||||
if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
|
||||
debug("Bad key file %.200s.", filename);
|
||||
debug3("Bad RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return 0;
|
||||
}
|
||||
@ -299,10 +303,11 @@ int
|
||||
load_public_key(const char *filename, Key * key, char **comment_return)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
case KEY_RSA1:
|
||||
return load_public_key_rsa(filename, key->rsa, comment_return);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
case KEY_RSA:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -317,14 +322,15 @@ load_public_key(const char *filename, Key * key, char **comment_return)
|
||||
*/
|
||||
|
||||
static int
|
||||
load_private_key_rsa(int fd, const char *filename,
|
||||
load_private_key_rsa1(int fd, const char *filename,
|
||||
const char *passphrase, RSA * prv, char **comment_return)
|
||||
{
|
||||
int i, check1, check2, cipher_type;
|
||||
off_t len;
|
||||
Buffer buffer, decrypted;
|
||||
char *cp;
|
||||
CipherContext cipher;
|
||||
CipherContext ciphercontext;
|
||||
Cipher *cipher;
|
||||
BN_CTX *ctx;
|
||||
BIGNUM *aux;
|
||||
|
||||
@ -336,7 +342,7 @@ load_private_key_rsa(int fd, const char *filename,
|
||||
|
||||
if (read(fd, cp, (size_t) len) != (size_t) len) {
|
||||
debug("Read from key file %.200s failed: %.100s", filename,
|
||||
strerror(errno));
|
||||
strerror(errno));
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
return 0;
|
||||
@ -345,7 +351,7 @@ load_private_key_rsa(int fd, const char *filename,
|
||||
|
||||
/* Check that it is at least big enought to contain the ID string. */
|
||||
if (len < strlen(AUTHFILE_ID_STRING) + 1) {
|
||||
debug("Bad key file %.200s.", filename);
|
||||
debug3("Bad RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return 0;
|
||||
}
|
||||
@ -353,9 +359,9 @@ load_private_key_rsa(int fd, const char *filename,
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
|
||||
if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
|
||||
debug("Bad key file %.200s.", filename);
|
||||
for (i = 0; i < (u_int) strlen(AUTHFILE_ID_STRING) + 1; i++)
|
||||
if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
|
||||
debug3("Bad RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return 0;
|
||||
}
|
||||
@ -375,10 +381,10 @@ load_private_key_rsa(int fd, const char *filename,
|
||||
xfree(buffer_get_string(&buffer, NULL));
|
||||
|
||||
/* Check that it is a supported cipher. */
|
||||
if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
|
||||
(1 << cipher_type)) == 0) {
|
||||
debug("Unsupported cipher %.100s used in key file %.200s.",
|
||||
cipher_name(cipher_type), filename);
|
||||
cipher = cipher_by_number(cipher_type);
|
||||
if (cipher == NULL) {
|
||||
debug("Unsupported cipher %d used in key file %.200s.",
|
||||
cipher_type, filename);
|
||||
buffer_free(&buffer);
|
||||
goto fail;
|
||||
}
|
||||
@ -387,11 +393,10 @@ load_private_key_rsa(int fd, const char *filename,
|
||||
buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
|
||||
|
||||
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
|
||||
cipher_set_key_string(&cipher, cipher_type, passphrase);
|
||||
cipher_decrypt(&cipher, (unsigned char *) cp,
|
||||
(unsigned char *) buffer_ptr(&buffer),
|
||||
buffer_len(&buffer));
|
||||
|
||||
cipher_set_key_string(&ciphercontext, cipher, passphrase);
|
||||
cipher_decrypt(&ciphercontext, (u_char *) cp,
|
||||
(u_char *) buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
buffer_free(&buffer);
|
||||
|
||||
check1 = buffer_get_char(&decrypted);
|
||||
@ -442,40 +447,59 @@ fail:
|
||||
}
|
||||
|
||||
static int
|
||||
load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return)
|
||||
load_private_key_ssh2(int fd, const char *passphrase, Key *k, char **comment_return)
|
||||
{
|
||||
DSA *dsa;
|
||||
BIO *in;
|
||||
FILE *fp;
|
||||
int success = 0;
|
||||
EVP_PKEY *pk = NULL;
|
||||
char *name = "<no key>";
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (in == NULL) {
|
||||
error("BIO_new failed");
|
||||
return 0;
|
||||
}
|
||||
fp = fdopen(fd, "r");
|
||||
if (fp == NULL) {
|
||||
error("fdopen failed");
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(in, fp, BIO_NOCLOSE);
|
||||
dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase);
|
||||
if (dsa == NULL) {
|
||||
debug("PEM_read_bio_DSAPrivateKey failed");
|
||||
} else {
|
||||
/* replace k->dsa with loaded key */
|
||||
DSA_free(k->dsa);
|
||||
k->dsa = dsa;
|
||||
}
|
||||
BIO_free(in);
|
||||
fclose(fp);
|
||||
if (comment_return)
|
||||
*comment_return = xstrdup("dsa w/o comment");
|
||||
debug("read DSA private key done");
|
||||
#ifdef DEBUG_DSS
|
||||
DSA_print_fp(stderr, dsa, 8);
|
||||
pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);
|
||||
if (pk == NULL) {
|
||||
debug("PEM_read_PrivateKey failed");
|
||||
(void)ERR_get_error();
|
||||
} else if (pk->type == EVP_PKEY_RSA) {
|
||||
/* replace k->rsa with loaded key */
|
||||
if (k->type == KEY_RSA || k->type == KEY_UNSPEC) {
|
||||
if (k->rsa != NULL)
|
||||
RSA_free(k->rsa);
|
||||
k->rsa = EVP_PKEY_get1_RSA(pk);
|
||||
k->type = KEY_RSA;
|
||||
name = "rsa w/o comment";
|
||||
success = 1;
|
||||
#ifdef DEBUG_PK
|
||||
RSA_print_fp(stderr, k->rsa, 8);
|
||||
#endif
|
||||
return dsa != NULL ? 1 : 0;
|
||||
}
|
||||
} else if (pk->type == EVP_PKEY_DSA) {
|
||||
/* replace k->dsa with loaded key */
|
||||
if (k->type == KEY_DSA || k->type == KEY_UNSPEC) {
|
||||
if (k->dsa != NULL)
|
||||
DSA_free(k->dsa);
|
||||
k->dsa = EVP_PKEY_get1_DSA(pk);
|
||||
k->type = KEY_DSA;
|
||||
name = "dsa w/o comment";
|
||||
#ifdef DEBUG_PK
|
||||
DSA_print_fp(stderr, k->dsa, 8);
|
||||
#endif
|
||||
success = 1;
|
||||
}
|
||||
} else {
|
||||
error("PEM_read_PrivateKey: mismatch or "
|
||||
"unknown EVP_PKEY save_type %d", pk->save_type);
|
||||
}
|
||||
fclose(fp);
|
||||
if (pk != NULL)
|
||||
EVP_PKEY_free(pk);
|
||||
if (success && comment_return)
|
||||
*comment_return = xstrdup(name);
|
||||
debug("read SSH2 private key done: name %s success %d", name, success);
|
||||
return success;
|
||||
}
|
||||
|
||||
int
|
||||
@ -492,7 +516,7 @@ load_private_key(const char *filename, const char *passphrase, Key *key,
|
||||
|
||||
/* check owner and modes */
|
||||
if (fstat(fd, &st) < 0 ||
|
||||
(st.st_uid != 0 && st.st_uid != getuid()) ||
|
||||
(st.st_uid != 0 && getuid() != 0 && st.st_uid != getuid()) ||
|
||||
(st.st_mode & 077) != 0) {
|
||||
close(fd);
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
@ -504,7 +528,7 @@ load_private_key(const char *filename, const char *passphrase, Key *key,
|
||||
return 0;
|
||||
}
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
case KEY_RSA1:
|
||||
if (key->rsa->e != NULL) {
|
||||
BN_clear_free(key->rsa->e);
|
||||
key->rsa->e = NULL;
|
||||
@ -513,11 +537,13 @@ load_private_key(const char *filename, const char *passphrase, Key *key,
|
||||
BN_clear_free(key->rsa->n);
|
||||
key->rsa->n = NULL;
|
||||
}
|
||||
ret = load_private_key_rsa(fd, filename, passphrase,
|
||||
ret = load_private_key_rsa1(fd, filename, passphrase,
|
||||
key->rsa, comment_return);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
ret = load_private_key_dsa(fd, passphrase, key, comment_return);
|
||||
case KEY_RSA:
|
||||
case KEY_UNSPEC:
|
||||
ret = load_private_key_ssh2(fd, passphrase, key, comment_return);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -529,7 +555,6 @@ static int
|
||||
do_load_public_key(const char *filename, Key *k, char **commentp)
|
||||
{
|
||||
FILE *f;
|
||||
unsigned int bits;
|
||||
char line[1024];
|
||||
char *cp;
|
||||
|
||||
@ -548,8 +573,7 @@ do_load_public_key(const char *filename, Key *k, char **commentp)
|
||||
for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
|
||||
;
|
||||
if (*cp) {
|
||||
bits = key_read(k, &cp);
|
||||
if (bits != 0) {
|
||||
if (key_read(k, &cp) == 1) {
|
||||
if (commentp)
|
||||
*commentp=xstrdup(filename);
|
||||
fclose(f);
|
||||
|
3
crypto/dist/ssh/authfile.h
vendored
3
crypto/dist/ssh/authfile.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: authfile.h,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $ */
|
||||
/* $NetBSD: authfile.h,v 1.1.1.2 2001/01/14 04:50:05 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -16,6 +16,7 @@
|
||||
#ifndef AUTHFILE_H
|
||||
#define AUTHFILE_H
|
||||
|
||||
|
||||
/*
|
||||
* Saves the authentication (private) key in a file, encrypting it with
|
||||
* passphrase.
|
||||
|
32
crypto/dist/ssh/bufaux.c
vendored
32
crypto/dist/ssh/bufaux.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bufaux.c,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $ */
|
||||
/* $NetBSD: bufaux.c,v 1.1.1.2 2001/01/14 04:50:05 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -38,11 +38,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: bufaux.c,v 1.13 2000/09/07 20:27:50 deraadt Exp */
|
||||
/* from OpenBSD: bufaux.c,v 1.14 2000/12/19 23:17:55 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: bufaux.c,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $");
|
||||
__RCSID("$NetBSD: bufaux.c,v 1.1.1.2 2001/01/14 04:50:05 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -62,7 +62,7 @@ buffer_put_bignum(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
int bits = BN_num_bits(value);
|
||||
int bin_size = (bits + 7) / 8;
|
||||
char unsigned *buf = xmalloc(bin_size);
|
||||
u_char *buf = xmalloc(bin_size);
|
||||
int oi;
|
||||
char msg[2];
|
||||
|
||||
@ -89,7 +89,7 @@ int
|
||||
buffer_get_bignum(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
int bits, bytes;
|
||||
unsigned char buf[2], *bin;
|
||||
u_char buf[2], *bin;
|
||||
|
||||
/* Get the number for bits. */
|
||||
buffer_get(buffer, (char *) buf, 2);
|
||||
@ -98,7 +98,7 @@ buffer_get_bignum(Buffer *buffer, BIGNUM *value)
|
||||
bytes = (bits + 7) / 8;
|
||||
if (buffer_len(buffer) < bytes)
|
||||
fatal("buffer_get_bignum: input buffer too small");
|
||||
bin = (unsigned char*) buffer_ptr(buffer);
|
||||
bin = (u_char*) buffer_ptr(buffer);
|
||||
BN_bin2bn(bin, bytes, value);
|
||||
buffer_consume(buffer, bytes);
|
||||
|
||||
@ -112,7 +112,7 @@ void
|
||||
buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
int bytes = BN_num_bytes(value) + 1;
|
||||
unsigned char *buf = xmalloc(bytes);
|
||||
u_char *buf = xmalloc(bytes);
|
||||
int oi;
|
||||
int hasnohigh = 0;
|
||||
buf[0] = '\0';
|
||||
@ -125,7 +125,7 @@ buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
if (value->neg) {
|
||||
/**XXX should be two's-complement */
|
||||
int i, carry;
|
||||
unsigned char *uc = buf;
|
||||
u_char *uc = buf;
|
||||
log("negativ!");
|
||||
for(i = bytes-1, carry = 1; i>=0; i--) {
|
||||
uc[i] ^= 0xff;
|
||||
@ -143,7 +143,7 @@ buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
/**XXX should be two's-complement */
|
||||
int len;
|
||||
unsigned char *bin = (unsigned char *)buffer_get_string(buffer, (unsigned int *)&len);
|
||||
u_char *bin = (u_char *)buffer_get_string(buffer, (u_int *)&len);
|
||||
BN_bin2bn(bin, len, value);
|
||||
xfree(bin);
|
||||
return len;
|
||||
@ -152,10 +152,10 @@ buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
/*
|
||||
* Returns an integer from the buffer (4 bytes, msb first).
|
||||
*/
|
||||
unsigned int
|
||||
u_int
|
||||
buffer_get_int(Buffer *buffer)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
u_char buf[4];
|
||||
buffer_get(buffer, (char *) buf, 4);
|
||||
return GET_32BIT(buf);
|
||||
}
|
||||
@ -164,7 +164,7 @@ buffer_get_int(Buffer *buffer)
|
||||
* Stores an integer in the buffer in 4 bytes, msb first.
|
||||
*/
|
||||
void
|
||||
buffer_put_int(Buffer *buffer, unsigned int value)
|
||||
buffer_put_int(Buffer *buffer, u_int value)
|
||||
{
|
||||
char buf[4];
|
||||
PUT_32BIT(buf, value);
|
||||
@ -180,9 +180,9 @@ buffer_put_int(Buffer *buffer, unsigned int value)
|
||||
* to the returned string, and is not counted in length.
|
||||
*/
|
||||
char *
|
||||
buffer_get_string(Buffer *buffer, unsigned int *length_ptr)
|
||||
buffer_get_string(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
unsigned int len;
|
||||
u_int len;
|
||||
char *value;
|
||||
/* Get the length. */
|
||||
len = buffer_get_int(buffer);
|
||||
@ -204,7 +204,7 @@ buffer_get_string(Buffer *buffer, unsigned int *length_ptr)
|
||||
* Stores and arbitrary binary string in the buffer.
|
||||
*/
|
||||
void
|
||||
buffer_put_string(Buffer *buffer, const void *buf, unsigned int len)
|
||||
buffer_put_string(Buffer *buffer, const void *buf, u_int len)
|
||||
{
|
||||
buffer_put_int(buffer, len);
|
||||
buffer_append(buffer, buf, len);
|
||||
@ -223,7 +223,7 @@ buffer_get_char(Buffer *buffer)
|
||||
{
|
||||
char ch;
|
||||
buffer_get(buffer, &ch, 1);
|
||||
return (unsigned char) ch;
|
||||
return (u_char) ch;
|
||||
}
|
||||
|
||||
/*
|
||||
|
12
crypto/dist/ssh/bufaux.h
vendored
12
crypto/dist/ssh/bufaux.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bufaux.h,v 1.1.1.1 2000/09/28 22:09:46 thorpej Exp $ */
|
||||
/* $NetBSD: bufaux.h,v 1.1.1.2 2001/01/14 04:50:05 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -12,7 +12,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: bufaux.h,v 1.8 2000/09/07 20:27:50 deraadt Exp $ */
|
||||
/* from OpenBSD: bufaux.h,v 1.8 2000/09/07 20:27:50 deraadt Exp */
|
||||
|
||||
#ifndef BUFAUX_H
|
||||
#define BUFAUX_H
|
||||
@ -31,10 +31,10 @@ int buffer_get_bignum(Buffer * buffer, BIGNUM * value);
|
||||
int buffer_get_bignum2(Buffer *buffer, BIGNUM * value);
|
||||
|
||||
/* Returns an integer from the buffer (4 bytes, msb first). */
|
||||
unsigned int buffer_get_int(Buffer * buffer);
|
||||
u_int buffer_get_int(Buffer * buffer);
|
||||
|
||||
/* Stores an integer in the buffer in 4 bytes, msb first. */
|
||||
void buffer_put_int(Buffer * buffer, unsigned int value);
|
||||
void buffer_put_int(Buffer * buffer, u_int value);
|
||||
|
||||
/* Returns a character from the buffer (0 - 255). */
|
||||
int buffer_get_char(Buffer * buffer);
|
||||
@ -50,10 +50,10 @@ void buffer_put_char(Buffer * buffer, int value);
|
||||
* stored there. A null character will be automatically appended to the
|
||||
* returned string, and is not counted in length.
|
||||
*/
|
||||
char *buffer_get_string(Buffer * buffer, unsigned int *length_ptr);
|
||||
char *buffer_get_string(Buffer * buffer, u_int *length_ptr);
|
||||
|
||||
/* Stores and arbitrary binary string in the buffer. */
|
||||
void buffer_put_string(Buffer * buffer, const void *buf, unsigned int len);
|
||||
void buffer_put_string(Buffer * buffer, const void *buf, u_int len);
|
||||
void buffer_put_cstring(Buffer *buffer, const char *s);
|
||||
|
||||
#endif /* BUFAUX_H */
|
||||
|
20
crypto/dist/ssh/buffer.c
vendored
20
crypto/dist/ssh/buffer.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buffer.c,v 1.1.1.1 2000/09/28 22:09:47 thorpej Exp $ */
|
||||
/* $NetBSD: buffer.c,v 1.1.1.2 2001/01/14 04:50:06 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,11 +13,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: buffer.c,v 1.8 2000/09/07 20:27:50 deraadt Exp */
|
||||
/* from OpenBSD: buffer.c,v 1.9 2000/12/19 23:17:55 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: buffer.c,v 1.1.1.1 2000/09/28 22:09:47 thorpej Exp $");
|
||||
__RCSID("$NetBSD: buffer.c,v 1.1.1.2 2001/01/14 04:50:06 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -61,7 +61,7 @@ buffer_clear(Buffer *buffer)
|
||||
/* Appends data to the buffer, expanding it if necessary. */
|
||||
|
||||
void
|
||||
buffer_append(Buffer *buffer, const char *data, unsigned int len)
|
||||
buffer_append(Buffer *buffer, const char *data, u_int len)
|
||||
{
|
||||
char *cp;
|
||||
buffer_append_space(buffer, &cp, len);
|
||||
@ -75,7 +75,7 @@ buffer_append(Buffer *buffer, const char *data, unsigned int len)
|
||||
*/
|
||||
|
||||
void
|
||||
buffer_append_space(Buffer *buffer, char **datap, unsigned int len)
|
||||
buffer_append_space(Buffer *buffer, char **datap, u_int len)
|
||||
{
|
||||
/* If the buffer is empty, start using it from the beginning. */
|
||||
if (buffer->offset == buffer->end) {
|
||||
@ -108,7 +108,7 @@ restart:
|
||||
|
||||
/* Returns the number of bytes of data in the buffer. */
|
||||
|
||||
unsigned int
|
||||
u_int
|
||||
buffer_len(Buffer *buffer)
|
||||
{
|
||||
return buffer->end - buffer->offset;
|
||||
@ -117,7 +117,7 @@ buffer_len(Buffer *buffer)
|
||||
/* Gets data from the beginning of the buffer. */
|
||||
|
||||
void
|
||||
buffer_get(Buffer *buffer, char *buf, unsigned int len)
|
||||
buffer_get(Buffer *buffer, char *buf, u_int len)
|
||||
{
|
||||
if (len > buffer->end - buffer->offset)
|
||||
fatal("buffer_get: trying to get more bytes than in buffer");
|
||||
@ -128,7 +128,7 @@ buffer_get(Buffer *buffer, char *buf, unsigned int len)
|
||||
/* Consumes the given number of bytes from the beginning of the buffer. */
|
||||
|
||||
void
|
||||
buffer_consume(Buffer *buffer, unsigned int bytes)
|
||||
buffer_consume(Buffer *buffer, u_int bytes)
|
||||
{
|
||||
if (bytes > buffer->end - buffer->offset)
|
||||
fatal("buffer_consume: trying to get more bytes than in buffer");
|
||||
@ -138,7 +138,7 @@ buffer_consume(Buffer *buffer, unsigned int bytes)
|
||||
/* Consumes the given number of bytes from the end of the buffer. */
|
||||
|
||||
void
|
||||
buffer_consume_end(Buffer *buffer, unsigned int bytes)
|
||||
buffer_consume_end(Buffer *buffer, u_int bytes)
|
||||
{
|
||||
if (bytes > buffer->end - buffer->offset)
|
||||
fatal("buffer_consume_end: trying to get more bytes than in buffer");
|
||||
@ -159,7 +159,7 @@ void
|
||||
buffer_dump(Buffer *buffer)
|
||||
{
|
||||
int i;
|
||||
unsigned char *ucp = (unsigned char *) buffer->buf;
|
||||
u_char *ucp = (u_char *) buffer->buf;
|
||||
|
||||
for (i = buffer->offset; i < buffer->end; i++)
|
||||
fprintf(stderr, " %02x", ucp[i]);
|
||||
|
22
crypto/dist/ssh/buffer.h
vendored
22
crypto/dist/ssh/buffer.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buffer.h,v 1.1.1.1 2000/09/28 22:09:47 thorpej Exp $ */
|
||||
/* $NetBSD: buffer.h,v 1.1.1.2 2001/01/14 04:50:06 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,16 +13,16 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: buffer.h,v 1.6 2000/09/07 20:27:50 deraadt Exp */
|
||||
/* from OpenBSD: buffer.h,v 1.7 2000/12/19 23:17:55 markus Exp */
|
||||
|
||||
#ifndef BUFFER_H
|
||||
#define BUFFER_H
|
||||
|
||||
typedef struct {
|
||||
char *buf; /* Buffer for data. */
|
||||
unsigned int alloc; /* Number of bytes allocated for data. */
|
||||
unsigned int offset; /* Offset of first byte containing data. */
|
||||
unsigned int end; /* Offset of last byte containing data. */
|
||||
u_int alloc; /* Number of bytes allocated for data. */
|
||||
u_int offset; /* Offset of first byte containing data. */
|
||||
u_int end; /* Offset of last byte containing data. */
|
||||
} Buffer;
|
||||
/* Initializes the buffer structure. */
|
||||
void buffer_init(Buffer * buffer);
|
||||
@ -35,26 +35,26 @@ void buffer_free(Buffer * buffer);
|
||||
void buffer_clear(Buffer * buffer);
|
||||
|
||||
/* Appends data to the buffer, expanding it if necessary. */
|
||||
void buffer_append(Buffer * buffer, const char *data, unsigned int len);
|
||||
void buffer_append(Buffer * buffer, const char *data, u_int len);
|
||||
|
||||
/*
|
||||
* Appends space to the buffer, expanding the buffer if necessary. This does
|
||||
* not actually copy the data into the buffer, but instead returns a pointer
|
||||
* to the allocated region.
|
||||
*/
|
||||
void buffer_append_space(Buffer * buffer, char **datap, unsigned int len);
|
||||
void buffer_append_space(Buffer * buffer, char **datap, u_int len);
|
||||
|
||||
/* Returns the number of bytes of data in the buffer. */
|
||||
unsigned int buffer_len(Buffer * buffer);
|
||||
u_int buffer_len(Buffer * buffer);
|
||||
|
||||
/* Gets data from the beginning of the buffer. */
|
||||
void buffer_get(Buffer * buffer, char *buf, unsigned int len);
|
||||
void buffer_get(Buffer * buffer, char *buf, u_int len);
|
||||
|
||||
/* Consumes the given number of bytes from the beginning of the buffer. */
|
||||
void buffer_consume(Buffer * buffer, unsigned int bytes);
|
||||
void buffer_consume(Buffer * buffer, u_int bytes);
|
||||
|
||||
/* Consumes the given number of bytes from the end of the buffer. */
|
||||
void buffer_consume_end(Buffer * buffer, unsigned int bytes);
|
||||
void buffer_consume_end(Buffer * buffer, u_int bytes);
|
||||
|
||||
/* Returns a pointer to the first used byte in the buffer. */
|
||||
char *buffer_ptr(Buffer * buffer);
|
||||
|
30
crypto/dist/ssh/channels.h
vendored
30
crypto/dist/ssh/channels.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: channels.h,v 1.1.1.1 2000/09/28 22:09:53 thorpej Exp $ */
|
||||
/* $NetBSD: channels.h,v 1.1.1.2 2001/01/14 04:50:12 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -35,7 +35,7 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: channels.h,v 1.20 2000/09/21 11:25:33 markus Exp */
|
||||
/* from OpenBSD: channels.h,v 1.24 2000/12/05 20:34:10 markus Exp */
|
||||
|
||||
#ifndef CHANNELS_H
|
||||
#define CHANNELS_H
|
||||
@ -52,7 +52,9 @@
|
||||
#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */
|
||||
#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */
|
||||
#define SSH_CHANNEL_LARVAL 10 /* larval session */
|
||||
#define SSH_CHANNEL_MAX_TYPE 11
|
||||
#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
|
||||
#define SSH_CHANNEL_CONNECTING 12
|
||||
#define SSH_CHANNEL_MAX_TYPE 13
|
||||
|
||||
/*
|
||||
* Data structure for channel data. This is iniailized in channel_allocate
|
||||
@ -120,7 +122,6 @@ struct Channel {
|
||||
#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2)
|
||||
|
||||
|
||||
void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage);
|
||||
void channel_open(int id);
|
||||
void channel_request(int id, char *service, int wantconfirm);
|
||||
void channel_request_start(int id, char *service, int wantconfirm);
|
||||
@ -132,7 +133,13 @@ Channel *channel_lookup(int id);
|
||||
|
||||
int
|
||||
channel_new(char *ctype, int type, int rfd, int wfd, int efd,
|
||||
int window, int maxpack, int extended_usage, char *remote_name);
|
||||
int window, int maxpack, int extended_usage, char *remote_name,
|
||||
int nonblock);
|
||||
void
|
||||
channel_set_fds(int id, int rfd, int wfd, int efd,
|
||||
int extusage, int nonblock);
|
||||
|
||||
void deny_input_open(int type, int plen, void *ctxt);
|
||||
|
||||
void channel_input_channel_request(int type, int plen, void *ctxt);
|
||||
void channel_input_close(int type, int plen, void *ctxt);
|
||||
@ -145,7 +152,6 @@ void channel_input_open_confirmation(int type, int plen, void *ctxt);
|
||||
void channel_input_open_failure(int type, int plen, void *ctxt);
|
||||
void channel_input_port_open(int type, int plen, void *ctxt);
|
||||
void channel_input_window_adjust(int type, int plen, void *ctxt);
|
||||
void channel_input_open(int type, int plen, void *ctxt);
|
||||
|
||||
/* Sets specific protocol options. */
|
||||
void channel_set_options(int hostname_in_open);
|
||||
@ -200,12 +206,15 @@ char *channel_open_message(void);
|
||||
|
||||
/*
|
||||
* Initiate forwarding of connections to local port "port" through the secure
|
||||
* channel to host:port from remote side. This never returns if there was an
|
||||
* error.
|
||||
* channel to host:port from remote side.
|
||||
*/
|
||||
void
|
||||
channel_request_local_forwarding(u_short port, const char *host,
|
||||
u_short remote_port, int gateway_ports);
|
||||
channel_request_local_forwarding(u_short listen_port,
|
||||
const char *host_to_connect, u_short port_to_connect, int gateway_ports);
|
||||
void
|
||||
channel_request_forwarding(const char *listen_address, u_short listen_port,
|
||||
const char *host_to_connect, u_short port_to_connect, int gateway_ports,
|
||||
int remote_fwd);
|
||||
|
||||
/*
|
||||
* Initiate forwarding of connections to port "port" on remote host through
|
||||
@ -286,6 +295,7 @@ void auth_input_open_request(int type, int plen, void *ctxt);
|
||||
|
||||
/* XXX */
|
||||
int channel_connect_to(const char *host, u_short host_port);
|
||||
int channel_connect_by_listen_adress(u_short listen_port);
|
||||
int x11_connect_display(void);
|
||||
|
||||
#endif
|
||||
|
131
crypto/dist/ssh/cipher.h
vendored
131
crypto/dist/ssh/cipher.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cipher.h,v 1.1.1.1 2000/09/28 22:09:54 thorpej Exp $ */
|
||||
/* $NetBSD: cipher.h,v 1.1.1.2 2001/01/14 04:50:13 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -10,9 +10,31 @@
|
||||
* 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".
|
||||
*
|
||||
* Copyright (c) 2000 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.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: cipher.h,v 1.19 2000/09/07 20:27:50 deraadt Exp */
|
||||
/* from OpenBSD: cipher.h,v 1.25 2000/12/19 23:17:56 markus Exp */
|
||||
|
||||
#ifndef CIPHER_H
|
||||
#define CIPHER_H
|
||||
@ -21,9 +43,12 @@
|
||||
#include <openssl/blowfish.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/cast.h>
|
||||
|
||||
/* Cipher types. New types can be added, but old types should not be removed
|
||||
for compatibility. The maximum allowed value is 31. */
|
||||
#include "rijndael.h"
|
||||
/*
|
||||
* Cipher types for SSH-1. New types can be added, but old types should not
|
||||
* be removed for compatibility. The maximum allowed value is 31.
|
||||
*/
|
||||
#define SSH_CIPHER_SSH2 -3
|
||||
#define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */
|
||||
#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */
|
||||
#define SSH_CIPHER_NONE 0 /* no encryption */
|
||||
@ -34,16 +59,17 @@
|
||||
#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */
|
||||
#define SSH_CIPHER_BLOWFISH 6
|
||||
#define SSH_CIPHER_RESERVED 7
|
||||
#define SSH_CIPHER_MAX 31
|
||||
|
||||
/* these ciphers are used in SSH2: */
|
||||
#define SSH_CIPHER_BLOWFISH_CBC 8
|
||||
#define SSH_CIPHER_3DES_CBC 9
|
||||
#define SSH_CIPHER_ARCFOUR 10 /* Alleged RC4 */
|
||||
#define SSH_CIPHER_CAST128_CBC 11
|
||||
typedef struct Cipher Cipher;
|
||||
typedef struct CipherContext CipherContext;
|
||||
|
||||
typedef struct {
|
||||
unsigned int type;
|
||||
struct CipherContext {
|
||||
union {
|
||||
struct {
|
||||
des_key_schedule key;
|
||||
des_cblock iv;
|
||||
} des;
|
||||
struct {
|
||||
des_key_schedule key1;
|
||||
des_key_schedule key2;
|
||||
@ -53,64 +79,41 @@ typedef struct {
|
||||
} des3;
|
||||
struct {
|
||||
struct bf_key_st key;
|
||||
unsigned char iv[8];
|
||||
u_char iv[8];
|
||||
} bf;
|
||||
struct {
|
||||
CAST_KEY key;
|
||||
unsigned char iv[8];
|
||||
u_char iv[8];
|
||||
} cast;
|
||||
struct {
|
||||
u4byte iv[4];
|
||||
rijndael_ctx enc;
|
||||
rijndael_ctx dec;
|
||||
} rijndael;
|
||||
RC4_KEY rc4;
|
||||
} u;
|
||||
} CipherContext;
|
||||
/*
|
||||
* Returns a bit mask indicating which ciphers are supported by this
|
||||
* implementation. The bit mask has the corresponding bit set of each
|
||||
* supported cipher.
|
||||
*/
|
||||
unsigned int cipher_mask(void);
|
||||
unsigned int cipher_mask1(void);
|
||||
unsigned int cipher_mask2(void);
|
||||
Cipher *cipher;
|
||||
};
|
||||
struct Cipher {
|
||||
char *name;
|
||||
int number; /* for ssh1 only */
|
||||
u_int block_size;
|
||||
u_int key_len;
|
||||
void (*setkey)(CipherContext *, const u_char *, u_int);
|
||||
void (*setiv)(CipherContext *, const u_char *, u_int);
|
||||
void (*encrypt)(CipherContext *, u_char *, const u_char *, u_int);
|
||||
void (*decrypt)(CipherContext *, u_char *, const u_char *, u_int);
|
||||
};
|
||||
|
||||
/* Returns the name of the cipher. */
|
||||
const char *cipher_name(int cipher);
|
||||
|
||||
/*
|
||||
* Parses the name of the cipher. Returns the number of the corresponding
|
||||
* cipher, or -1 on error.
|
||||
*/
|
||||
int cipher_number(const char *name);
|
||||
|
||||
/* returns 1 if all ciphers are supported (ssh2 only) */
|
||||
int ciphers_valid(const char *names);
|
||||
|
||||
/*
|
||||
* Selects the cipher to use and sets the key. If for_encryption is true,
|
||||
* the key is setup for encryption; otherwise it is setup for decryption.
|
||||
*/
|
||||
void
|
||||
cipher_set_key(CipherContext * context, int cipher,
|
||||
const unsigned char *key, int keylen);
|
||||
void
|
||||
cipher_set_key_iv(CipherContext * context, int cipher,
|
||||
const unsigned char *key, int keylen,
|
||||
const unsigned char *iv, int ivlen);
|
||||
|
||||
/*
|
||||
* Sets key for the cipher by computing the MD5 checksum of the passphrase,
|
||||
* and using the resulting 16 bytes as the key.
|
||||
*/
|
||||
void
|
||||
cipher_set_key_string(CipherContext * context, int cipher,
|
||||
const char *passphrase);
|
||||
|
||||
/* Encrypts data using the cipher. */
|
||||
void
|
||||
cipher_encrypt(CipherContext * context, unsigned char *dest,
|
||||
const unsigned char *src, unsigned int len);
|
||||
|
||||
/* Decrypts data using the cipher. */
|
||||
void
|
||||
cipher_decrypt(CipherContext * context, unsigned char *dest,
|
||||
const unsigned char *src, unsigned int len);
|
||||
u_int cipher_mask_ssh1(int client);
|
||||
Cipher *cipher_by_name(const char *name);
|
||||
Cipher *cipher_by_number(int id);
|
||||
int cipher_number(const char *name);
|
||||
char *cipher_name(int id);
|
||||
int ciphers_valid(const char *names);
|
||||
void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, const u_char *, u_int);
|
||||
void cipher_encrypt(CipherContext *context, u_char *dest, const u_char *src, u_int len);
|
||||
void cipher_decrypt(CipherContext *context, u_char *dest, const u_char *src, u_int len);
|
||||
void cipher_set_key_string(CipherContext *context, Cipher *cipher, const char *passphrase);
|
||||
|
||||
#endif /* CIPHER_H */
|
||||
|
205
crypto/dist/ssh/cli.c
vendored
Normal file
205
crypto/dist/ssh/cli.c
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
/* $NetBSD: cli.c,v 1.1.1.1 2001/01/14 04:51:06 itojun Exp $ */
|
||||
|
||||
/* from OpenBSD: cli.c,v 1.2 2000/10/16 09:38:44 djm Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: cli.c,v 1.1.1.1 2001/01/14 04:51:06 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include <vis.h>
|
||||
#include "cli.h"
|
||||
|
||||
static int cli_input = -1;
|
||||
static int cli_output = -1;
|
||||
static int cli_from_stdin = 0;
|
||||
|
||||
sigset_t oset;
|
||||
sigset_t nset;
|
||||
struct sigaction nsa;
|
||||
struct sigaction osa;
|
||||
struct termios ntio;
|
||||
struct termios otio;
|
||||
int echo_modified;
|
||||
|
||||
volatile int intr;
|
||||
|
||||
static int
|
||||
cli_open(int from_stdin)
|
||||
{
|
||||
if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin)
|
||||
return 1;
|
||||
|
||||
if (from_stdin) {
|
||||
if (!cli_from_stdin && cli_input >= 0) {
|
||||
(void)close(cli_input);
|
||||
}
|
||||
cli_input = STDIN_FILENO;
|
||||
cli_output = STDERR_FILENO;
|
||||
} else {
|
||||
cli_input = cli_output = open("/dev/tty", O_RDWR);
|
||||
if (cli_input < 0)
|
||||
fatal("You have no controlling tty. Cannot read passphrase.");
|
||||
}
|
||||
|
||||
cli_from_stdin = from_stdin;
|
||||
|
||||
return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_close(void)
|
||||
{
|
||||
if (!cli_from_stdin && cli_input >= 0)
|
||||
close(cli_input);
|
||||
cli_input = -1;
|
||||
cli_output = -1;
|
||||
cli_from_stdin = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
intrcatch(int sig)
|
||||
{
|
||||
intr = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_disable(void)
|
||||
{
|
||||
sigemptyset(&nset);
|
||||
sigaddset(&nset, SIGTSTP);
|
||||
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
|
||||
intr = 0;
|
||||
|
||||
memset(&nsa, 0, sizeof(nsa));
|
||||
nsa.sa_handler = intrcatch;
|
||||
(void) sigaction(SIGINT, &nsa, &osa);
|
||||
|
||||
echo_modified = 0;
|
||||
if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) {
|
||||
echo_modified = 1;
|
||||
ntio = otio;
|
||||
ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
(void) tcsetattr(cli_input, TCSANOW, &ntio);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_restore(void)
|
||||
{
|
||||
if (echo_modified != 0) {
|
||||
tcsetattr(cli_input, TCSANOW, &otio);
|
||||
echo_modified = 0;
|
||||
}
|
||||
|
||||
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
(void) sigaction(SIGINT, &osa, NULL);
|
||||
|
||||
if (intr != 0) {
|
||||
kill(getpid(), SIGINT);
|
||||
sigemptyset(&nset);
|
||||
/* XXX tty has not neccessarily drained by now? */
|
||||
sigsuspend(&nset);
|
||||
intr = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_read(char* buf, int size, int echo)
|
||||
{
|
||||
char ch = 0;
|
||||
int i = 0;
|
||||
|
||||
if (!echo)
|
||||
cli_echo_disable();
|
||||
|
||||
while (ch != '\n') {
|
||||
if (read(cli_input, &ch, 1) != 1)
|
||||
break;
|
||||
if (ch == '\n' || intr != 0)
|
||||
break;
|
||||
if (i < size)
|
||||
buf[i++] = ch;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
if (!echo)
|
||||
cli_echo_restore();
|
||||
if (!intr && !echo)
|
||||
(void) write(cli_output, "\n", 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_write(char* buf, int size)
|
||||
{
|
||||
int i, len, pos, ret = 0;
|
||||
char *output, *p;
|
||||
|
||||
output = xmalloc(4*size);
|
||||
for (p = output, i = 0; i < size; i++) {
|
||||
if (buf[i] == '\n')
|
||||
*p++ = buf[i];
|
||||
else
|
||||
p = vis(p, buf[i], 0, 0);
|
||||
}
|
||||
len = p - output;
|
||||
|
||||
for (pos = 0; pos < len; pos += ret) {
|
||||
ret = write(cli_output, output + pos, len - pos);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char*
|
||||
cli_read_passphrase(char* prompt, int from_stdin, int echo_enable)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char* p;
|
||||
|
||||
if (!cli_open(from_stdin))
|
||||
fatal("Cannot read passphrase.");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
cli_write(prompt, strlen(prompt));
|
||||
cli_read(buf, sizeof buf, echo_enable);
|
||||
|
||||
cli_close();
|
||||
|
||||
p = xstrdup(buf);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return (p);
|
||||
}
|
||||
|
||||
char*
|
||||
cli_prompt(char* prompt, int echo_enable)
|
||||
{
|
||||
return cli_read_passphrase(prompt, 0, echo_enable);
|
||||
}
|
||||
|
||||
void
|
||||
cli_mesg(char* mesg)
|
||||
{
|
||||
cli_open(0);
|
||||
cli_write(mesg, strlen(mesg));
|
||||
cli_write("\n", strlen("\n"));
|
||||
cli_close();
|
||||
return;
|
||||
}
|
16
crypto/dist/ssh/cli.h
vendored
Normal file
16
crypto/dist/ssh/cli.h
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/* $OpenBSD: cli.h,v 1.2 2000/10/16 09:38:44 djm Exp $ */
|
||||
|
||||
#ifndef CLI_H
|
||||
#define CLI_H
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char* cli_read_passphrase(char* prompt, int from_stdin, int echo_enable);
|
||||
char* cli_prompt(char* prompt, int echo_enable);
|
||||
void cli_mesg(char* mesg);
|
||||
|
||||
#endif /* CLI_H */
|
55
crypto/dist/ssh/compat.c
vendored
55
crypto/dist/ssh/compat.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compat.c,v 1.1.1.1 2000/09/28 22:10:00 thorpej Exp $ */
|
||||
/* $NetBSD: compat.c,v 1.1.1.2 2001/01/14 04:50:16 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: compat.c,v 1.23 2000/09/07 21:13:37 markus Exp */
|
||||
/* from OpenBSD: compat.c,v 1.32 2000/12/09 23:51:11 provos Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: compat.c,v 1.1.1.1 2000/09/28 22:10:00 thorpej Exp $");
|
||||
__RCSID("$NetBSD: compat.c,v 1.1.1.2 2001/01/14 04:50:16 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -37,6 +37,7 @@ __RCSID("$NetBSD: compat.c,v 1.1.1.1 2000/09/28 22:10:00 thorpej Exp $");
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "compat.h"
|
||||
#include <regex.h>
|
||||
|
||||
int compat13 = 0;
|
||||
int compat20 = 0;
|
||||
@ -58,27 +59,49 @@ enable_compat13(void)
|
||||
void
|
||||
compat_datafellows(const char *version)
|
||||
{
|
||||
int i;
|
||||
size_t len;
|
||||
struct {
|
||||
char *version;
|
||||
int i, ret;
|
||||
char ebuf[1024];
|
||||
regex_t reg;
|
||||
static struct {
|
||||
char *pat;
|
||||
int bugs;
|
||||
} check[] = {
|
||||
{"2.1.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC},
|
||||
{"2.0.1", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD},
|
||||
{"2.", SSH_BUG_HMAC|SSH_COMPAT_SESSIONID_ENCODING},
|
||||
{NULL, 0}
|
||||
{ "^OpenSSH[-_]2\\.[012]", SSH_OLD_SESSIONID },
|
||||
{ "MindTerm", 0 },
|
||||
{ "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG },
|
||||
{ "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD },
|
||||
{ "^2\\.0\\.", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
|
||||
SSH_BUG_PKAUTH },
|
||||
{ "^2\\.[23]\\.0", SSH_BUG_HMAC},
|
||||
{ "^2\\.[2-9]\\.", 0 },
|
||||
{ "^2\\.4$", SSH_OLD_SESSIONID}, /* Van Dyke */
|
||||
{ "^3\\.0 SecureCRT", SSH_OLD_SESSIONID},
|
||||
{ "^1\\.7 SecureFX", SSH_OLD_SESSIONID},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
/* process table, return first match */
|
||||
for (i = 0; check[i].version; i++) {
|
||||
len = strlen(check[i].version);
|
||||
if (strlen(version) >= len &&
|
||||
(strncmp(version, check[i].version, len) == 0)) {
|
||||
verbose("datafellows: %.200s", version);
|
||||
for (i = 0; check[i].pat; i++) {
|
||||
ret = regcomp(®, check[i].pat, REG_EXTENDED|REG_NOSUB);
|
||||
if (ret != 0) {
|
||||
regerror(ret, ®, ebuf, sizeof(ebuf));
|
||||
ebuf[sizeof(ebuf)-1] = '\0';
|
||||
error("regerror: %s", ebuf);
|
||||
continue;
|
||||
}
|
||||
ret = regexec(®, version, 0, NULL, 0);
|
||||
regfree(®);
|
||||
if (ret == 0) {
|
||||
debug("match: %s pat %s", version, check[i].pat);
|
||||
datafellows = check[i].bugs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug("no match: %s", version);
|
||||
}
|
||||
|
||||
#define SEP ","
|
||||
|
10
crypto/dist/ssh/compat.h
vendored
10
crypto/dist/ssh/compat.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compat.h,v 1.1.1.1 2000/09/28 22:10:00 thorpej Exp $ */
|
||||
/* $NetBSD: compat.h,v 1.1.1.2 2001/01/14 04:50:16 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
@ -24,7 +24,7 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: compat.h,v 1.10 2000/09/07 20:27:50 deraadt Exp */
|
||||
/* from OpenBSD: compat.h,v 1.13 2000/12/06 22:58:15 markus Exp */
|
||||
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
@ -35,10 +35,12 @@
|
||||
#define SSH_PROTO_2 0x04
|
||||
|
||||
#define SSH_BUG_SIGBLOB 0x01
|
||||
#define SSH_BUG_PUBKEYAUTH 0x02
|
||||
#define SSH_BUG_PKSERVICE 0x02
|
||||
#define SSH_BUG_HMAC 0x04
|
||||
#define SSH_BUG_X11FWD 0x08
|
||||
#define SSH_COMPAT_SESSIONID_ENCODING 0x10
|
||||
#define SSH_OLD_SESSIONID 0x10
|
||||
#define SSH_BUG_PKAUTH 0x20
|
||||
#define SSH_BUG_DEBUG 0x40
|
||||
|
||||
void enable_compat13(void);
|
||||
void enable_compat20(void);
|
||||
|
16
crypto/dist/ssh/compress.c
vendored
16
crypto/dist/ssh/compress.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compress.c,v 1.1.1.1 2000/09/28 22:10:00 thorpej Exp $ */
|
||||
/* $NetBSD: compress.c,v 1.1.1.2 2001/01/14 04:50:16 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,11 +13,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: compress.c,v 1.9 2000/09/07 20:27:50 deraadt Exp */
|
||||
/* from OpenBSD: compress.c,v 1.11 2000/12/20 19:37:21 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: compress.c,v 1.1.1.1 2000/09/28 22:10:00 thorpej Exp $");
|
||||
__RCSID("$NetBSD: compress.c,v 1.1.1.2 2001/01/14 04:50:16 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -48,7 +48,7 @@ buffer_compress_init(int level)
|
||||
/* Frees any data structures allocated for compression. */
|
||||
|
||||
void
|
||||
buffer_compress_uninit()
|
||||
buffer_compress_uninit(void)
|
||||
{
|
||||
debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f",
|
||||
outgoing_stream.total_in, outgoing_stream.total_out,
|
||||
@ -82,13 +82,13 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
|
||||
return;
|
||||
|
||||
/* Input is the contents of the input buffer. */
|
||||
outgoing_stream.next_in = (unsigned char *) buffer_ptr(input_buffer);
|
||||
outgoing_stream.next_in = (u_char *) buffer_ptr(input_buffer);
|
||||
outgoing_stream.avail_in = buffer_len(input_buffer);
|
||||
|
||||
/* Loop compressing until deflate() returns with avail_out != 0. */
|
||||
do {
|
||||
/* Set up fixed-size output buffer. */
|
||||
outgoing_stream.next_out = (unsigned char *)buf;
|
||||
outgoing_stream.next_out = (u_char *)buf;
|
||||
outgoing_stream.avail_out = sizeof(buf);
|
||||
|
||||
/* Compress as much data into the buffer as possible. */
|
||||
@ -121,12 +121,12 @@ buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
|
||||
char buf[4096];
|
||||
int status;
|
||||
|
||||
incoming_stream.next_in = (unsigned char *) buffer_ptr(input_buffer);
|
||||
incoming_stream.next_in = (u_char *) buffer_ptr(input_buffer);
|
||||
incoming_stream.avail_in = buffer_len(input_buffer);
|
||||
|
||||
for (;;) {
|
||||
/* Set up fixed-size output buffer. */
|
||||
incoming_stream.next_out = (unsigned char *) buf;
|
||||
incoming_stream.next_out = (u_char *) buf;
|
||||
incoming_stream.avail_out = sizeof(buf);
|
||||
|
||||
status = inflate(&incoming_stream, Z_PARTIAL_FLUSH);
|
||||
|
4
crypto/dist/ssh/compress.h
vendored
4
crypto/dist/ssh/compress.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compress.h,v 1.1.1.1 2000/09/28 22:10:00 thorpej Exp $ */
|
||||
/* $NetBSD: compress.h,v 1.1.1.2 2001/01/14 04:50:16 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,7 +13,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: compress.h,v 1.6 2000/09/07 20:27:50 deraadt Exp */
|
||||
/* from OpenBSD: compress.h,v 1.7 2000/12/20 19:37:22 markus Exp */
|
||||
|
||||
#ifndef COMPRESS_H
|
||||
#define COMPRESS_H
|
||||
|
20
crypto/dist/ssh/crc32.c
vendored
20
crypto/dist/ssh/crc32.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: crc32.c,v 1.1.1.1 2000/09/28 22:10:01 thorpej Exp $ */
|
||||
/* $NetBSD: crc32.c,v 1.1.1.2 2001/01/14 04:50:17 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||
@ -33,22 +33,24 @@
|
||||
* 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 unsigned (bring in zeroes). On some
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* from OpenBSD: crc32.c,v 1.7 2000/09/07 20:27:51 deraadt Exp */
|
||||
/* from OpenBSD: crc32.c,v 1.8 2000/12/19 23:17:56 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: crc32.c,v 1.1.1.1 2000/09/28 22:10:01 thorpej Exp $");
|
||||
__RCSID("$NetBSD: crc32.c,v 1.1.1.2 2001/01/14 04:50:17 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "crc32.h"
|
||||
|
||||
static unsigned int crc32_tab[] = {
|
||||
static u_int crc32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
@ -105,11 +107,11 @@ static unsigned int crc32_tab[] = {
|
||||
|
||||
/* Return a 32-bit CRC of the contents of the buffer. */
|
||||
|
||||
unsigned int
|
||||
ssh_crc32(const unsigned char *s, unsigned int len)
|
||||
u_int
|
||||
ssh_crc32(const u_char *s, u_int len)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int crc32val;
|
||||
u_int i;
|
||||
u_int crc32val;
|
||||
|
||||
crc32val = 0;
|
||||
for (i = 0; i < len; i ++) {
|
||||
|
6
crypto/dist/ssh/crc32.h
vendored
6
crypto/dist/ssh/crc32.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: crc32.h,v 1.1.1.1 2000/09/28 22:10:01 thorpej Exp $ */
|
||||
/* $NetBSD: crc32.h,v 1.1.1.2 2001/01/14 04:50:17 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,7 +13,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: crc32.h,v 1.8 2000/09/07 20:27:51 deraadt Exp */
|
||||
/* from OpenBSD: crc32.h,v 1.9 2000/12/19 23:17:56 markus Exp */
|
||||
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
@ -22,6 +22,6 @@
|
||||
* This computes a 32 bit CRC of the data in the buffer, and returns the CRC.
|
||||
* The polynomial used is 0xedb88320.
|
||||
*/
|
||||
unsigned int ssh_crc32(const unsigned char *buf, unsigned int len);
|
||||
u_int ssh_crc32(const u_char *buf, u_int len);
|
||||
|
||||
#endif /* CRC32_H */
|
||||
|
4
crypto/dist/ssh/deattack.h
vendored
4
crypto/dist/ssh/deattack.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: deattack.h,v 1.1.1.1 2000/09/28 22:10:01 thorpej Exp $ */
|
||||
/* $NetBSD: deattack.h,v 1.1.1.2 2001/01/14 04:50:17 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Cryptographic attack detector for ssh - Header file
|
||||
@ -26,5 +26,5 @@
|
||||
#define DEATTACK_OK 0
|
||||
#define DEATTACK_DETECTED 1
|
||||
|
||||
int detect_attack(unsigned char *buf, u_int32_t len, unsigned char IV[8]);
|
||||
int detect_attack(u_char *buf, u_int32_t len, u_char IV[8]);
|
||||
#endif
|
||||
|
167
crypto/dist/ssh/dh.c
vendored
Normal file
167
crypto/dist/ssh/dh.c
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
/* $NetBSD: dh.c,v 1.1.1.1 2001/01/14 04:51:06 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. 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.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: dh.c,v 1.3 2000/11/16 17:55:43 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: dh.c,v 1.1.1.1 2001/01/14 04:51:06 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "pathnames.h"
|
||||
#include "buffer.h"
|
||||
#include "kex.h"
|
||||
#include "dh.h"
|
||||
|
||||
static int
|
||||
parse_prime(int linenum, char *line, struct dhgroup *dhg)
|
||||
{
|
||||
char *cp, *arg;
|
||||
char *strsize, *gen, *prime;
|
||||
|
||||
cp = line;
|
||||
arg = strdelim(&cp);
|
||||
/* Ignore leading whitespace */
|
||||
if (*arg == '\0')
|
||||
arg = strdelim(&cp);
|
||||
if (!*arg || *arg == '#')
|
||||
return 0;
|
||||
|
||||
/* time */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
arg = strsep(&cp, " "); /* type */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
arg = strsep(&cp, " "); /* tests */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
arg = strsep(&cp, " "); /* tries */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
strsize = strsep(&cp, " "); /* size */
|
||||
if (cp == NULL || *strsize == '\0' ||
|
||||
(dhg->size = atoi(strsize)) == 0)
|
||||
goto fail;
|
||||
gen = strsep(&cp, " "); /* gen */
|
||||
if (cp == NULL || *gen == '\0')
|
||||
goto fail;
|
||||
prime = strsep(&cp, " "); /* prime */
|
||||
if (cp != NULL || *prime == '\0')
|
||||
goto fail;
|
||||
|
||||
dhg->g = BN_new();
|
||||
if (BN_hex2bn(&dhg->g, gen) < 0) {
|
||||
BN_free(dhg->g);
|
||||
goto fail;
|
||||
}
|
||||
dhg->p = BN_new();
|
||||
if (BN_hex2bn(&dhg->p, prime) < 0) {
|
||||
BN_free(dhg->g);
|
||||
BN_free(dhg->p);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return (1);
|
||||
fail:
|
||||
fprintf(stderr, "Bad prime description in line %d\n", linenum);
|
||||
return (0);
|
||||
}
|
||||
|
||||
DH *
|
||||
choose_dh(int minbits)
|
||||
{
|
||||
FILE *f;
|
||||
char line[1024];
|
||||
int best, bestcount, which;
|
||||
int linenum;
|
||||
struct dhgroup dhg;
|
||||
|
||||
f = fopen(_PATH_DH_PRIMES, "r");
|
||||
if (!f) {
|
||||
log("WARNING: %s does not exist, using old prime", _PATH_DH_PRIMES);
|
||||
return (dh_new_group1());
|
||||
}
|
||||
|
||||
linenum = 0;
|
||||
best = bestcount = 0;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
linenum++;
|
||||
if (!parse_prime(linenum, line, &dhg))
|
||||
continue;
|
||||
BN_free(dhg.g);
|
||||
BN_free(dhg.p);
|
||||
|
||||
if ((dhg.size > minbits && dhg.size < best) ||
|
||||
(dhg.size > best && best < minbits)) {
|
||||
best = dhg.size;
|
||||
bestcount = 0;
|
||||
}
|
||||
if (dhg.size == best)
|
||||
bestcount++;
|
||||
}
|
||||
fclose (f);
|
||||
|
||||
if (bestcount == 0) {
|
||||
log("WARNING: no primes in %s, using old prime", _PATH_DH_PRIMES);
|
||||
return (dh_new_group1());
|
||||
}
|
||||
|
||||
f = fopen(_PATH_DH_PRIMES, "r");
|
||||
if (!f) {
|
||||
fatal("WARNING: %s dissappeared, giving up", _PATH_DH_PRIMES);
|
||||
}
|
||||
|
||||
linenum = 0;
|
||||
/* XXXthorpej */
|
||||
RAND_pseudo_bytes((u_char *)&which, sizeof(which));
|
||||
which %= bestcount;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
if (!parse_prime(linenum, line, &dhg))
|
||||
continue;
|
||||
if (dhg.size != best)
|
||||
continue;
|
||||
if (linenum++ != which) {
|
||||
BN_free(dhg.g);
|
||||
BN_free(dhg.p);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
return (dh_new_group(dhg.g, dhg.p));
|
||||
}
|
35
crypto/dist/ssh/dh.h
vendored
Normal file
35
crypto/dist/ssh/dh.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. 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.
|
||||
*/
|
||||
#ifndef DH_H
|
||||
#define DH_H
|
||||
|
||||
struct dhgroup {
|
||||
int size;
|
||||
BIGNUM *g;
|
||||
BIGNUM *p;
|
||||
};
|
||||
|
||||
DH *choose_dh(int minbits);
|
||||
|
||||
#endif
|
28
crypto/dist/ssh/getput.h
vendored
28
crypto/dist/ssh/getput.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: getput.h,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $ */
|
||||
/* $NetBSD: getput.h,v 1.1.1.2 2001/01/14 04:50:19 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,20 +13,20 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: getput.h,v 1.5 2000/09/07 20:27:51 deraadt Exp */
|
||||
/* from OpenBSD: getput.h,v 1.6 2000/12/19 23:17:56 markus Exp */
|
||||
|
||||
#ifndef GETPUT_H
|
||||
#define GETPUT_H
|
||||
|
||||
/*------------ macros for storing/extracting msb first words -------------*/
|
||||
|
||||
#define GET_32BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 24) | \
|
||||
((unsigned long)(unsigned char)(cp)[1] << 16) | \
|
||||
((unsigned long)(unsigned char)(cp)[2] << 8) | \
|
||||
((unsigned long)(unsigned char)(cp)[3]))
|
||||
#define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \
|
||||
((u_long)(u_char)(cp)[1] << 16) | \
|
||||
((u_long)(u_char)(cp)[2] << 8) | \
|
||||
((u_long)(u_char)(cp)[3]))
|
||||
|
||||
#define GET_16BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 8) | \
|
||||
((unsigned long)(unsigned char)(cp)[1]))
|
||||
#define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \
|
||||
((u_long)(u_char)(cp)[1]))
|
||||
|
||||
#define PUT_32BIT(cp, value) do { \
|
||||
(cp)[0] = (value) >> 24; \
|
||||
@ -41,14 +41,14 @@
|
||||
/*------------ macros for storing/extracting lsb first words -------------*/
|
||||
|
||||
#define GET_32BIT_LSB_FIRST(cp) \
|
||||
(((unsigned long)(unsigned char)(cp)[0]) | \
|
||||
((unsigned long)(unsigned char)(cp)[1] << 8) | \
|
||||
((unsigned long)(unsigned char)(cp)[2] << 16) | \
|
||||
((unsigned long)(unsigned char)(cp)[3] << 24))
|
||||
(((u_long)(u_char)(cp)[0]) | \
|
||||
((u_long)(u_char)(cp)[1] << 8) | \
|
||||
((u_long)(u_char)(cp)[2] << 16) | \
|
||||
((u_long)(u_char)(cp)[3] << 24))
|
||||
|
||||
#define GET_16BIT_LSB_FIRST(cp) \
|
||||
(((unsigned long)(unsigned char)(cp)[0]) | \
|
||||
((unsigned long)(unsigned char)(cp)[1] << 8))
|
||||
(((u_long)(u_char)(cp)[0]) | \
|
||||
((u_long)(u_char)(cp)[1] << 8))
|
||||
|
||||
#define PUT_32BIT_LSB_FIRST(cp, value) do { \
|
||||
(cp)[0] = (value); \
|
||||
|
18
crypto/dist/ssh/hmac.c
vendored
18
crypto/dist/ssh/hmac.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hmac.c,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $ */
|
||||
/* $NetBSD: hmac.c,v 1.1.1.2 2001/01/14 04:50:19 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: hmac.c,v 1.4 2000/09/07 20:27:51 deraadt Exp */
|
||||
/* from OpenBSD: hmac.c,v 1.5 2000/12/19 23:17:56 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: hmac.c,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $");
|
||||
__RCSID("$NetBSD: hmac.c,v 1.1.1.2 2001/01/14 04:50:19 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -41,16 +41,16 @@ __RCSID("$NetBSD: hmac.c,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $");
|
||||
|
||||
#include "hmac.h"
|
||||
|
||||
unsigned char *
|
||||
u_char *
|
||||
hmac(
|
||||
EVP_MD *evp_md,
|
||||
unsigned int seqno,
|
||||
unsigned char *data, int datalen,
|
||||
unsigned char *key, int keylen)
|
||||
u_int seqno,
|
||||
u_char *data, int datalen,
|
||||
u_char *key, int keylen)
|
||||
{
|
||||
HMAC_CTX c;
|
||||
static unsigned char m[EVP_MAX_MD_SIZE];
|
||||
unsigned char b[4];
|
||||
static u_char m[EVP_MAX_MD_SIZE];
|
||||
u_char b[4];
|
||||
|
||||
if (key == NULL)
|
||||
fatal("hmac: no key");
|
||||
|
10
crypto/dist/ssh/hmac.h
vendored
10
crypto/dist/ssh/hmac.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hmac.h,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $ */
|
||||
/* $NetBSD: hmac.h,v 1.1.1.2 2001/01/14 04:50:19 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -27,11 +27,11 @@
|
||||
#ifndef HMAC_H
|
||||
#define HMAC_H
|
||||
|
||||
unsigned char *
|
||||
u_char *
|
||||
hmac(
|
||||
EVP_MD *evp_md,
|
||||
unsigned int seqno,
|
||||
unsigned char *data, int datalen,
|
||||
unsigned char *key, int len);
|
||||
u_int seqno,
|
||||
u_char *data, int datalen,
|
||||
u_char *key, int len);
|
||||
|
||||
#endif
|
||||
|
30
crypto/dist/ssh/hostfile.c
vendored
30
crypto/dist/ssh/hostfile.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hostfile.c,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $ */
|
||||
/* $NetBSD: hostfile.c,v 1.1.1.2 2001/01/14 04:50:20 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -37,11 +37,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: hostfile.c,v 1.20 2000/09/07 20:27:51 deraadt Exp */
|
||||
/* from OpenBSD: hostfile.c,v 1.23 2000/12/21 15:10:16 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: hostfile.c,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $");
|
||||
__RCSID("$NetBSD: hostfile.c,v 1.1.1.2 2001/01/14 04:50:20 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -60,17 +60,15 @@ __RCSID("$NetBSD: hostfile.c,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $");
|
||||
*/
|
||||
|
||||
static int
|
||||
hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
|
||||
hostfile_read_key(char **cpp, u_int *bitsp, Key *ret)
|
||||
{
|
||||
unsigned int bits;
|
||||
char *cp;
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
|
||||
bits = key_read(ret, &cp);
|
||||
if (bits == 0)
|
||||
if (key_read(ret, &cp) != 1)
|
||||
return 0;
|
||||
|
||||
/* Skip trailing whitespace. */
|
||||
@ -79,14 +77,14 @@ hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
|
||||
|
||||
/* Return results. */
|
||||
*cpp = cp;
|
||||
*bitsp = bits;
|
||||
*bitsp = key_size(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
|
||||
auth_rsa_read_key(char **cpp, u_int *bitsp, BIGNUM * e, BIGNUM * n)
|
||||
{
|
||||
Key *k = key_new(KEY_RSA);
|
||||
Key *k = key_new(KEY_RSA1);
|
||||
int ret = hostfile_read_key(cpp, bitsp, k);
|
||||
BN_copy(e, k->rsa->e);
|
||||
BN_copy(n, k->rsa->n);
|
||||
@ -97,7 +95,7 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
|
||||
static int
|
||||
hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum)
|
||||
{
|
||||
if (key == NULL || key->type != KEY_RSA || key->rsa == NULL)
|
||||
if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL)
|
||||
return 1;
|
||||
if (bits != BN_num_bits(key->rsa->n)) {
|
||||
log("Warning: %s, line %d: keysize mismatch for host %s: "
|
||||
@ -117,12 +115,13 @@ hostfile_check_key(int bits, Key *key, const char *host, const char *filename, i
|
||||
*/
|
||||
|
||||
HostStatus
|
||||
check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found)
|
||||
check_host_in_hostfile(const char *filename, const char *host, Key *key,
|
||||
Key *found, int *numret)
|
||||
{
|
||||
FILE *f;
|
||||
char line[8192];
|
||||
int linenum = 0;
|
||||
unsigned int kbits, hostlen;
|
||||
u_int kbits, hostlen;
|
||||
char *cp, *cp2;
|
||||
HostStatus end_return;
|
||||
|
||||
@ -159,7 +158,7 @@ check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *fo
|
||||
;
|
||||
|
||||
/* Check if the host name matches. */
|
||||
if (match_hostname(host, cp, (unsigned int) (cp2 - cp)) != 1)
|
||||
if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1)
|
||||
continue;
|
||||
|
||||
/* Got a match. Skip host name. */
|
||||
@ -174,6 +173,9 @@ check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *fo
|
||||
if (!hostfile_check_key(kbits, found, host, filename, linenum))
|
||||
continue;
|
||||
|
||||
if (numret != NULL)
|
||||
*numret = linenum;
|
||||
|
||||
/* Check if the current key is the same as the given key. */
|
||||
if (key_equal(key, found)) {
|
||||
/* Ok, they match. */
|
||||
|
6
crypto/dist/ssh/hostfile.h
vendored
6
crypto/dist/ssh/hostfile.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hostfile.h,v 1.1.1.1 2000/09/28 22:10:02 thorpej Exp $ */
|
||||
/* $NetBSD: hostfile.h,v 1.1.1.2 2001/01/14 04:50:20 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -24,8 +24,10 @@
|
||||
typedef enum {
|
||||
HOST_OK, HOST_NEW, HOST_CHANGED
|
||||
} HostStatus;
|
||||
|
||||
HostStatus
|
||||
check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found);
|
||||
check_host_in_hostfile(const char *filename, const char *host, Key *key,
|
||||
Key *found, int *line);
|
||||
|
||||
/*
|
||||
* Appends an entry to the host file. Returns false if the entry could not
|
||||
|
54
crypto/dist/ssh/kex.h
vendored
54
crypto/dist/ssh/kex.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kex.h,v 1.1.1.1 2000/09/28 22:10:03 thorpej Exp $ */
|
||||
/* $NetBSD: kex.h,v 1.1.1.2 2001/01/14 04:50:21 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -26,8 +26,9 @@
|
||||
#ifndef KEX_H
|
||||
#define KEX_H
|
||||
|
||||
#define KEX_DH1 "diffie-hellman-group1-sha1"
|
||||
#define KEX_DSS "ssh-dss"
|
||||
#define KEX_DH1 "diffie-hellman-group1-sha1"
|
||||
#define KEX_DHGEX "diffie-hellman-group-exchange-sha1"
|
||||
#define KEX_DSS "ssh-dss"
|
||||
|
||||
enum kex_init_proposals {
|
||||
PROPOSAL_KEX_ALGS,
|
||||
@ -49,28 +50,30 @@ enum kex_modes {
|
||||
MODE_MAX
|
||||
};
|
||||
|
||||
enum kex_exchange {
|
||||
DH_GRP1_SHA1,
|
||||
DH_GEX_SHA1
|
||||
};
|
||||
|
||||
typedef struct Kex Kex;
|
||||
typedef struct Mac Mac;
|
||||
typedef struct Comp Comp;
|
||||
typedef struct Enc Enc;
|
||||
|
||||
struct Enc {
|
||||
int type;
|
||||
int enabled;
|
||||
int block_size;
|
||||
unsigned char *key;
|
||||
unsigned char *iv;
|
||||
int key_len;
|
||||
int iv_len;
|
||||
char *name;
|
||||
Cipher *cipher;
|
||||
int enabled;
|
||||
u_char *key;
|
||||
u_char *iv;
|
||||
};
|
||||
struct Mac {
|
||||
EVP_MD *md;
|
||||
int enabled;
|
||||
int mac_len;
|
||||
unsigned char *key;
|
||||
int key_len;
|
||||
char *name;
|
||||
int enabled;
|
||||
EVP_MD *md;
|
||||
int mac_len;
|
||||
u_char *key;
|
||||
int key_len;
|
||||
};
|
||||
struct Comp {
|
||||
int type;
|
||||
@ -84,7 +87,8 @@ struct Kex {
|
||||
int we_need;
|
||||
int server;
|
||||
char *name;
|
||||
char *hostkeyalg;
|
||||
int hostkey_type;
|
||||
int kex_type;
|
||||
};
|
||||
|
||||
Buffer *kex_init(char *myproposal[PROPOSAL_MAX]);
|
||||
@ -95,12 +99,15 @@ kex_exchange_kexinit(
|
||||
Kex *
|
||||
kex_choose_conf(char *cprop[PROPOSAL_MAX],
|
||||
char *sprop[PROPOSAL_MAX], int server);
|
||||
int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret);
|
||||
int kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret);
|
||||
void packet_set_kex(Kex *k);
|
||||
int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
|
||||
DH *dh_new_group_asc(const char *, const char *);
|
||||
DH *dh_new_group(BIGNUM *, BIGNUM *);
|
||||
void dh_gen_key(DH *);
|
||||
DH *dh_new_group1(void);
|
||||
|
||||
unsigned char *
|
||||
u_char *
|
||||
kex_hash(
|
||||
char *client_version_string,
|
||||
char *server_version_string,
|
||||
@ -111,4 +118,15 @@ kex_hash(
|
||||
BIGNUM *server_dh_pub,
|
||||
BIGNUM *shared_secret);
|
||||
|
||||
u_char *
|
||||
kex_hash_gex(
|
||||
char *client_version_string,
|
||||
char *server_version_string,
|
||||
char *ckexinit, int ckexinitlen,
|
||||
char *skexinit, int skexinitlen,
|
||||
char *serverhostkeyblob, int sbloblen,
|
||||
int minbits, BIGNUM *prime, BIGNUM *gen,
|
||||
BIGNUM *client_dh_pub,
|
||||
BIGNUM *server_dh_pub,
|
||||
BIGNUM *shared_secret);
|
||||
#endif
|
||||
|
402
crypto/dist/ssh/key.c
vendored
402
crypto/dist/ssh/key.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: key.c,v 1.1.1.1 2000/09/28 22:10:03 thorpej Exp $ */
|
||||
/* $NetBSD: key.c,v 1.1.1.2 2001/01/14 04:50:22 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* read_bignum():
|
||||
@ -39,11 +39,11 @@
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
*/
|
||||
|
||||
/* from OpenBSD: key.c,v 1.11 2000/09/07 20:27:51 deraadt Exp */
|
||||
/* from OpenBSD: key.c,v 1.13 2000/12/19 23:17:56 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: key.c,v 1.1.1.1 2000/09/28 22:10:03 thorpej Exp $");
|
||||
__RCSID("$NetBSD: key.c,v 1.1.1.2 2001/01/14 04:50:22 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -53,10 +53,12 @@ __RCSID("$NetBSD: key.c,v 1.1.1.1 2000/09/28 22:10:03 thorpej Exp $");
|
||||
#include <openssl/evp.h>
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "dsa.h"
|
||||
#include "rsa.h"
|
||||
#include "ssh-dss.h"
|
||||
#include "ssh-rsa.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
#define SSH_DSS "ssh-dss"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
|
||||
Key *
|
||||
key_new(int type)
|
||||
@ -69,6 +71,7 @@ key_new(int type)
|
||||
k->dsa = NULL;
|
||||
k->rsa = NULL;
|
||||
switch (k->type) {
|
||||
case KEY_RSA1:
|
||||
case KEY_RSA:
|
||||
rsa = RSA_new();
|
||||
rsa->n = BN_new();
|
||||
@ -83,7 +86,7 @@ key_new(int type)
|
||||
dsa->pub_key = BN_new();
|
||||
k->dsa = dsa;
|
||||
break;
|
||||
case KEY_EMPTY:
|
||||
case KEY_UNSPEC:
|
||||
break;
|
||||
default:
|
||||
fatal("key_new: bad key type %d", k->type);
|
||||
@ -91,10 +94,35 @@ key_new(int type)
|
||||
}
|
||||
return k;
|
||||
}
|
||||
Key *
|
||||
key_new_private(int type)
|
||||
{
|
||||
Key *k = key_new(type);
|
||||
switch (k->type) {
|
||||
case KEY_RSA1:
|
||||
case KEY_RSA:
|
||||
k->rsa->d = BN_new();
|
||||
k->rsa->iqmp = BN_new();
|
||||
k->rsa->q = BN_new();
|
||||
k->rsa->p = BN_new();
|
||||
k->rsa->dmq1 = BN_new();
|
||||
k->rsa->dmp1 = BN_new();
|
||||
break;
|
||||
case KEY_DSA:
|
||||
k->dsa->priv_key = BN_new();
|
||||
break;
|
||||
case KEY_UNSPEC:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
void
|
||||
key_free(Key *k)
|
||||
{
|
||||
switch (k->type) {
|
||||
case KEY_RSA1:
|
||||
case KEY_RSA:
|
||||
if (k->rsa != NULL)
|
||||
RSA_free(k->rsa);
|
||||
@ -105,6 +133,8 @@ key_free(Key *k)
|
||||
DSA_free(k->dsa);
|
||||
k->dsa = NULL;
|
||||
break;
|
||||
case KEY_UNSPEC:
|
||||
break;
|
||||
default:
|
||||
fatal("key_free: bad key type %d", k->type);
|
||||
break;
|
||||
@ -117,6 +147,7 @@ key_equal(Key *a, Key *b)
|
||||
if (a == NULL || b == NULL || a->type != b->type)
|
||||
return 0;
|
||||
switch (a->type) {
|
||||
case KEY_RSA1:
|
||||
case KEY_RSA:
|
||||
return a->rsa != NULL && b->rsa != NULL &&
|
||||
BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
|
||||
@ -144,12 +175,13 @@ char *
|
||||
key_fingerprint(Key *k)
|
||||
{
|
||||
static char retval[(EVP_MAX_MD_SIZE+1)*3];
|
||||
unsigned char *blob = NULL;
|
||||
u_char *blob = NULL;
|
||||
int len = 0;
|
||||
int nlen, elen;
|
||||
|
||||
retval[0] = '\0';
|
||||
switch (k->type) {
|
||||
case KEY_RSA:
|
||||
case KEY_RSA1:
|
||||
nlen = BN_num_bytes(k->rsa->n);
|
||||
elen = BN_num_bytes(k->rsa->e);
|
||||
len = nlen + elen;
|
||||
@ -158,17 +190,19 @@ key_fingerprint(Key *k)
|
||||
BN_bn2bin(k->rsa->e, blob + nlen);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
dsa_make_key_blob(k, &blob, &len);
|
||||
case KEY_RSA:
|
||||
key_to_blob(k, &blob, &len);
|
||||
break;
|
||||
case KEY_UNSPEC:
|
||||
return retval;
|
||||
break;
|
||||
default:
|
||||
fatal("key_fingerprint: bad key type %d", k->type);
|
||||
break;
|
||||
}
|
||||
retval[0] = '\0';
|
||||
|
||||
if (blob != NULL) {
|
||||
int i;
|
||||
unsigned char digest[EVP_MAX_MD_SIZE];
|
||||
u_char digest[EVP_MAX_MD_SIZE];
|
||||
EVP_MD *md = EVP_md5();
|
||||
EVP_MD_CTX ctx;
|
||||
EVP_DigestInit(&ctx, md);
|
||||
@ -241,56 +275,106 @@ write_bignum(FILE *f, BIGNUM *num)
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
unsigned int
|
||||
|
||||
/* returns 1 ok, -1 error, 0 type mismatch */
|
||||
int
|
||||
key_read(Key *ret, char **cpp)
|
||||
{
|
||||
Key *k;
|
||||
unsigned int bits = 0;
|
||||
char *cp;
|
||||
int len, n;
|
||||
unsigned char *blob;
|
||||
int success = -1;
|
||||
char *cp, *space;
|
||||
int len, n, type;
|
||||
u_int bits;
|
||||
u_char *blob;
|
||||
|
||||
cp = *cpp;
|
||||
|
||||
switch(ret->type) {
|
||||
case KEY_RSA:
|
||||
case KEY_RSA1:
|
||||
/* Get number of bits. */
|
||||
if (*cp < '0' || *cp > '9')
|
||||
return 0; /* Bad bit count... */
|
||||
return -1; /* Bad bit count... */
|
||||
for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
|
||||
bits = 10 * bits + *cp - '0';
|
||||
if (bits == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
*cpp = cp;
|
||||
/* Get public exponent, public modulus. */
|
||||
if (!read_bignum(cpp, ret->rsa->e))
|
||||
return 0;
|
||||
return -1;
|
||||
if (!read_bignum(cpp, ret->rsa->n))
|
||||
return 0;
|
||||
return -1;
|
||||
success = 1;
|
||||
break;
|
||||
case KEY_UNSPEC:
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
if (strncmp(cp, SSH_DSS " ", 7) != 0)
|
||||
space = strchr(cp, ' ');
|
||||
if (space == NULL) {
|
||||
debug3("key_read: no space");
|
||||
return -1;
|
||||
}
|
||||
*space = '\0';
|
||||
type = key_type_from_name(cp);
|
||||
*space = ' ';
|
||||
if (type == KEY_UNSPEC) {
|
||||
debug3("key_read: no key found");
|
||||
return -1;
|
||||
}
|
||||
cp = space+1;
|
||||
if (*cp == '\0') {
|
||||
debug3("key_read: short string");
|
||||
return -1;
|
||||
}
|
||||
if (ret->type == KEY_UNSPEC) {
|
||||
ret->type = type;
|
||||
} else if (ret->type != type) {
|
||||
/* is a key, but different type */
|
||||
debug3("key_read: type mismatch");
|
||||
return 0;
|
||||
cp += 7;
|
||||
}
|
||||
len = 2*strlen(cp);
|
||||
blob = xmalloc(len);
|
||||
n = uudecode(cp, blob, len);
|
||||
if (n < 0) {
|
||||
error("key_read: uudecode %s failed", cp);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
k = dsa_key_from_blob(blob, n);
|
||||
k = key_from_blob(blob, n);
|
||||
if (k == NULL) {
|
||||
error("key_read: dsa_key_from_blob %s failed", cp);
|
||||
return 0;
|
||||
error("key_read: key_from_blob %s failed", cp);
|
||||
return -1;
|
||||
}
|
||||
xfree(blob);
|
||||
if (ret->dsa != NULL)
|
||||
DSA_free(ret->dsa);
|
||||
ret->dsa = k->dsa;
|
||||
k->dsa = NULL;
|
||||
if (k->type != type) {
|
||||
error("key_read: type mismatch: encoding error");
|
||||
key_free(k);
|
||||
return -1;
|
||||
}
|
||||
/*XXXX*/
|
||||
if (ret->type == KEY_RSA) {
|
||||
if (ret->rsa != NULL)
|
||||
RSA_free(ret->rsa);
|
||||
ret->rsa = k->rsa;
|
||||
k->rsa = NULL;
|
||||
success = 1;
|
||||
#ifdef DEBUG_PK
|
||||
RSA_print_fp(stderr, ret->rsa, 8);
|
||||
#endif
|
||||
} else {
|
||||
if (ret->dsa != NULL)
|
||||
DSA_free(ret->dsa);
|
||||
ret->dsa = k->dsa;
|
||||
k->dsa = NULL;
|
||||
success = 1;
|
||||
#ifdef DEBUG_PK
|
||||
DSA_print_fp(stderr, ret->dsa, 8);
|
||||
#endif
|
||||
}
|
||||
/*XXXX*/
|
||||
if (success != 1)
|
||||
break;
|
||||
key_free(k);
|
||||
bits = BN_num_bits(ret->dsa->p);
|
||||
/* advance cp: skip whitespace and data */
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
@ -302,15 +386,15 @@ key_read(Key *ret, char **cpp)
|
||||
fatal("key_read: bad key type: %d", ret->type);
|
||||
break;
|
||||
}
|
||||
return bits;
|
||||
return success;
|
||||
}
|
||||
int
|
||||
key_write(Key *key, FILE *f)
|
||||
{
|
||||
int success = 0;
|
||||
unsigned int bits = 0;
|
||||
u_int bits = 0;
|
||||
|
||||
if (key->type == KEY_RSA && key->rsa != NULL) {
|
||||
if (key->type == KEY_RSA1 && key->rsa != NULL) {
|
||||
/* size of modulus 'n' */
|
||||
bits = BN_num_bits(key->rsa->n);
|
||||
fprintf(f, "%u", bits);
|
||||
@ -320,14 +404,15 @@ key_write(Key *key, FILE *f)
|
||||
} else {
|
||||
error("key_write: failed for RSA key");
|
||||
}
|
||||
} else if (key->type == KEY_DSA && key->dsa != NULL) {
|
||||
} else if ((key->type == KEY_DSA && key->dsa != NULL) ||
|
||||
(key->type == KEY_RSA && key->rsa != NULL)) {
|
||||
int len, n;
|
||||
unsigned char *blob, *uu;
|
||||
dsa_make_key_blob(key, &blob, &len);
|
||||
u_char *blob, *uu;
|
||||
key_to_blob(key, &blob, &len);
|
||||
uu = xmalloc(2*len);
|
||||
n = uuencode(blob, len, uu, 2*len);
|
||||
if (n > 0) {
|
||||
fprintf(f, "%s %s", SSH_DSS, uu);
|
||||
fprintf(f, "%s %s", key_ssh_name(key), uu);
|
||||
success = 1;
|
||||
}
|
||||
xfree(blob);
|
||||
@ -339,6 +424,9 @@ char *
|
||||
key_type(Key *k)
|
||||
{
|
||||
switch (k->type) {
|
||||
case KEY_RSA1:
|
||||
return "RSA1";
|
||||
break;
|
||||
case KEY_RSA:
|
||||
return "RSA";
|
||||
break;
|
||||
@ -348,9 +436,23 @@ key_type(Key *k)
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
unsigned int
|
||||
char *
|
||||
key_ssh_name(Key *k)
|
||||
{
|
||||
switch (k->type) {
|
||||
case KEY_RSA:
|
||||
return "ssh-rsa";
|
||||
break;
|
||||
case KEY_DSA:
|
||||
return "ssh-dss";
|
||||
break;
|
||||
}
|
||||
return "ssh-unknown";
|
||||
}
|
||||
u_int
|
||||
key_size(Key *k){
|
||||
switch (k->type) {
|
||||
case KEY_RSA1:
|
||||
case KEY_RSA:
|
||||
return BN_num_bits(k->rsa->n);
|
||||
break;
|
||||
@ -360,3 +462,219 @@ key_size(Key *k){
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RSA *
|
||||
rsa_generate_private_key(u_int bits)
|
||||
{
|
||||
RSA *private;
|
||||
private = RSA_generate_key(bits, 35, NULL, NULL);
|
||||
if (private == NULL)
|
||||
fatal("rsa_generate_private_key: key generation failed.");
|
||||
return private;
|
||||
}
|
||||
|
||||
static DSA*
|
||||
dsa_generate_private_key(u_int bits)
|
||||
{
|
||||
DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
if (private == NULL)
|
||||
fatal("dsa_generate_private_key: DSA_generate_parameters failed");
|
||||
if (!DSA_generate_key(private))
|
||||
fatal("dsa_generate_private_key: DSA_generate_key failed.");
|
||||
if (private == NULL)
|
||||
fatal("dsa_generate_private_key: NULL.");
|
||||
return private;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_generate(int type, u_int bits)
|
||||
{
|
||||
Key *k = key_new(KEY_UNSPEC);
|
||||
switch (type) {
|
||||
case KEY_DSA:
|
||||
k->dsa = dsa_generate_private_key(bits);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
case KEY_RSA1:
|
||||
k->rsa = rsa_generate_private_key(bits);
|
||||
break;
|
||||
default:
|
||||
fatal("key_generate: unknown type %d", type);
|
||||
}
|
||||
k->type = type;
|
||||
return k;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_from_private(Key *k)
|
||||
{
|
||||
Key *n = NULL;
|
||||
switch (k->type) {
|
||||
case KEY_DSA:
|
||||
n = key_new(k->type);
|
||||
BN_copy(n->dsa->p, k->dsa->p);
|
||||
BN_copy(n->dsa->q, k->dsa->q);
|
||||
BN_copy(n->dsa->g, k->dsa->g);
|
||||
BN_copy(n->dsa->pub_key, k->dsa->pub_key);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
case KEY_RSA1:
|
||||
n = key_new(k->type);
|
||||
BN_copy(n->rsa->n, k->rsa->n);
|
||||
BN_copy(n->rsa->e, k->rsa->e);
|
||||
break;
|
||||
default:
|
||||
fatal("key_from_private: unknown type %d", k->type);
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
key_type_from_name(char *name)
|
||||
{
|
||||
if (strcmp(name, "rsa1") == 0){
|
||||
return KEY_RSA1;
|
||||
} else if (strcmp(name, "rsa") == 0){
|
||||
return KEY_RSA;
|
||||
} else if (strcmp(name, "dsa") == 0){
|
||||
return KEY_DSA;
|
||||
} else if (strcmp(name, "ssh-rsa") == 0){
|
||||
return KEY_RSA;
|
||||
} else if (strcmp(name, "ssh-dss") == 0){
|
||||
return KEY_DSA;
|
||||
}
|
||||
debug("key_type_from_name: unknown key type '%s'", name);
|
||||
return KEY_UNSPEC;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_from_blob(char *blob, int blen)
|
||||
{
|
||||
Buffer b;
|
||||
char *ktype;
|
||||
int rlen, type;
|
||||
Key *key = NULL;
|
||||
|
||||
#ifdef DEBUG_PK
|
||||
dump_base64(stderr, blob, blen);
|
||||
#endif
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, blob, blen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
type = key_type_from_name(ktype);
|
||||
|
||||
switch(type){
|
||||
case KEY_RSA:
|
||||
key = key_new(type);
|
||||
buffer_get_bignum2(&b, key->rsa->n);
|
||||
buffer_get_bignum2(&b, key->rsa->e);
|
||||
#ifdef DEBUG_PK
|
||||
RSA_print_fp(stderr, key->rsa, 8);
|
||||
#endif
|
||||
break;
|
||||
case KEY_DSA:
|
||||
key = key_new(type);
|
||||
buffer_get_bignum2(&b, key->dsa->p);
|
||||
buffer_get_bignum2(&b, key->dsa->q);
|
||||
buffer_get_bignum2(&b, key->dsa->g);
|
||||
buffer_get_bignum2(&b, key->dsa->pub_key);
|
||||
#ifdef DEBUG_PK
|
||||
DSA_print_fp(stderr, key->dsa, 8);
|
||||
#endif
|
||||
break;
|
||||
case KEY_UNSPEC:
|
||||
key = key_new(type);
|
||||
break;
|
||||
default:
|
||||
error("key_from_blob: cannot handle type %s", ktype);
|
||||
break;
|
||||
}
|
||||
rlen = buffer_len(&b);
|
||||
if (key != NULL && rlen != 0)
|
||||
error("key_from_blob: remaining bytes in key blob %d", rlen);
|
||||
xfree(ktype);
|
||||
buffer_free(&b);
|
||||
return key;
|
||||
}
|
||||
|
||||
int
|
||||
key_to_blob(Key *key, u_char **blobp, u_int *lenp)
|
||||
{
|
||||
Buffer b;
|
||||
int len;
|
||||
u_char *buf;
|
||||
|
||||
if (key == NULL) {
|
||||
error("key_to_blob: key == NULL");
|
||||
return 0;
|
||||
}
|
||||
buffer_init(&b);
|
||||
switch(key->type){
|
||||
case KEY_DSA:
|
||||
buffer_put_cstring(&b, key_ssh_name(key));
|
||||
buffer_put_bignum2(&b, key->dsa->p);
|
||||
buffer_put_bignum2(&b, key->dsa->q);
|
||||
buffer_put_bignum2(&b, key->dsa->g);
|
||||
buffer_put_bignum2(&b, key->dsa->pub_key);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
buffer_put_cstring(&b, key_ssh_name(key));
|
||||
buffer_put_bignum2(&b, key->rsa->n);
|
||||
buffer_put_bignum2(&b, key->rsa->e);
|
||||
break;
|
||||
default:
|
||||
error("key_to_blob: illegal key type %d", key->type);
|
||||
break;
|
||||
}
|
||||
len = buffer_len(&b);
|
||||
buf = xmalloc(len);
|
||||
memcpy(buf, buffer_ptr(&b), len);
|
||||
memset(buffer_ptr(&b), 0, len);
|
||||
buffer_free(&b);
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (blobp != NULL)
|
||||
*blobp = buf;
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
key_sign(
|
||||
Key *key,
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
switch(key->type){
|
||||
case KEY_DSA:
|
||||
return ssh_dss_sign(key, sigp, lenp, data, datalen);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
return ssh_rsa_sign(key, sigp, lenp, data, datalen);
|
||||
break;
|
||||
default:
|
||||
error("key_sign: illegal key type %d", key->type);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
key_verify(
|
||||
Key *key,
|
||||
u_char *signature, int signaturelen,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
switch(key->type){
|
||||
case KEY_DSA:
|
||||
return ssh_dss_verify(key, signature, signaturelen, data, datalen);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
|
||||
break;
|
||||
default:
|
||||
error("key_verify: illegal key type %d", key->type);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
30
crypto/dist/ssh/key.h
vendored
30
crypto/dist/ssh/key.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: key.h,v 1.1.1.1 2000/09/28 22:10:03 thorpej Exp $ */
|
||||
/* $NetBSD: key.h,v 1.1.1.2 2001/01/14 04:50:22 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -29,9 +29,10 @@
|
||||
|
||||
typedef struct Key Key;
|
||||
enum types {
|
||||
KEY_RSA1,
|
||||
KEY_RSA,
|
||||
KEY_DSA,
|
||||
KEY_EMPTY
|
||||
KEY_UNSPEC
|
||||
};
|
||||
struct Key {
|
||||
int type;
|
||||
@ -40,12 +41,33 @@ struct Key {
|
||||
};
|
||||
|
||||
Key *key_new(int type);
|
||||
Key *key_new_private(int type);
|
||||
void key_free(Key *k);
|
||||
int key_equal(Key *a, Key *b);
|
||||
char *key_fingerprint(Key *k);
|
||||
char *key_type(Key *k);
|
||||
int key_write(Key *key, FILE *f);
|
||||
unsigned int key_read(Key *key, char **cpp);
|
||||
unsigned int key_size(Key *k);
|
||||
int key_read(Key *key, char **cpp);
|
||||
u_int key_size(Key *k);
|
||||
|
||||
Key *key_generate(int type, u_int bits);
|
||||
Key *key_from_private(Key *k);
|
||||
int key_type_from_name(char *name);
|
||||
|
||||
Key *key_from_blob(char *blob, int blen);
|
||||
int key_to_blob(Key *key, u_char **blobp, u_int *lenp);
|
||||
char *key_ssh_name(Key *k);
|
||||
|
||||
int
|
||||
key_sign(
|
||||
Key *key,
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen);
|
||||
|
||||
int
|
||||
key_verify(
|
||||
Key *key,
|
||||
u_char *signature, int signaturelen,
|
||||
u_char *data, int datalen);
|
||||
|
||||
#endif
|
||||
|
11
crypto/dist/ssh/log.c
vendored
11
crypto/dist/ssh/log.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: log.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $ */
|
||||
/* $NetBSD: log.c,v 1.1.1.2 2001/01/14 04:50:23 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -37,11 +37,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: log.c,v 1.10 2000/09/12 20:53:10 markus Exp */
|
||||
/* from OpenBSD: log.c,v 1.12 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: log.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $");
|
||||
__RCSID("$NetBSD: log.c,v 1.1.1.2 2001/01/14 04:50:23 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -163,7 +163,7 @@ fatal_remove_cleanup(void (*proc) (void *context), void *context)
|
||||
}
|
||||
}
|
||||
fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n",
|
||||
(unsigned long) proc, (unsigned long) context);
|
||||
(u_long) proc, (u_long) context);
|
||||
}
|
||||
|
||||
/* Cleanup and exit */
|
||||
@ -180,7 +180,7 @@ fatal_cleanup(void)
|
||||
for (cu = fatal_cleanups; cu; cu = next_cu) {
|
||||
next_cu = cu->next;
|
||||
debug("Calling cleanup 0x%lx(0x%lx)",
|
||||
(unsigned long) cu->proc, (unsigned long) cu->context);
|
||||
(u_long) cu->proc, (u_long) cu->context);
|
||||
(*cu->proc) (cu->context);
|
||||
}
|
||||
exit(255);
|
||||
@ -216,6 +216,7 @@ static struct {
|
||||
{ "ERROR", SYSLOG_LEVEL_ERROR },
|
||||
{ "INFO", SYSLOG_LEVEL_INFO },
|
||||
{ "VERBOSE", SYSLOG_LEVEL_VERBOSE },
|
||||
{ "DEBUG", SYSLOG_LEVEL_DEBUG1 },
|
||||
{ "DEBUG1", SYSLOG_LEVEL_DEBUG1 },
|
||||
{ "DEBUG2", SYSLOG_LEVEL_DEBUG2 },
|
||||
{ "DEBUG3", SYSLOG_LEVEL_DEBUG3 },
|
||||
|
10
crypto/dist/ssh/login.c
vendored
10
crypto/dist/ssh/login.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: login.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $ */
|
||||
/* $NetBSD: login.c,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -40,11 +40,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: login.c,v 1.15 2000/09/07 20:27:52 deraadt Exp */
|
||||
/* from OpenBSD: login.c,v 1.16 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: login.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $");
|
||||
__RCSID("$NetBSD: login.c,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -64,9 +64,9 @@ __RCSID("$NetBSD: login.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $");
|
||||
* is found). The name of the host used last time is returned in buf.
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
u_long
|
||||
get_last_login_time(uid_t uid, const char *logname,
|
||||
char *buf, unsigned int bufsize)
|
||||
char *buf, u_int bufsize)
|
||||
{
|
||||
struct lastlog ll;
|
||||
char *lastlog;
|
||||
|
10
crypto/dist/ssh/match.c
vendored
10
crypto/dist/ssh/match.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: match.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $ */
|
||||
/* $NetBSD: match.c,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,11 +13,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: match.c,v 1.9 2000/09/07 20:27:52 deraadt Exp */
|
||||
/* from OpenBSD: match.c,v 1.10 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: match.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $");
|
||||
__RCSID("$NetBSD: match.c,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -96,12 +96,12 @@ match_pattern(const char *s, const char *pattern)
|
||||
*/
|
||||
|
||||
int
|
||||
match_hostname(const char *host, const char *pattern, unsigned int len)
|
||||
match_hostname(const char *host, const char *pattern, u_int len)
|
||||
{
|
||||
char sub[1024];
|
||||
int negated;
|
||||
int got_positive;
|
||||
unsigned int i, subi;
|
||||
u_int i, subi;
|
||||
|
||||
got_positive = 0;
|
||||
for (i = 0; i < len;) {
|
||||
|
4
crypto/dist/ssh/match.h
vendored
4
crypto/dist/ssh/match.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: match.h,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $ */
|
||||
/* $NetBSD: match.h,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -29,6 +29,6 @@ int match_pattern(const char *s, const char *pattern);
|
||||
* indicate negation). Returns -1 if negation matches, 1 if there is
|
||||
* a positive match, 0 if there is no match at all.
|
||||
*/
|
||||
int match_hostname(const char *host, const char *pattern, unsigned int len);
|
||||
int match_hostname(const char *host, const char *pattern, u_int len);
|
||||
|
||||
#endif
|
||||
|
18
crypto/dist/ssh/mpaux.c
vendored
18
crypto/dist/ssh/mpaux.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mpaux.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $ */
|
||||
/* $NetBSD: mpaux.c,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -14,11 +14,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: mpaux.c,v 1.14 2000/09/07 20:27:52 deraadt Exp */
|
||||
/* from OpenBSD: mpaux.c,v 1.15 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: mpaux.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $");
|
||||
__RCSID("$NetBSD: mpaux.c,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -32,15 +32,15 @@ __RCSID("$NetBSD: mpaux.c,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $");
|
||||
#include "mpaux.h"
|
||||
|
||||
void
|
||||
compute_session_id(unsigned char session_id[16],
|
||||
unsigned char cookie[8],
|
||||
compute_session_id(u_char session_id[16],
|
||||
u_char cookie[8],
|
||||
BIGNUM* host_key_n,
|
||||
BIGNUM* session_key_n)
|
||||
{
|
||||
unsigned int host_key_bytes = BN_num_bytes(host_key_n);
|
||||
unsigned int session_key_bytes = BN_num_bytes(session_key_n);
|
||||
unsigned int bytes = host_key_bytes + session_key_bytes;
|
||||
unsigned char *buf = xmalloc(bytes);
|
||||
u_int host_key_bytes = BN_num_bytes(host_key_n);
|
||||
u_int session_key_bytes = BN_num_bytes(session_key_n);
|
||||
u_int bytes = host_key_bytes + session_key_bytes;
|
||||
u_char *buf = xmalloc(bytes);
|
||||
MD5_CTX md;
|
||||
|
||||
BN_bn2bin(host_key_n, buf);
|
||||
|
8
crypto/dist/ssh/mpaux.h
vendored
8
crypto/dist/ssh/mpaux.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mpaux.h,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $ */
|
||||
/* $NetBSD: mpaux.h,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -14,7 +14,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: mpaux.h,v 1.8 2000/09/07 20:27:52 deraadt Exp */
|
||||
/* from OpenBSD: mpaux.h,v 1.9 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#ifndef MPAUX_H
|
||||
#define MPAUX_H
|
||||
@ -25,8 +25,8 @@
|
||||
* representations of host_key_n, session_key_n, and the cookie.
|
||||
*/
|
||||
void
|
||||
compute_session_id(unsigned char session_id[16],
|
||||
unsigned char cookie[8],
|
||||
compute_session_id(u_char session_id[16],
|
||||
u_char cookie[8],
|
||||
BIGNUM * host_key_n,
|
||||
BIGNUM * session_key_n);
|
||||
|
||||
|
15
crypto/dist/ssh/myproposal.h
vendored
15
crypto/dist/ssh/myproposal.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: myproposal.h,v 1.1.1.1 2000/09/28 22:10:04 thorpej Exp $ */
|
||||
/* $NetBSD: myproposal.h,v 1.1.1.2 2001/01/14 04:50:24 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -23,12 +23,15 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1"
|
||||
#define KEX_DEFAULT_PK_ALG "ssh-dss"
|
||||
#define KEX_DEFAULT_ENCRYPT "3des-cbc,blowfish-cbc,arcfour,cast128-cbc"
|
||||
#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1"
|
||||
#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss"
|
||||
#define KEX_DEFAULT_ENCRYPT \
|
||||
"3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \
|
||||
"aes128-cbc,aes192-cbc,aes256-cbc," \
|
||||
"rijndael128-cbc,rijndael192-cbc,rijndael256-cbc," \
|
||||
"rijndael-cbc@lysator.liu.se"
|
||||
#define KEX_DEFAULT_MAC "hmac-sha1,hmac-md5,hmac-ripemd160@openssh.com"
|
||||
#define KEX_DEFAULT_COMP "zlib,none"
|
||||
#define KEX_DEFAULT_COMP "none,zlib"
|
||||
#define KEX_DEFAULT_LANG ""
|
||||
|
||||
|
||||
|
10
crypto/dist/ssh/nchan.c
vendored
10
crypto/dist/ssh/nchan.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nchan.c,v 1.1.1.1 2000/09/28 22:10:05 thorpej Exp $ */
|
||||
/* $NetBSD: nchan.c,v 1.1.1.2 2001/01/14 04:50:25 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: nchan.c,v 1.19 2000/09/07 20:27:52 deraadt Exp */
|
||||
/* from OpenBSD: nchan.c,v 1.20 2000/11/06 23:04:56 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: nchan.c,v 1.1.1.1 2000/09/28 22:10:05 thorpej Exp $");
|
||||
__RCSID("$NetBSD: nchan.c,v 1.1.1.2 2001/01/14 04:50:25 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -261,6 +261,8 @@ chan_send_oclose1(Channel *c)
|
||||
static void
|
||||
chan_delete_if_full_closed1(Channel *c)
|
||||
{
|
||||
debug3("channel %d: chan_delete_if_full_closed1: istate %d ostate %d",
|
||||
c->self, c->istate, c->ostate);
|
||||
if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
|
||||
debug("channel %d: full closed", c->self);
|
||||
channel_free(c->self);
|
||||
@ -411,6 +413,8 @@ chan_send_close2(Channel *c)
|
||||
static void
|
||||
chan_delete_if_full_closed2(Channel *c)
|
||||
{
|
||||
debug3("channel %d: chan_delete_if_full_closed2: istate %d ostate %d",
|
||||
c->self, c->istate, c->ostate);
|
||||
if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
|
||||
if (!(c->flags & CHAN_CLOSE_SENT)) {
|
||||
chan_send_close2(c);
|
||||
|
24
crypto/dist/ssh/packet.h
vendored
24
crypto/dist/ssh/packet.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: packet.h,v 1.1.1.1 2000/09/28 22:10:08 thorpej Exp $ */
|
||||
/* $NetBSD: packet.h,v 1.1.1.2 2001/01/14 04:50:29 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,7 +13,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: packet.h,v 1.17 2000/09/07 20:27:52 deraadt Exp */
|
||||
/* from OpenBSD: packet.h,v 1.18 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#ifndef PACKET_H
|
||||
#define PACKET_H
|
||||
@ -48,17 +48,17 @@ void packet_close(void);
|
||||
* encrypted independently of each other. Cipher types are defined in ssh.h.
|
||||
*/
|
||||
void
|
||||
packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
|
||||
packet_set_encryption_key(const u_char *key, u_int keylen,
|
||||
int cipher_type);
|
||||
|
||||
/*
|
||||
* Sets remote side protocol flags for the current connection. This can be
|
||||
* called at any time.
|
||||
*/
|
||||
void packet_set_protocol_flags(unsigned int flags);
|
||||
void packet_set_protocol_flags(u_int flags);
|
||||
|
||||
/* Returns the remote protocol flags set earlier by the above function. */
|
||||
unsigned int packet_get_protocol_flags(void);
|
||||
u_int packet_get_protocol_flags(void);
|
||||
|
||||
/* Enables compression in both directions starting from the next packet. */
|
||||
void packet_start_compression(int level);
|
||||
@ -79,16 +79,16 @@ void packet_start(int type);
|
||||
void packet_put_char(int ch);
|
||||
|
||||
/* Appends an integer to the packet data. */
|
||||
void packet_put_int(unsigned int value);
|
||||
void packet_put_int(u_int value);
|
||||
|
||||
/* Appends an arbitrary precision integer to packet data. */
|
||||
void packet_put_bignum(BIGNUM * value);
|
||||
void packet_put_bignum2(BIGNUM * value);
|
||||
|
||||
/* Appends a string to packet data. */
|
||||
void packet_put_string(const char *buf, unsigned int len);
|
||||
void packet_put_string(const char *buf, u_int len);
|
||||
void packet_put_cstring(const char *str);
|
||||
void packet_put_raw(const char *buf, unsigned int len);
|
||||
void packet_put_raw(const char *buf, u_int len);
|
||||
|
||||
/*
|
||||
* Finalizes and sends the packet. If the encryption key has been set,
|
||||
@ -119,13 +119,13 @@ int packet_read_poll(int *packet_len_ptr);
|
||||
* Buffers the given amount of input characters. This is intended to be used
|
||||
* together with packet_read_poll.
|
||||
*/
|
||||
void packet_process_incoming(const char *buf, unsigned int len);
|
||||
void packet_process_incoming(const char *buf, u_int len);
|
||||
|
||||
/* Returns a character (0-255) from the packet data. */
|
||||
unsigned int packet_get_char(void);
|
||||
u_int packet_get_char(void);
|
||||
|
||||
/* Returns an integer from the packet data. */
|
||||
unsigned int packet_get_int(void);
|
||||
u_int packet_get_int(void);
|
||||
|
||||
/*
|
||||
* Returns an arbitrary precision integer from the packet data. The integer
|
||||
@ -141,7 +141,7 @@ char *packet_get_raw(int *length_ptr);
|
||||
* no longer needed. The length_ptr argument may be NULL, or point to an
|
||||
* integer into which the length of the string is stored.
|
||||
*/
|
||||
char *packet_get_string(unsigned int *length_ptr);
|
||||
char *packet_get_string(u_int *length_ptr);
|
||||
|
||||
/*
|
||||
* Logs the error in syslog using LOG_INFO, constructs and sends a disconnect
|
||||
|
4
crypto/dist/ssh/pathnames.h
vendored
4
crypto/dist/ssh/pathnames.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pathnames.h,v 1.1.1.1 2000/09/28 22:10:08 thorpej Exp $ */
|
||||
/* $NetBSD: pathnames.h,v 1.1.1.2 2001/01/14 04:51:03 itojun Exp $ */
|
||||
|
||||
#ifndef _PATHNAMES_H
|
||||
#define _PATHNAMES_H
|
||||
@ -32,6 +32,7 @@
|
||||
/* host keys (should be readable only by root) */
|
||||
#define _PATH_HOST_KEY_FILE "/etc/ssh_host_key"
|
||||
#define _PATH_HOST_DSA_KEY_FILE "/etc/ssh_host_dsa_key"
|
||||
#define _PATH_DH_PRIMES "/etc/primes"
|
||||
|
||||
/* client and server config files */
|
||||
#define _PATH_CLIENT_CONFIG_FILE "/etc/ssh.conf"
|
||||
@ -69,6 +70,7 @@
|
||||
*/
|
||||
#define _PATH_SSH_CLIENT_IDENTITY _PATH_SSH_USER_DIR "/identity"
|
||||
#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa"
|
||||
#define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa"
|
||||
|
||||
/*
|
||||
* Configuration and environment files in user's home directory. These
|
||||
|
54
crypto/dist/ssh/pty.c
vendored
54
crypto/dist/ssh/pty.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pty.c,v 1.1.1.1 2000/09/28 22:10:08 thorpej Exp $ */
|
||||
/* $NetBSD: pty.c,v 1.1.1.2 2001/01/14 04:50:29 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,11 +13,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: pty.c,v 1.16 2000/09/07 21:13:37 markus Exp */
|
||||
/* from OpenBSD: pty.c,v 1.19 2000/12/20 20:00:34 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: pty.c,v 1.1.1.1 2000/09/28 22:10:08 thorpej Exp $");
|
||||
__RCSID("$NetBSD: pty.c,v 1.1.1.2 2001/01/14 04:50:29 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -219,12 +219,8 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
/* Make it our controlling tty. */
|
||||
#ifdef TIOCSCTTY
|
||||
debug("Setting controlling tty using TIOCSCTTY.");
|
||||
/*
|
||||
* We ignore errors from this, because HPSUX defines TIOCSCTTY, but
|
||||
* returns EINVAL with these arguments, and there is absolutely no
|
||||
* documentation.
|
||||
*/
|
||||
ioctl(*ttyfd, TIOCSCTTY, NULL);
|
||||
if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0)
|
||||
error("ioctl(TIOCSCTTY): %.100s", strerror(errno));
|
||||
#endif /* TIOCSCTTY */
|
||||
fd = open(ttyname, O_RDWR);
|
||||
if (fd < 0)
|
||||
@ -262,6 +258,7 @@ pty_setowner(struct passwd *pw, const char *ttyname)
|
||||
struct group *grp;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
struct stat st;
|
||||
|
||||
/* Determine the group to make the owner of the tty. */
|
||||
grp = getgrnam("tty");
|
||||
@ -273,11 +270,36 @@ pty_setowner(struct passwd *pw, const char *ttyname)
|
||||
mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
}
|
||||
|
||||
/* Change ownership of the tty. */
|
||||
if (chown(ttyname, pw->pw_uid, gid) < 0)
|
||||
fatal("chown(%.100s, %d, %d) failed: %.100s",
|
||||
ttyname, pw->pw_uid, gid, strerror(errno));
|
||||
if (chmod(ttyname, mode) < 0)
|
||||
fatal("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
/*
|
||||
* Change owner and mode of the tty as required.
|
||||
* Warn but continue if filesystem is read-only and the uids match.
|
||||
*/
|
||||
if (stat(ttyname, &st))
|
||||
fatal("stat(%.100s) failed: %.100s", ttyname,
|
||||
strerror(errno));
|
||||
|
||||
if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
|
||||
if (chown(ttyname, pw->pw_uid, gid) < 0) {
|
||||
if (errno == EROFS && st.st_uid == pw->pw_uid)
|
||||
error("chown(%.100s, %d, %d) failed: %.100s",
|
||||
ttyname, pw->pw_uid, gid,
|
||||
strerror(errno));
|
||||
else
|
||||
fatal("chown(%.100s, %d, %d) failed: %.100s",
|
||||
ttyname, pw->pw_uid, gid,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
|
||||
if (chmod(ttyname, mode) < 0) {
|
||||
if (errno == EROFS &&
|
||||
(st.st_mode & (S_IRGRP | S_IROTH)) == 0)
|
||||
error("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
else
|
||||
fatal("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
crypto/dist/ssh/radix.c
vendored
24
crypto/dist/ssh/radix.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: radix.c,v 1.1.1.1 2000/09/28 22:10:08 thorpej Exp $ */
|
||||
/* $NetBSD: radix.c,v 1.1.1.2 2001/01/14 04:50:30 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Dug Song. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: radix.c,v 1.13 2000/09/07 20:27:52 deraadt Exp */
|
||||
/* from OpenBSD: radix.c,v 1.14 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: radix.c,v 1.1.1.1 2000/09/28 22:10:08 thorpej Exp $");
|
||||
__RCSID("$NetBSD: radix.c,v 1.1.1.2 2001/01/14 04:50:30 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -38,9 +38,9 @@ __RCSID("$NetBSD: radix.c,v 1.1.1.1 2000/09/28 22:10:08 thorpej Exp $");
|
||||
#ifdef AFS
|
||||
#include <krb.h>
|
||||
|
||||
typedef unsigned char my_u_char;
|
||||
typedef unsigned int my_u_int32_t;
|
||||
typedef unsigned short my_u_short;
|
||||
typedef u_char my_u_char;
|
||||
typedef u_int my_u_int32_t;
|
||||
typedef u_short my_u_short;
|
||||
|
||||
/* Nasty macros from BIND-4.9.2 */
|
||||
|
||||
@ -97,7 +97,7 @@ typedef unsigned short my_u_short;
|
||||
|
||||
|
||||
int
|
||||
creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen)
|
||||
creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen)
|
||||
{
|
||||
char *p, *s;
|
||||
int len;
|
||||
@ -131,8 +131,8 @@ creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen)
|
||||
|
||||
PUTLONG(creds->issue_date, p);
|
||||
{
|
||||
unsigned int endTime;
|
||||
endTime = (unsigned int) krb_life_to_time(creds->issue_date,
|
||||
u_int endTime;
|
||||
endTime = (u_int) krb_life_to_time(creds->issue_date,
|
||||
creds->lifetime);
|
||||
PUTLONG(endTime, p);
|
||||
}
|
||||
@ -147,7 +147,7 @@ creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen)
|
||||
p += creds->ticket_st.length;
|
||||
len = p - temp;
|
||||
|
||||
return (uuencode((unsigned char *)temp, len, (char *)buf, buflen));
|
||||
return (uuencode((u_char *)temp, len, (char *)buf, buflen));
|
||||
}
|
||||
|
||||
int
|
||||
@ -159,7 +159,7 @@ radix_to_creds(const char *buf, CREDENTIALS *creds)
|
||||
char version;
|
||||
char temp[2048];
|
||||
|
||||
len = uudecode(buf, (unsigned char *)temp, sizeof(temp));
|
||||
len = uudecode(buf, (u_char *)temp, sizeof(temp));
|
||||
if (len < 0)
|
||||
return 0;
|
||||
|
||||
@ -192,7 +192,7 @@ radix_to_creds(const char *buf, CREDENTIALS *creds)
|
||||
GETLONG(creds->issue_date, p);
|
||||
len -= 4;
|
||||
{
|
||||
unsigned int endTime;
|
||||
u_int endTime;
|
||||
GETLONG(endTime, p);
|
||||
len -= 4;
|
||||
creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
|
||||
|
90
crypto/dist/ssh/readconf.c
vendored
90
crypto/dist/ssh/readconf.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: readconf.c,v 1.1.1.1 2000/09/28 22:10:10 thorpej Exp $ */
|
||||
/* $NetBSD: readconf.c,v 1.1.1.2 2001/01/14 04:50:31 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,17 +13,16 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: readconf.c,v 1.47 2000/09/07 21:13:37 markus Exp */
|
||||
/* from OpenBSD: readconf.c,v 1.52 2000/12/27 12:30:19 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: readconf.c,v 1.1.1.1 2000/09/28 22:10:10 thorpej Exp $");
|
||||
__RCSID("$NetBSD: readconf.c,v 1.1.1.2 2001/01/14 04:50:31 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "ssh.h"
|
||||
#include "cipher.h"
|
||||
#include "pathnames.h"
|
||||
#include "readconf.h"
|
||||
#include "match.h"
|
||||
@ -78,7 +77,7 @@ __RCSID("$NetBSD: readconf.c,v 1.1.1.1 2000/09/28 22:10:10 thorpej Exp $");
|
||||
# Defaults for various options
|
||||
Host *
|
||||
ForwardAgent no
|
||||
ForwardX11 yes
|
||||
ForwardX11 no
|
||||
RhostsAuthentication yes
|
||||
PasswordAuthentication yes
|
||||
RSAAuthentication yes
|
||||
@ -111,8 +110,9 @@ typedef enum {
|
||||
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
||||
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
|
||||
oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
|
||||
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2,
|
||||
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication
|
||||
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol,
|
||||
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
|
||||
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias
|
||||
} OpCodes;
|
||||
|
||||
/* Textual representations of the tokens. */
|
||||
@ -128,8 +128,11 @@ static struct {
|
||||
{ "useprivilegedport", oUsePrivilegedPort },
|
||||
{ "rhostsauthentication", oRhostsAuthentication },
|
||||
{ "passwordauthentication", oPasswordAuthentication },
|
||||
{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
|
||||
{ "kbdinteractivedevices", oKbdInteractiveDevices },
|
||||
{ "rsaauthentication", oRSAAuthentication },
|
||||
{ "dsaauthentication", oDSAAuthentication },
|
||||
{ "pubkeyauthentication", oPubkeyAuthentication },
|
||||
{ "dsaauthentication", oPubkeyAuthentication }, /* alias */
|
||||
{ "skeyauthentication", oSkeyAuthentication },
|
||||
#ifdef KRB4
|
||||
{ "kerberosauthentication", oKerberosAuthentication },
|
||||
@ -141,8 +144,9 @@ static struct {
|
||||
{ "fallbacktorsh", oFallBackToRsh },
|
||||
{ "usersh", oUseRsh },
|
||||
{ "identityfile", oIdentityFile },
|
||||
{ "identityfile2", oIdentityFile2 },
|
||||
{ "identityfile2", oIdentityFile }, /* alias */
|
||||
{ "hostname", oHostName },
|
||||
{ "hostkeyalias", oHostKeyAlias },
|
||||
{ "proxycommand", oProxyCommand },
|
||||
{ "port", oPort },
|
||||
{ "cipher", oCipher },
|
||||
@ -219,7 +223,7 @@ add_remote_forward(Options *options, u_short port, const char *host,
|
||||
static OpCodes
|
||||
parse_token(const char *cp, const char *filename, int linenum)
|
||||
{
|
||||
unsigned int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; keywords[i].name; i++)
|
||||
if (strcasecmp(cp, keywords[i].name) == 0)
|
||||
@ -297,8 +301,16 @@ parse_flag:
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oDSAAuthentication:
|
||||
intptr = &options->dsa_authentication;
|
||||
case oKbdInteractiveAuthentication:
|
||||
intptr = &options->kbd_interactive_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oKbdInteractiveDevices:
|
||||
charptr = &options->kbd_interactive_devices;
|
||||
goto parse_string;
|
||||
|
||||
case oPubkeyAuthentication:
|
||||
intptr = &options->pubkey_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oRSAAuthentication:
|
||||
@ -399,20 +411,15 @@ parse_flag:
|
||||
goto parse_int;
|
||||
|
||||
case oIdentityFile:
|
||||
case oIdentityFile2:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing argument.", filename, linenum);
|
||||
if (*activep) {
|
||||
intptr = (opcode == oIdentityFile) ?
|
||||
&options->num_identity_files :
|
||||
&options->num_identity_files2;
|
||||
intptr = &options->num_identity_files;
|
||||
if (*intptr >= SSH_MAX_IDENTITY_FILES)
|
||||
fatal("%.200s line %d: Too many identity files specified (max %d).",
|
||||
filename, linenum, SSH_MAX_IDENTITY_FILES);
|
||||
charptr = (opcode == oIdentityFile) ?
|
||||
&options->identity_files[*intptr] :
|
||||
&options->identity_files2[*intptr];
|
||||
charptr = &options->identity_files[*intptr];
|
||||
*charptr = xstrdup(arg);
|
||||
*intptr = *intptr + 1;
|
||||
}
|
||||
@ -452,6 +459,10 @@ parse_string:
|
||||
charptr = &options->hostname;
|
||||
goto parse_string;
|
||||
|
||||
case oHostKeyAlias:
|
||||
charptr = &options->host_key_alias;
|
||||
goto parse_string;
|
||||
|
||||
case oProxyCommand:
|
||||
charptr = &options->proxy_command;
|
||||
string = xstrdup("");
|
||||
@ -590,10 +601,10 @@ parse_int:
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing argument.", filename, linenum);
|
||||
if (arg[0] == '^' && arg[2] == 0 &&
|
||||
(unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128)
|
||||
value = (unsigned char) arg[1] & 31;
|
||||
(u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
|
||||
value = (u_char) arg[1] & 31;
|
||||
else if (strlen(arg) == 1)
|
||||
value = (unsigned char) arg[0];
|
||||
value = (u_char) arg[0];
|
||||
else if (strcmp(arg, "none") == 0)
|
||||
value = -2;
|
||||
else {
|
||||
@ -677,7 +688,7 @@ initialize_options(Options * options)
|
||||
options->use_privileged_port = -1;
|
||||
options->rhosts_authentication = -1;
|
||||
options->rsa_authentication = -1;
|
||||
options->dsa_authentication = -1;
|
||||
options->pubkey_authentication = -1;
|
||||
options->skey_authentication = -1;
|
||||
#ifdef KRB4
|
||||
options->kerberos_authentication = -1;
|
||||
@ -687,6 +698,8 @@ initialize_options(Options * options)
|
||||
options->afs_token_passing = -1;
|
||||
#endif
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->kbd_interactive_devices = NULL;
|
||||
options->rhosts_rsa_authentication = -1;
|
||||
options->fallback_to_rsh = -1;
|
||||
options->use_rsh = -1;
|
||||
@ -703,8 +716,8 @@ initialize_options(Options * options)
|
||||
options->ciphers = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->num_identity_files = 0;
|
||||
options->num_identity_files2 = 0;
|
||||
options->hostname = NULL;
|
||||
options->host_key_alias = NULL;
|
||||
options->proxy_command = NULL;
|
||||
options->user = NULL;
|
||||
options->escape_char = -1;
|
||||
@ -741,8 +754,8 @@ fill_default_options(Options * options)
|
||||
options->rhosts_authentication = 1;
|
||||
if (options->rsa_authentication == -1)
|
||||
options->rsa_authentication = 1;
|
||||
if (options->dsa_authentication == -1)
|
||||
options->dsa_authentication = 1;
|
||||
if (options->pubkey_authentication == -1)
|
||||
options->pubkey_authentication = 1;
|
||||
if (options->skey_authentication == -1)
|
||||
options->skey_authentication = 1;
|
||||
#ifdef KRB4
|
||||
@ -757,6 +770,8 @@ fill_default_options(Options * options)
|
||||
#endif /* AFS */
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
options->kbd_interactive_authentication = 0;
|
||||
if (options->rhosts_rsa_authentication == -1)
|
||||
options->rhosts_rsa_authentication = 1;
|
||||
if (options->fallback_to_rsh == -1)
|
||||
@ -788,16 +803,18 @@ fill_default_options(Options * options)
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
|
||||
if (options->num_identity_files == 0) {
|
||||
options->identity_files[0] =
|
||||
xmalloc(2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1);
|
||||
sprintf(options->identity_files[0], "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
|
||||
options->num_identity_files = 1;
|
||||
}
|
||||
if (options->num_identity_files2 == 0) {
|
||||
options->identity_files2[0] =
|
||||
xmalloc(2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1);
|
||||
sprintf(options->identity_files2[0], "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
|
||||
options->num_identity_files2 = 1;
|
||||
if (options->protocol & SSH_PROTO_1) {
|
||||
options->identity_files[options->num_identity_files] =
|
||||
xmalloc(2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1);
|
||||
sprintf(options->identity_files[options->num_identity_files++],
|
||||
"~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
|
||||
}
|
||||
if (options->protocol & SSH_PROTO_2) {
|
||||
options->identity_files[options->num_identity_files] =
|
||||
xmalloc(2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1);
|
||||
sprintf(options->identity_files[options->num_identity_files++],
|
||||
"~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
|
||||
}
|
||||
}
|
||||
if (options->escape_char == -1)
|
||||
options->escape_char = '~';
|
||||
@ -814,4 +831,5 @@ fill_default_options(Options * options)
|
||||
/* 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 */
|
||||
/* options->host_key_alias should not be set by default */
|
||||
}
|
||||
|
14
crypto/dist/ssh/readconf.h
vendored
14
crypto/dist/ssh/readconf.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: readconf.h,v 1.1.1.1 2000/09/28 22:10:10 thorpej Exp $ */
|
||||
/* $NetBSD: readconf.h,v 1.1.1.2 2001/01/14 04:50:32 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,7 +13,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: readconf.h,v 1.21 2000/09/07 20:27:53 deraadt Exp */
|
||||
/* from OpenBSD: readconf.h,v 1.24 2000/12/27 12:30:20 markus Exp */
|
||||
|
||||
#ifndef READCONF_H
|
||||
#define READCONF_H
|
||||
@ -37,7 +37,7 @@ typedef struct {
|
||||
int rhosts_rsa_authentication; /* Try rhosts with RSA
|
||||
* authentication. */
|
||||
int rsa_authentication; /* Try RSA authentication. */
|
||||
int dsa_authentication; /* Try DSA authentication. */
|
||||
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
|
||||
int skey_authentication; /* Try S/Key or TIS authentication. */
|
||||
#ifdef KRB4
|
||||
int kerberos_authentication; /* Try Kerberos
|
||||
@ -49,6 +49,8 @@ typedef struct {
|
||||
#endif
|
||||
int password_authentication; /* Try password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
||||
char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
|
||||
int fallback_to_rsh;/* Use rsh if cannot connect with ssh. */
|
||||
int use_rsh; /* Always use rsh (don\'t try ssh). */
|
||||
int batch_mode; /* Batch mode: do not ask for passwords. */
|
||||
@ -69,6 +71,7 @@ typedef struct {
|
||||
char *ciphers; /* SSH2 ciphers in order of preference. */
|
||||
int protocol; /* Protocol in order of preference. */
|
||||
char *hostname; /* Real host to connect. */
|
||||
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
|
||||
char *proxy_command; /* Proxy command for connecting the host. */
|
||||
char *user; /* User to log in as. */
|
||||
int escape_char; /* Escape character; -2 = none */
|
||||
@ -78,10 +81,9 @@ typedef struct {
|
||||
char *system_hostfile2;
|
||||
char *user_hostfile2;
|
||||
|
||||
int num_identity_files; /* Number of files for RSA identities. */
|
||||
int num_identity_files2; /* DSA identities. */
|
||||
int num_identity_files; /* Number of files for RSA/DSA identities. */
|
||||
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
||||
char *identity_files2[SSH_MAX_IDENTITY_FILES];
|
||||
int identity_files_type[SSH_MAX_IDENTITY_FILES];
|
||||
|
||||
/* Local TCP/IP forward requests. */
|
||||
int num_local_forwards;
|
||||
|
86
crypto/dist/ssh/readpass.c
vendored
86
crypto/dist/ssh/readpass.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: readpass.c,v 1.1.1.1 2000/09/28 22:10:10 thorpej Exp $ */
|
||||
/* $NetBSD: readpass.c,v 1.1.1.2 2001/01/14 04:50:32 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
@ -33,95 +33,31 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: readpass.c,v 1.11 2000/06/20 01:39:44 markus Exp */
|
||||
/* from OpenBSD: readpass.c,v 1.12 2000/10/11 20:14:39 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: readpass.c,v 1.1.1.1 2000/09/28 22:10:10 thorpej Exp $");
|
||||
__RCSID("$NetBSD: readpass.c,v 1.1.1.2 2001/01/14 04:50:32 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
|
||||
volatile int intr;
|
||||
|
||||
static void
|
||||
intcatch(int signo)
|
||||
{
|
||||
intr = 1;
|
||||
}
|
||||
#include "cli.h"
|
||||
|
||||
/*
|
||||
* Reads a passphrase from /dev/tty with echo turned off. Returns the
|
||||
* passphrase (allocated with xmalloc), being very careful to ensure that
|
||||
* no other userland buffer is storing the password.
|
||||
*/
|
||||
/*
|
||||
* Note: the funcationallity of this routing has been moved to
|
||||
* cli_read_passphrase(). This routing remains to maintain
|
||||
* compatibility with existing code.
|
||||
*/
|
||||
char *
|
||||
read_passphrase(const char *prompt, int from_stdin)
|
||||
read_passphrase(char *prompt, int from_stdin)
|
||||
{
|
||||
char buf[1024], *p, ch;
|
||||
struct termios tio, saved_tio;
|
||||
sigset_t oset, nset;
|
||||
struct sigaction sa, osa;
|
||||
int input, output, echo = 0;
|
||||
|
||||
if (from_stdin) {
|
||||
input = STDIN_FILENO;
|
||||
output = STDERR_FILENO;
|
||||
} else
|
||||
input = output = open(_PATH_TTY, O_RDWR);
|
||||
|
||||
if (input == -1)
|
||||
fatal("You have no controlling tty. Cannot read passphrase.\n");
|
||||
|
||||
/* block signals, get terminal modes and turn off echo */
|
||||
sigemptyset(&nset);
|
||||
sigaddset(&nset, SIGTSTP);
|
||||
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = intcatch;
|
||||
(void) sigaction(SIGINT, &sa, &osa);
|
||||
|
||||
intr = 0;
|
||||
|
||||
if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) {
|
||||
echo = 1;
|
||||
tio = saved_tio;
|
||||
tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
(void) tcsetattr(input, TCSANOW, &tio);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
(void)write(output, prompt, strlen(prompt));
|
||||
for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) {
|
||||
if (intr)
|
||||
break;
|
||||
if (p < buf + sizeof(buf) - 1)
|
||||
*p++ = ch;
|
||||
}
|
||||
*p = '\0';
|
||||
if (!intr)
|
||||
(void)write(output, "\n", 1);
|
||||
|
||||
/* restore terminal modes and allow signals */
|
||||
if (echo)
|
||||
tcsetattr(input, TCSANOW, &saved_tio);
|
||||
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
(void) sigaction(SIGINT, &osa, NULL);
|
||||
|
||||
if (intr) {
|
||||
kill(getpid(), SIGINT);
|
||||
sigemptyset(&nset);
|
||||
/* XXX tty has not neccessarily drained by now? */
|
||||
sigsuspend(&nset);
|
||||
}
|
||||
|
||||
if (!from_stdin)
|
||||
(void)close(input);
|
||||
p = xstrdup(buf);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return (p);
|
||||
return cli_read_passphrase(prompt, from_stdin, 0);
|
||||
}
|
||||
|
412
crypto/dist/ssh/rijndael.c
vendored
Normal file
412
crypto/dist/ssh/rijndael.c
vendored
Normal file
@ -0,0 +1,412 @@
|
||||
/* $OpenBSD: rijndael.c,v 1.6 2000/12/09 13:48:31 markus Exp $ */
|
||||
|
||||
/* This is an independent implementation of the encryption algorithm: */
|
||||
/* */
|
||||
/* RIJNDAEL by Joan Daemen and Vincent Rijmen */
|
||||
/* */
|
||||
/* which is a candidate algorithm in the Advanced Encryption Standard */
|
||||
/* programme of the US National Institute of Standards and Technology. */
|
||||
/* */
|
||||
/* Copyright in this implementation is held by Dr B R Gladman but I */
|
||||
/* hereby give permission for its free direct or derivative use subject */
|
||||
/* to acknowledgment of its origin and compliance with any conditions */
|
||||
/* that the originators of the algorithm place on its exploitation. */
|
||||
/* */
|
||||
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
|
||||
|
||||
/* Timing data for Rijndael (rijndael.c)
|
||||
|
||||
Algorithm: rijndael (rijndael.c)
|
||||
|
||||
128 bit key:
|
||||
Key Setup: 305/1389 cycles (encrypt/decrypt)
|
||||
Encrypt: 374 cycles = 68.4 mbits/sec
|
||||
Decrypt: 352 cycles = 72.7 mbits/sec
|
||||
Mean: 363 cycles = 70.5 mbits/sec
|
||||
|
||||
192 bit key:
|
||||
Key Setup: 277/1595 cycles (encrypt/decrypt)
|
||||
Encrypt: 439 cycles = 58.3 mbits/sec
|
||||
Decrypt: 425 cycles = 60.2 mbits/sec
|
||||
Mean: 432 cycles = 59.3 mbits/sec
|
||||
|
||||
256 bit key:
|
||||
Key Setup: 374/1960 cycles (encrypt/decrypt)
|
||||
Encrypt: 502 cycles = 51.0 mbits/sec
|
||||
Decrypt: 498 cycles = 51.4 mbits/sec
|
||||
Mean: 500 cycles = 51.2 mbits/sec
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "rijndael.h"
|
||||
|
||||
void gen_tabs __P((void));
|
||||
|
||||
/* 3. Basic macros for speeding up generic operations */
|
||||
|
||||
/* Circular rotate of 32 bit values */
|
||||
|
||||
#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
|
||||
#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
|
||||
|
||||
/* Invert byte order in a 32 bit variable */
|
||||
|
||||
#define bswap(x) ((rotl(x, 8) & 0x00ff00ff) | (rotr(x, 8) & 0xff00ff00))
|
||||
|
||||
/* Extract byte from a 32 bit quantity (little endian notation) */
|
||||
|
||||
#define byte(x,n) ((u1byte)((x) >> (8 * n)))
|
||||
|
||||
#if BYTE_ORDER != LITTLE_ENDIAN
|
||||
#define BYTE_SWAP
|
||||
#endif
|
||||
|
||||
#ifdef BYTE_SWAP
|
||||
#define io_swap(x) bswap(x)
|
||||
#else
|
||||
#define io_swap(x) (x)
|
||||
#endif
|
||||
|
||||
#define LARGE_TABLES
|
||||
|
||||
u1byte pow_tab[256];
|
||||
u1byte log_tab[256];
|
||||
u1byte sbx_tab[256];
|
||||
u1byte isb_tab[256];
|
||||
u4byte rco_tab[ 10];
|
||||
u4byte ft_tab[4][256];
|
||||
u4byte it_tab[4][256];
|
||||
|
||||
#ifdef LARGE_TABLES
|
||||
u4byte fl_tab[4][256];
|
||||
u4byte il_tab[4][256];
|
||||
#endif
|
||||
|
||||
u4byte tab_gen = 0;
|
||||
|
||||
#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
|
||||
|
||||
#define f_rn(bo, bi, n, k) \
|
||||
bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
|
||||
ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
|
||||
ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
|
||||
ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
|
||||
|
||||
#define i_rn(bo, bi, n, k) \
|
||||
bo[n] = it_tab[0][byte(bi[n],0)] ^ \
|
||||
it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
|
||||
it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
|
||||
it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
|
||||
|
||||
#ifdef LARGE_TABLES
|
||||
|
||||
#define ls_box(x) \
|
||||
( fl_tab[0][byte(x, 0)] ^ \
|
||||
fl_tab[1][byte(x, 1)] ^ \
|
||||
fl_tab[2][byte(x, 2)] ^ \
|
||||
fl_tab[3][byte(x, 3)] )
|
||||
|
||||
#define f_rl(bo, bi, n, k) \
|
||||
bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
|
||||
fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
|
||||
fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
|
||||
fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
|
||||
|
||||
#define i_rl(bo, bi, n, k) \
|
||||
bo[n] = il_tab[0][byte(bi[n],0)] ^ \
|
||||
il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
|
||||
il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
|
||||
il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
|
||||
|
||||
#else
|
||||
|
||||
#define ls_box(x) \
|
||||
((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \
|
||||
((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \
|
||||
((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \
|
||||
((u4byte)sbx_tab[byte(x, 3)] << 24)
|
||||
|
||||
#define f_rl(bo, bi, n, k) \
|
||||
bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^ \
|
||||
rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]), 8) ^ \
|
||||
rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \
|
||||
rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)
|
||||
|
||||
#define i_rl(bo, bi, n, k) \
|
||||
bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^ \
|
||||
rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \
|
||||
rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \
|
||||
rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
gen_tabs(void)
|
||||
{
|
||||
u4byte i, t;
|
||||
u1byte p, q;
|
||||
|
||||
/* log and power tables for GF(2**8) finite field with */
|
||||
/* 0x11b as modular polynomial - the simplest prmitive */
|
||||
/* root is 0x11, used here to generate the tables */
|
||||
|
||||
for(i = 0,p = 1; i < 256; ++i) {
|
||||
pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i;
|
||||
|
||||
p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
|
||||
}
|
||||
|
||||
log_tab[1] = 0; p = 1;
|
||||
|
||||
for(i = 0; i < 10; ++i) {
|
||||
rco_tab[i] = p;
|
||||
|
||||
p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
|
||||
}
|
||||
|
||||
/* note that the affine byte transformation matrix in */
|
||||
/* rijndael specification is in big endian format with */
|
||||
/* bit 0 as the most significant bit. In the remainder */
|
||||
/* of the specification the bits are numbered from the */
|
||||
/* least significant end of a byte. */
|
||||
|
||||
for(i = 0; i < 256; ++i) {
|
||||
p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p;
|
||||
q = (q >> 7) | (q << 1); p ^= q;
|
||||
q = (q >> 7) | (q << 1); p ^= q;
|
||||
q = (q >> 7) | (q << 1); p ^= q;
|
||||
q = (q >> 7) | (q << 1); p ^= q ^ 0x63;
|
||||
sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i;
|
||||
}
|
||||
|
||||
for(i = 0; i < 256; ++i) {
|
||||
p = sbx_tab[i];
|
||||
|
||||
#ifdef LARGE_TABLES
|
||||
|
||||
t = p; fl_tab[0][i] = t;
|
||||
fl_tab[1][i] = rotl(t, 8);
|
||||
fl_tab[2][i] = rotl(t, 16);
|
||||
fl_tab[3][i] = rotl(t, 24);
|
||||
#endif
|
||||
t = ((u4byte)ff_mult(2, p)) |
|
||||
((u4byte)p << 8) |
|
||||
((u4byte)p << 16) |
|
||||
((u4byte)ff_mult(3, p) << 24);
|
||||
|
||||
ft_tab[0][i] = t;
|
||||
ft_tab[1][i] = rotl(t, 8);
|
||||
ft_tab[2][i] = rotl(t, 16);
|
||||
ft_tab[3][i] = rotl(t, 24);
|
||||
|
||||
p = isb_tab[i];
|
||||
|
||||
#ifdef LARGE_TABLES
|
||||
|
||||
t = p; il_tab[0][i] = t;
|
||||
il_tab[1][i] = rotl(t, 8);
|
||||
il_tab[2][i] = rotl(t, 16);
|
||||
il_tab[3][i] = rotl(t, 24);
|
||||
#endif
|
||||
t = ((u4byte)ff_mult(14, p)) |
|
||||
((u4byte)ff_mult( 9, p) << 8) |
|
||||
((u4byte)ff_mult(13, p) << 16) |
|
||||
((u4byte)ff_mult(11, p) << 24);
|
||||
|
||||
it_tab[0][i] = t;
|
||||
it_tab[1][i] = rotl(t, 8);
|
||||
it_tab[2][i] = rotl(t, 16);
|
||||
it_tab[3][i] = rotl(t, 24);
|
||||
}
|
||||
|
||||
tab_gen = 1;
|
||||
}
|
||||
|
||||
#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
|
||||
|
||||
#define imix_col(y,x) \
|
||||
u = star_x(x); \
|
||||
v = star_x(u); \
|
||||
w = star_x(v); \
|
||||
t = w ^ (x); \
|
||||
(y) = u ^ v ^ w; \
|
||||
(y) ^= rotr(u ^ t, 8) ^ \
|
||||
rotr(v ^ t, 16) ^ \
|
||||
rotr(t,24)
|
||||
|
||||
/* initialise the key schedule from the user supplied key */
|
||||
|
||||
#define loop4(i) \
|
||||
{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
|
||||
t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \
|
||||
t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \
|
||||
t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \
|
||||
t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \
|
||||
}
|
||||
|
||||
#define loop6(i) \
|
||||
{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
|
||||
t ^= e_key[6 * i]; e_key[6 * i + 6] = t; \
|
||||
t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t; \
|
||||
t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t; \
|
||||
t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t; \
|
||||
t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t; \
|
||||
t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t; \
|
||||
}
|
||||
|
||||
#define loop8(i) \
|
||||
{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
|
||||
t ^= e_key[8 * i]; e_key[8 * i + 8] = t; \
|
||||
t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t; \
|
||||
t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t; \
|
||||
t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t; \
|
||||
t = e_key[8 * i + 4] ^ ls_box(t); \
|
||||
e_key[8 * i + 12] = t; \
|
||||
t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t; \
|
||||
t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t; \
|
||||
t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t; \
|
||||
}
|
||||
|
||||
rijndael_ctx *
|
||||
rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len,
|
||||
int encrypt)
|
||||
{
|
||||
u4byte i, t, u, v, w;
|
||||
u4byte *e_key = ctx->e_key;
|
||||
u4byte *d_key = ctx->d_key;
|
||||
|
||||
ctx->decrypt = !encrypt;
|
||||
|
||||
if(!tab_gen)
|
||||
gen_tabs();
|
||||
|
||||
ctx->k_len = (key_len + 31) / 32;
|
||||
|
||||
e_key[0] = io_swap(in_key[0]); e_key[1] = io_swap(in_key[1]);
|
||||
e_key[2] = io_swap(in_key[2]); e_key[3] = io_swap(in_key[3]);
|
||||
|
||||
switch(ctx->k_len) {
|
||||
case 4: t = e_key[3];
|
||||
for(i = 0; i < 10; ++i)
|
||||
loop4(i);
|
||||
break;
|
||||
|
||||
case 6: e_key[4] = io_swap(in_key[4]); t = e_key[5] = io_swap(in_key[5]);
|
||||
for(i = 0; i < 8; ++i)
|
||||
loop6(i);
|
||||
break;
|
||||
|
||||
case 8: e_key[4] = io_swap(in_key[4]); e_key[5] = io_swap(in_key[5]);
|
||||
e_key[6] = io_swap(in_key[6]); t = e_key[7] = io_swap(in_key[7]);
|
||||
for(i = 0; i < 7; ++i)
|
||||
loop8(i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!encrypt) {
|
||||
d_key[0] = e_key[0]; d_key[1] = e_key[1];
|
||||
d_key[2] = e_key[2]; d_key[3] = e_key[3];
|
||||
|
||||
for(i = 4; i < 4 * ctx->k_len + 24; ++i) {
|
||||
imix_col(d_key[i], e_key[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/* encrypt a block of text */
|
||||
|
||||
#define f_nround(bo, bi, k) \
|
||||
f_rn(bo, bi, 0, k); \
|
||||
f_rn(bo, bi, 1, k); \
|
||||
f_rn(bo, bi, 2, k); \
|
||||
f_rn(bo, bi, 3, k); \
|
||||
k += 4
|
||||
|
||||
#define f_lround(bo, bi, k) \
|
||||
f_rl(bo, bi, 0, k); \
|
||||
f_rl(bo, bi, 1, k); \
|
||||
f_rl(bo, bi, 2, k); \
|
||||
f_rl(bo, bi, 3, k)
|
||||
|
||||
void
|
||||
rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
|
||||
{
|
||||
u4byte k_len = ctx->k_len;
|
||||
u4byte *e_key = ctx->e_key;
|
||||
u4byte b0[4], b1[4], *kp;
|
||||
|
||||
b0[0] = io_swap(in_blk[0]) ^ e_key[0];
|
||||
b0[1] = io_swap(in_blk[1]) ^ e_key[1];
|
||||
b0[2] = io_swap(in_blk[2]) ^ e_key[2];
|
||||
b0[3] = io_swap(in_blk[3]) ^ e_key[3];
|
||||
|
||||
kp = e_key + 4;
|
||||
|
||||
if(k_len > 6) {
|
||||
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
|
||||
}
|
||||
|
||||
if(k_len > 4) {
|
||||
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
|
||||
}
|
||||
|
||||
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
|
||||
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
|
||||
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
|
||||
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
|
||||
f_nround(b1, b0, kp); f_lround(b0, b1, kp);
|
||||
|
||||
out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]);
|
||||
out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]);
|
||||
}
|
||||
|
||||
/* decrypt a block of text */
|
||||
|
||||
#define i_nround(bo, bi, k) \
|
||||
i_rn(bo, bi, 0, k); \
|
||||
i_rn(bo, bi, 1, k); \
|
||||
i_rn(bo, bi, 2, k); \
|
||||
i_rn(bo, bi, 3, k); \
|
||||
k -= 4
|
||||
|
||||
#define i_lround(bo, bi, k) \
|
||||
i_rl(bo, bi, 0, k); \
|
||||
i_rl(bo, bi, 1, k); \
|
||||
i_rl(bo, bi, 2, k); \
|
||||
i_rl(bo, bi, 3, k)
|
||||
|
||||
void
|
||||
rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
|
||||
{
|
||||
u4byte b0[4], b1[4], *kp;
|
||||
u4byte k_len = ctx->k_len;
|
||||
u4byte *e_key = ctx->e_key;
|
||||
u4byte *d_key = ctx->d_key;
|
||||
|
||||
b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24];
|
||||
b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25];
|
||||
b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26];
|
||||
b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27];
|
||||
|
||||
kp = d_key + 4 * (k_len + 5);
|
||||
|
||||
if(k_len > 6) {
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
}
|
||||
|
||||
if(k_len > 4) {
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
}
|
||||
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
i_nround(b1, b0, kp); i_lround(b0, b1, kp);
|
||||
|
||||
out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]);
|
||||
out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]);
|
||||
}
|
31
crypto/dist/ssh/rijndael.h
vendored
Normal file
31
crypto/dist/ssh/rijndael.h
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _RIJNDAEL_H_
|
||||
#define _RIJNDAEL_H_
|
||||
|
||||
/* 1. Standard types for AES cryptography source code */
|
||||
|
||||
typedef u_int8_t u1byte; /* an 8 bit unsigned character type */
|
||||
typedef u_int16_t u2byte; /* a 16 bit unsigned integer type */
|
||||
typedef u_int32_t u4byte; /* a 32 bit unsigned integer type */
|
||||
|
||||
typedef int8_t s1byte; /* an 8 bit signed character type */
|
||||
typedef int16_t s2byte; /* a 16 bit signed integer type */
|
||||
typedef int32_t s4byte; /* a 32 bit signed integer type */
|
||||
|
||||
typedef struct _rijndael_ctx {
|
||||
u4byte k_len;
|
||||
int decrypt;
|
||||
u4byte e_key[64];
|
||||
u4byte d_key[64];
|
||||
} rijndael_ctx;
|
||||
|
||||
|
||||
/* 2. Standard interface for AES cryptographic routines */
|
||||
|
||||
/* These are all based on 32 bit unsigned values and will therefore */
|
||||
/* require endian conversions for big-endian architectures */
|
||||
|
||||
rijndael_ctx *rijndael_set_key __P((rijndael_ctx *, const u4byte *, u4byte, int));
|
||||
void rijndael_encrypt __P((rijndael_ctx *, const u4byte *, u4byte *));
|
||||
void rijndael_decrypt __P((rijndael_ctx *, const u4byte *, u4byte *));
|
||||
|
||||
#endif /* _RIJNDAEL_H_ */
|
84
crypto/dist/ssh/rsa.c
vendored
84
crypto/dist/ssh/rsa.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rsa.c,v 1.1.1.1 2000/09/28 22:10:11 thorpej Exp $ */
|
||||
/* $NetBSD: rsa.c,v 1.1.1.2 2001/01/14 04:50:32 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -61,11 +61,11 @@
|
||||
* [gone - had to be deleted - what a pity]
|
||||
*/
|
||||
|
||||
/* from OpenBSD: rsa.c,v 1.16 2000/09/07 20:27:53 deraadt Exp */
|
||||
/* from OpenBSD: rsa.c,v 1.18 2000/12/19 23:17:57 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: rsa.c,v 1.1.1.1 2000/09/28 22:10:11 thorpej Exp $");
|
||||
__RCSID("$NetBSD: rsa.c,v 1.1.1.2 2001/01/14 04:50:32 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -74,76 +74,10 @@ __RCSID("$NetBSD: rsa.c,v 1.1.1.1 2000/09/28 22:10:11 thorpej Exp $");
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
int rsa_verbose = 1;
|
||||
|
||||
int
|
||||
rsa_alive()
|
||||
{
|
||||
RSA *key;
|
||||
|
||||
key = RSA_generate_key(32, 3, NULL, NULL);
|
||||
if (key == NULL)
|
||||
return (0);
|
||||
RSA_free(key);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates RSA public and private keys. This initializes the data
|
||||
* structures; they should be freed with rsa_clear_private_key and
|
||||
* rsa_clear_public_key.
|
||||
*/
|
||||
|
||||
void
|
||||
rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits)
|
||||
{
|
||||
RSA *key;
|
||||
|
||||
if (rsa_verbose) {
|
||||
printf("Generating RSA keys: ");
|
||||
fflush(stdout);
|
||||
}
|
||||
key = RSA_generate_key(bits, 35, NULL, NULL);
|
||||
if (key == NULL)
|
||||
fatal("rsa_generate_key: key generation failed.");
|
||||
|
||||
/* Copy public key parameters */
|
||||
pub->n = BN_new();
|
||||
BN_copy(pub->n, key->n);
|
||||
pub->e = BN_new();
|
||||
BN_copy(pub->e, key->e);
|
||||
|
||||
/* Copy private key parameters */
|
||||
prv->n = BN_new();
|
||||
BN_copy(prv->n, key->n);
|
||||
prv->e = BN_new();
|
||||
BN_copy(prv->e, key->e);
|
||||
prv->d = BN_new();
|
||||
BN_copy(prv->d, key->d);
|
||||
prv->p = BN_new();
|
||||
BN_copy(prv->p, key->p);
|
||||
prv->q = BN_new();
|
||||
BN_copy(prv->q, key->q);
|
||||
|
||||
prv->dmp1 = BN_new();
|
||||
BN_copy(prv->dmp1, key->dmp1);
|
||||
|
||||
prv->dmq1 = BN_new();
|
||||
BN_copy(prv->dmq1, key->dmq1);
|
||||
|
||||
prv->iqmp = BN_new();
|
||||
BN_copy(prv->iqmp, key->iqmp);
|
||||
|
||||
RSA_free(key);
|
||||
|
||||
if (rsa_verbose)
|
||||
printf("Key generation complete.\n");
|
||||
}
|
||||
|
||||
void
|
||||
rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
|
||||
{
|
||||
unsigned char *inbuf, *outbuf;
|
||||
u_char *inbuf, *outbuf;
|
||||
int len, ilen, olen;
|
||||
|
||||
if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
|
||||
@ -171,7 +105,7 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
|
||||
void
|
||||
rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
|
||||
{
|
||||
unsigned char *inbuf, *outbuf;
|
||||
u_char *inbuf, *outbuf;
|
||||
int len, ilen, olen;
|
||||
|
||||
olen = BN_num_bytes(key->n);
|
||||
@ -192,11 +126,3 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
|
||||
xfree(outbuf);
|
||||
xfree(inbuf);
|
||||
}
|
||||
|
||||
/* Set whether to output verbose messages during key generation. */
|
||||
|
||||
void
|
||||
rsa_set_verbose(int verbose)
|
||||
{
|
||||
rsa_verbose = verbose;
|
||||
}
|
||||
|
15
crypto/dist/ssh/rsa.h
vendored
15
crypto/dist/ssh/rsa.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rsa.h,v 1.1.1.1 2000/09/28 22:10:11 thorpej Exp $ */
|
||||
/* $NetBSD: rsa.h,v 1.1.1.2 2001/01/14 04:50:32 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,7 +13,7 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: rsa.h,v 1.8 2000/09/07 20:27:53 deraadt Exp */
|
||||
/* from OpenBSD: rsa.h,v 1.9 2000/11/12 19:50:38 markus Exp */
|
||||
|
||||
#ifndef RSA_H
|
||||
#define RSA_H
|
||||
@ -21,17 +21,6 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
/* Calls SSL RSA_generate_key, only copies to prv and pub */
|
||||
void rsa_generate_key(RSA * prv, RSA * pub, unsigned int bits);
|
||||
|
||||
/*
|
||||
* Indicates whether the rsa module is permitted to show messages on the
|
||||
* terminal.
|
||||
*/
|
||||
void rsa_set_verbose __P((int verbose));
|
||||
|
||||
int rsa_alive __P((void));
|
||||
|
||||
void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
|
||||
void rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
|
||||
|
||||
|
9
crypto/dist/ssh/scp.1
vendored
9
crypto/dist/ssh/scp.1
vendored
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.\" Created: Sun May 7 00:14:37 1995 ylo
|
||||
.\"
|
||||
.\" $NetBSD: scp.1,v 1.1.1.1 2000/09/28 22:10:11 thorpej Exp $
|
||||
.\" $NetBSD: scp.1,v 1.1.1.2 2001/01/14 04:50:32 itojun Exp $
|
||||
.\"
|
||||
.Dd September 25, 1999
|
||||
.Dt SCP 1
|
||||
@ -24,6 +24,7 @@
|
||||
.Op Fl P Ar port
|
||||
.Op Fl c Ar cipher
|
||||
.Op Fl i Ar identity_file
|
||||
.Op Fl o Ar option
|
||||
.Sm off
|
||||
.Oo
|
||||
.Op Ar user@
|
||||
@ -102,9 +103,13 @@ is already reserved for preserving the times and modes of the file in
|
||||
.It Fl S Ar program
|
||||
Name of
|
||||
.Ar program
|
||||
to use for the encrypted connection. The program must understand
|
||||
to use for the encrypted connection.
|
||||
The program must understand
|
||||
.Xr ssh 1
|
||||
options.
|
||||
.It Fl o Ar option
|
||||
The given option is directly passed to
|
||||
.Xr ssh 1 .
|
||||
.It Fl 4
|
||||
Forces
|
||||
.Nm
|
||||
|
157
crypto/dist/ssh/serverloop.c
vendored
157
crypto/dist/ssh/serverloop.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: serverloop.c,v 1.1.1.1 2000/09/28 22:10:20 thorpej Exp $ */
|
||||
/* $NetBSD: serverloop.c,v 1.1.1.2 2001/01/14 04:50:38 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -36,12 +36,15 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: serverloop.c,v 1.39 2000/12/27 14:19:21 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: serverloop.c,v 1.1.1.1 2000/09/28 22:10:20 thorpej Exp $");
|
||||
__RCSID("$NetBSD: serverloop.c,v 1.1.1.2 2001/01/14 04:50:38 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "packet.h"
|
||||
@ -55,6 +58,9 @@ __RCSID("$NetBSD: serverloop.c,v 1.1.1.1 2000/09/28 22:10:20 thorpej Exp $");
|
||||
#include "session.h"
|
||||
#include "dispatch.h"
|
||||
#include "auth-options.h"
|
||||
#include "auth.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
static Buffer stdin_buffer; /* Buffer for stdin data. */
|
||||
static Buffer stdout_buffer; /* Buffer for stdout data. */
|
||||
@ -72,7 +78,7 @@ static int fdout_eof = 0; /* EOF encountered reading from fdout. */
|
||||
static int fderr_eof = 0; /* EOF encountered readung from fderr. */
|
||||
static int connection_in; /* Connection to client (input). */
|
||||
static int connection_out; /* Connection to client (output). */
|
||||
static unsigned int buffer_high;/* "Soft" max buffer size. */
|
||||
static u_int buffer_high;/* "Soft" max buffer size. */
|
||||
static int max_fd; /* Max file descriptor number for select(). */
|
||||
|
||||
/*
|
||||
@ -181,7 +187,7 @@ make_packets_from_stdout_data(void)
|
||||
*/
|
||||
static void
|
||||
wait_until_can_do_something(fd_set * readset, fd_set * writeset,
|
||||
unsigned int max_time_milliseconds)
|
||||
u_int max_time_milliseconds)
|
||||
{
|
||||
struct timeval tv, *tvp;
|
||||
int ret;
|
||||
@ -252,7 +258,7 @@ retry_select:
|
||||
tvp = &tv;
|
||||
}
|
||||
if (tvp!=NULL)
|
||||
debug("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds);
|
||||
debug2("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds);
|
||||
|
||||
/* Wait for something to happen, or the timeout to expire. */
|
||||
ret = select(max_fd + 1, readset, writeset, NULL, tvp);
|
||||
@ -404,9 +410,9 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
int wait_status; /* Status returned by wait(). */
|
||||
pid_t wait_pid; /* pid returned by wait(). */
|
||||
int waiting_termination = 0; /* Have displayed waiting close message. */
|
||||
unsigned int max_time_milliseconds;
|
||||
unsigned int previous_stdout_buffer_bytes;
|
||||
unsigned int stdout_buffer_bytes;
|
||||
u_int max_time_milliseconds;
|
||||
u_int previous_stdout_buffer_bytes;
|
||||
u_int stdout_buffer_bytes;
|
||||
int type;
|
||||
|
||||
debug("Entering interactive session.");
|
||||
@ -579,7 +585,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
|
||||
/* Wait for the child to exit. Get its exit status. */
|
||||
wait_pid = wait(&wait_status);
|
||||
if (wait_pid < 0) {
|
||||
if (wait_pid == -1) {
|
||||
/*
|
||||
* It is possible that the wait was handled by SIGCHLD
|
||||
* handler. This may result in either: this call
|
||||
@ -683,7 +689,7 @@ static void
|
||||
server_input_stdin_data(int type, int plen, void *ctxt)
|
||||
{
|
||||
char *data;
|
||||
unsigned int data_len;
|
||||
u_int data_len;
|
||||
|
||||
/* Stdin data from the client. Append it to the buffer. */
|
||||
/* Ignore any data if the client has closed stdin. */
|
||||
@ -723,10 +729,10 @@ server_input_window_size(int type, int plen, void *ctxt)
|
||||
pty_change_window_size(fdin, row, col, xpixel, ypixel);
|
||||
}
|
||||
|
||||
static int
|
||||
input_direct_tcpip(void)
|
||||
static Channel *
|
||||
server_request_direct_tcpip(char *ctype)
|
||||
{
|
||||
int sock;
|
||||
int sock, newch;
|
||||
char *target, *originator;
|
||||
int target_port, originator_port;
|
||||
|
||||
@ -736,23 +742,52 @@ input_direct_tcpip(void)
|
||||
originator_port = packet_get_int();
|
||||
packet_done();
|
||||
|
||||
debug("open direct-tcpip: from %s port %d to %s port %d",
|
||||
debug("server_request_direct_tcpip: originator %s port %d, target %s port %d",
|
||||
originator, originator_port, target, target_port);
|
||||
|
||||
/* XXX check permission */
|
||||
if (no_port_forwarding_flag) {
|
||||
if (no_port_forwarding_flag || !options.allow_tcp_forwarding) {
|
||||
xfree(target);
|
||||
xfree(originator);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
sock = channel_connect_to(target, target_port);
|
||||
xfree(target);
|
||||
xfree(originator);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
return channel_new("direct-tcpip", SSH_CHANNEL_OPEN,
|
||||
return NULL;
|
||||
newch = channel_new(ctype, SSH_CHANNEL_CONNECTING,
|
||||
sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
|
||||
CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"));
|
||||
CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
|
||||
return (newch >= 0) ? channel_lookup(newch) : NULL;
|
||||
}
|
||||
|
||||
static Channel *
|
||||
server_request_session(char *ctype)
|
||||
{
|
||||
int newch;
|
||||
|
||||
debug("input_session_request");
|
||||
packet_done();
|
||||
/*
|
||||
* A server session has no fd to read or write until a
|
||||
* CHANNEL_REQUEST for a shell is made, so we set the type to
|
||||
* SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
|
||||
* CHANNEL_REQUEST messages is registered.
|
||||
*/
|
||||
newch = channel_new(ctype, SSH_CHANNEL_LARVAL,
|
||||
-1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT,
|
||||
0, xstrdup("server-session"), 1);
|
||||
if (session_open(newch) == 1) {
|
||||
channel_register_callback(newch, SSH2_MSG_CHANNEL_REQUEST,
|
||||
session_input_channel_req, (void *)0);
|
||||
channel_register_cleanup(newch, session_close_by_channel);
|
||||
return channel_lookup(newch);
|
||||
} else {
|
||||
debug("session open failed, free channel %d", newch);
|
||||
channel_free(newch);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -760,8 +795,7 @@ server_input_channel_open(int type, int plen, void *ctxt)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
char *ctype;
|
||||
int id;
|
||||
unsigned int len;
|
||||
u_int len;
|
||||
int rchan;
|
||||
int rmaxpack;
|
||||
int rwindow;
|
||||
@ -775,34 +809,12 @@ server_input_channel_open(int type, int plen, void *ctxt)
|
||||
ctype, rchan, rwindow, rmaxpack);
|
||||
|
||||
if (strcmp(ctype, "session") == 0) {
|
||||
debug("open session");
|
||||
packet_done();
|
||||
/*
|
||||
* A server session has no fd to read or write
|
||||
* until a CHANNEL_REQUEST for a shell is made,
|
||||
* so we set the type to SSH_CHANNEL_LARVAL.
|
||||
* Additionally, a callback for handling all
|
||||
* CHANNEL_REQUEST messages is registered.
|
||||
*/
|
||||
id = channel_new(ctype, SSH_CHANNEL_LARVAL,
|
||||
-1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT,
|
||||
0, xstrdup("server-session"));
|
||||
if (session_open(id) == 1) {
|
||||
channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST,
|
||||
session_input_channel_req, (void *)0);
|
||||
channel_register_cleanup(id, session_close_by_channel);
|
||||
c = channel_lookup(id);
|
||||
} else {
|
||||
debug("session open failed, free channel %d", id);
|
||||
channel_free(id);
|
||||
}
|
||||
c = server_request_session(ctype);
|
||||
} else if (strcmp(ctype, "direct-tcpip") == 0) {
|
||||
id = input_direct_tcpip();
|
||||
if (id >= 0)
|
||||
c = channel_lookup(id);
|
||||
c = server_request_direct_tcpip(ctype);
|
||||
}
|
||||
if (c != NULL) {
|
||||
debug("confirm %s", ctype);
|
||||
debug("server_input_channel_open: confirm %s", ctype);
|
||||
c->remote_id = rchan;
|
||||
c->remote_window = rwindow;
|
||||
c->remote_maxpacket = rmaxpack;
|
||||
@ -814,7 +826,7 @@ server_input_channel_open(int type, int plen, void *ctxt)
|
||||
packet_put_int(c->local_maxpacket);
|
||||
packet_send();
|
||||
} else {
|
||||
debug("failure %s", ctype);
|
||||
debug("server_input_channel_open: failure %s", ctype);
|
||||
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
|
||||
packet_put_int(rchan);
|
||||
packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
|
||||
@ -825,6 +837,56 @@ server_input_channel_open(int type, int plen, void *ctxt)
|
||||
xfree(ctype);
|
||||
}
|
||||
|
||||
static void
|
||||
server_input_global_request(int type, int plen, void *ctxt)
|
||||
{
|
||||
char *rtype;
|
||||
int want_reply;
|
||||
int success = 0;
|
||||
|
||||
rtype = packet_get_string(NULL);
|
||||
want_reply = packet_get_char();
|
||||
debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);
|
||||
|
||||
if (strcmp(rtype, "tcpip-forward") == 0) {
|
||||
struct passwd *pw;
|
||||
char *listen_address;
|
||||
u_short listen_port;
|
||||
|
||||
pw = auth_get_user();
|
||||
if (pw == NULL)
|
||||
fatal("server_input_global_request: no user");
|
||||
listen_address = packet_get_string(NULL); /* XXX currently ignored */
|
||||
listen_port = (u_short)packet_get_int();
|
||||
debug("server_input_global_request: tcpip-forward listen %s port %d",
|
||||
listen_address, listen_port);
|
||||
|
||||
/* check permissions */
|
||||
if (!options.allow_tcp_forwarding ||
|
||||
no_port_forwarding_flag ||
|
||||
(listen_port < IPPORT_RESERVED && pw->pw_uid != 0)) {
|
||||
success = 0;
|
||||
packet_send_debug("Server has disabled port forwarding.");
|
||||
} else {
|
||||
/* Start listening on the port */
|
||||
channel_request_forwarding(
|
||||
listen_address, listen_port,
|
||||
/*unspec host_to_connect*/ "<unspec host>",
|
||||
/*unspec port_to_connect*/ 0,
|
||||
options.gateway_ports, /*remote*/ 1);
|
||||
success = 1;
|
||||
}
|
||||
xfree(listen_address);
|
||||
}
|
||||
if (want_reply) {
|
||||
packet_start(success ?
|
||||
SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
}
|
||||
xfree(rtype);
|
||||
}
|
||||
|
||||
static void
|
||||
server_init_dispatch_20(void)
|
||||
{
|
||||
@ -839,6 +901,7 @@ server_init_dispatch_20(void)
|
||||
dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
|
||||
dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request);
|
||||
dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
|
||||
dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
|
||||
}
|
||||
static void
|
||||
server_init_dispatch_13(void)
|
||||
|
75
crypto/dist/ssh/session.c
vendored
75
crypto/dist/ssh/session.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: session.c,v 1.1.1.1 2000/09/28 22:10:23 thorpej Exp $ */
|
||||
/* $NetBSD: session.c,v 1.1.1.2 2001/01/14 04:50:41 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -34,11 +34,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: session.c,v 1.37 2000/09/07 20:27:53 deraadt Exp */
|
||||
/* from OpenBSD: session.c,v 1.46 2001/01/04 22:41:03 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: session.c,v 1.1.1.1 2000/09/28 22:10:23 thorpej Exp $");
|
||||
__RCSID("$NetBSD: session.c,v 1.1.1.2 2001/01/14 04:50:41 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -48,7 +48,6 @@ __RCSID("$NetBSD: session.c,v 1.1.1.1 2000/09/28 22:10:23 thorpej Exp $");
|
||||
#include "pty.h"
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "cipher.h"
|
||||
#include "mpaux.h"
|
||||
#include "servconf.h"
|
||||
#include "uidswap.h"
|
||||
@ -98,7 +97,7 @@ void session_pty_cleanup(Session *s);
|
||||
void session_proctitle(Session *s);
|
||||
void do_exec_pty(Session *s, const char *command, struct passwd * pw);
|
||||
void do_exec_no_pty(Session *s, const char *command, struct passwd * pw);
|
||||
void do_login(Session *s);
|
||||
void do_login(Session *s, const char *command);
|
||||
|
||||
void
|
||||
do_child(const char *command, struct passwd * pw, const char *term,
|
||||
@ -110,7 +109,7 @@ extern ServerOptions options;
|
||||
extern char *__progname;
|
||||
extern int log_stderr;
|
||||
extern int debug_flag;
|
||||
extern unsigned int utmp_len;
|
||||
extern u_int utmp_len;
|
||||
|
||||
extern int startup_pipe;
|
||||
|
||||
@ -184,7 +183,7 @@ do_authenticated(struct passwd * pw)
|
||||
char *command;
|
||||
int n_bytes;
|
||||
int plen;
|
||||
unsigned int proto_len, data_len, dlen;
|
||||
u_int proto_len, data_len, dlen;
|
||||
|
||||
/*
|
||||
* Cancel the alarm we set to limit the time taken for
|
||||
@ -203,7 +202,7 @@ do_authenticated(struct passwd * pw)
|
||||
* by the client telling us, so we can equally well trust the client
|
||||
* not to request anything bogus.)
|
||||
*/
|
||||
if (!no_port_forwarding_flag)
|
||||
if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
|
||||
channel_permit_all_opens();
|
||||
|
||||
s = session_new();
|
||||
@ -350,6 +349,10 @@ do_authenticated(struct passwd * pw)
|
||||
debug("Port forwarding not permitted for this authentication.");
|
||||
break;
|
||||
}
|
||||
if (!options.allow_tcp_forwarding) {
|
||||
debug("Port forwarding not permitted.");
|
||||
break;
|
||||
}
|
||||
debug("Received TCP/IP port forwarding request.");
|
||||
channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports);
|
||||
success = 1;
|
||||
@ -571,8 +574,8 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
|
||||
close(ttyfd);
|
||||
|
||||
/* record login, etc. similar to login(1) */
|
||||
if (command == NULL && !options.use_login)
|
||||
do_login(s);
|
||||
if (!(options.use_login && command == NULL))
|
||||
do_login(s, command);
|
||||
|
||||
/*
|
||||
* Do common processing for the child, such as execing
|
||||
@ -627,7 +630,7 @@ get_remote_name_or_ip(void)
|
||||
|
||||
/* administrative, login(1)-like work */
|
||||
void
|
||||
do_login(Session *s)
|
||||
do_login(Session *s, const char *command)
|
||||
{
|
||||
FILE *f;
|
||||
char *time_string;
|
||||
@ -663,7 +666,9 @@ do_login(Session *s)
|
||||
record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
|
||||
get_remote_name_or_ip(), (struct sockaddr *)&from);
|
||||
|
||||
/* Done if .hushlogin exists. */
|
||||
/* Done if .hushlogin exists or a command given. */
|
||||
if (command != NULL)
|
||||
return;
|
||||
snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
|
||||
if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
|
||||
return;
|
||||
@ -671,7 +676,7 @@ do_login(Session *s)
|
||||
time_string = ctime(&last_login_time);
|
||||
if (strchr(time_string, '\n'))
|
||||
*strchr(time_string, '\n') = 0;
|
||||
if (strcmp(buf, "") == 0)
|
||||
if (strcmp(hostname, "") == 0)
|
||||
printf("Last login: %s\r\n", time_string);
|
||||
else
|
||||
printf("Last login: %s from %s\r\n", time_string, hostname);
|
||||
@ -692,10 +697,10 @@ do_login(Session *s)
|
||||
* already exists, its value is overriden.
|
||||
*/
|
||||
static void
|
||||
child_set_env(char ***envp, unsigned int *envsizep, const char *name,
|
||||
child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||
const char *value)
|
||||
{
|
||||
unsigned int i, namelen;
|
||||
u_int i, namelen;
|
||||
char **env;
|
||||
|
||||
/*
|
||||
@ -733,7 +738,7 @@ child_set_env(char ***envp, unsigned int *envsizep, const char *name,
|
||||
* and assignments of the form name=value. No other forms are allowed.
|
||||
*/
|
||||
static void
|
||||
read_environment_file(char ***env, unsigned int *envsize,
|
||||
read_environment_file(char ***env, u_int *envsize,
|
||||
const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
@ -781,7 +786,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
char buf[256];
|
||||
char cmd[1024];
|
||||
FILE *f = NULL;
|
||||
unsigned int envsize, i;
|
||||
u_int envsize, i;
|
||||
char **env;
|
||||
extern char **environ;
|
||||
struct stat st;
|
||||
@ -975,8 +980,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
if (!options.use_login) {
|
||||
if (stat(_PATH_SSH_USER_RC, &st) >= 0) {
|
||||
if (debug_flag)
|
||||
fprintf(stderr, "Running %s %s\n",
|
||||
_PATH_BSHELL, _PATH_SSH_USER_RC);
|
||||
fprintf(stderr, "Running %s %s\n", _PATH_BSHELL, _PATH_SSH_USER_RC);
|
||||
|
||||
f = popen(_PATH_BSHELL " " _PATH_SSH_USER_RC, "w");
|
||||
if (f) {
|
||||
@ -988,8 +992,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
_PATH_SSH_USER_RC);
|
||||
} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
|
||||
if (debug_flag)
|
||||
fprintf(stderr, "Running %s %s\n",
|
||||
_PATH_BSHELL, _PATH_SSH_SYSTEM_RC);
|
||||
fprintf(stderr, "Running %s %s\n", _PATH_BSHELL, _PATH_SSH_SYSTEM_RC);
|
||||
|
||||
f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
|
||||
if (f) {
|
||||
@ -1218,7 +1221,7 @@ session_window_change_req(Session *s)
|
||||
static int
|
||||
session_pty_req(Session *s)
|
||||
{
|
||||
unsigned int len;
|
||||
u_int len;
|
||||
char *term_modes; /* encoded terminal modes */
|
||||
|
||||
if (no_pty_flag)
|
||||
@ -1267,7 +1270,7 @@ session_pty_req(Session *s)
|
||||
static int
|
||||
session_subsystem_req(Session *s)
|
||||
{
|
||||
unsigned int len;
|
||||
u_int len;
|
||||
int success = 0;
|
||||
char *subsys = packet_get_string(&len);
|
||||
int i;
|
||||
@ -1363,7 +1366,7 @@ session_shell_req(Session *s)
|
||||
static int
|
||||
session_exec_req(Session *s)
|
||||
{
|
||||
unsigned int len;
|
||||
u_int len;
|
||||
char *command = packet_get_string(&len);
|
||||
packet_done();
|
||||
if (forced_command) {
|
||||
@ -1381,10 +1384,27 @@ session_exec_req(Session *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
session_auth_agent_req(Session *s)
|
||||
{
|
||||
static int called = 0;
|
||||
packet_done();
|
||||
if (no_agent_forwarding_flag) {
|
||||
debug("session_auth_agent_req: no_agent_forwarding_flag");
|
||||
return 0;
|
||||
}
|
||||
if (called) {
|
||||
return 0;
|
||||
} else {
|
||||
called = 1;
|
||||
return auth_input_request_forwarding(s->pw);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
session_input_channel_req(int id, void *arg)
|
||||
{
|
||||
unsigned int len;
|
||||
u_int len;
|
||||
int reply;
|
||||
int success = 0;
|
||||
char *rtype;
|
||||
@ -1417,6 +1437,8 @@ session_input_channel_req(int id, void *arg)
|
||||
success = session_pty_req(s);
|
||||
} else if (strcmp(rtype, "x11-req") == 0) {
|
||||
success = session_x11_req(s);
|
||||
} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
|
||||
success = session_auth_agent_req(s);
|
||||
} else if (strcmp(rtype, "subsystem") == 0) {
|
||||
success = session_subsystem_req(s);
|
||||
}
|
||||
@ -1447,7 +1469,8 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
|
||||
fatal("no channel for session %d", s->self);
|
||||
channel_set_fds(s->chanid,
|
||||
fdout, fdin, fderr,
|
||||
fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ);
|
||||
fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
|
||||
1);
|
||||
}
|
||||
|
||||
void
|
||||
|
18
crypto/dist/ssh/sftp-server.8
vendored
18
crypto/dist/ssh/sftp-server.8
vendored
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" $NetBSD: sftp-server.8,v 1.1.1.1 2000/09/28 22:10:23 thorpej Exp $
|
||||
.\" $NetBSD: sftp-server.8,v 1.1.1.2 2001/01/14 04:49:51 itojun Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
.\"
|
||||
@ -39,21 +39,21 @@ is a program that speaks the server side of SFTP protocol
|
||||
to stdout and expects client requests from stdin.
|
||||
.Nm
|
||||
is not intended to be called directly, but from
|
||||
.Xr sshd 8
|
||||
.Xr sshd 8
|
||||
using the
|
||||
.Cm Subsystem
|
||||
option.
|
||||
See
|
||||
.Xr sshd 8
|
||||
.Xr sshd 8
|
||||
for more information.
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
first appeared in
|
||||
.Nx 1.5 .
|
||||
.Sh AUTHOR
|
||||
Markus Friedl <markus@openbsd.org>
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr sshd 8
|
||||
.Sh AUTHORS
|
||||
Markus Friedl <markus@openbsd.org>
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
first appeared in
|
||||
.Nx 1.5 .
|
||||
|
43
crypto/dist/ssh/ssh-add.1
vendored
43
crypto/dist/ssh/ssh-add.1
vendored
@ -1,6 +1,6 @@
|
||||
.\" -*- nroff -*-
|
||||
.\"
|
||||
.\" $NetBSD: ssh-add.1,v 1.1.1.1 2000/09/28 22:10:25 thorpej Exp $
|
||||
.\" $NetBSD: ssh-add.1,v 1.1.1.2 2001/01/14 04:50:41 itojun Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -79,8 +79,7 @@ The options are as follows:
|
||||
.It Fl l
|
||||
Lists fingerprints of all identities currently represented by the agent.
|
||||
.It Fl L
|
||||
Lists public key parameters of all identities currently represented by
|
||||
the agent.
|
||||
Lists public key parameters of all identities currently represented by the agent.
|
||||
.It Fl d
|
||||
Instead of adding the identity, removes the identity from the agent.
|
||||
.It Fl D
|
||||
@ -105,22 +104,30 @@ Contains the DSA authentication identity of the user.
|
||||
.Pp
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width "SSH_ASKPASS"
|
||||
.It Ev DISPLAY
|
||||
If set, indicates the X11 display associated with a session. This
|
||||
is the display that the external Passphrase prompting program will
|
||||
be run on.
|
||||
.It Ev SSH_ASKPASS
|
||||
If set, indicates the program to use as the external Passphrase
|
||||
prompter. If unset,
|
||||
.Bl -tag -width Ds
|
||||
.It Ev "DISPLAY" and "SSH_ASKPASS"
|
||||
If
|
||||
.Nm
|
||||
will use the default
|
||||
.Pa /usr/X11R6/bin/ssh-askpass .
|
||||
This environment variable is useful for selecting Passphrase prompters
|
||||
that are part of integrated desktop environments, such as
|
||||
.Em GNOME
|
||||
or
|
||||
.Em KDE .
|
||||
needs a passphrase, it will read the passphrase from the current
|
||||
terminal if it was run from a terminal.
|
||||
If
|
||||
.Nm
|
||||
does not have a terminal associated with it but
|
||||
.Ev DISPLAY
|
||||
and
|
||||
.Ev SSH_ASKPASS
|
||||
are set, it will execute the program specified by
|
||||
.Ev SSH_ASKPASS
|
||||
and open an X11 window to read the passphrase.
|
||||
This is particularly useful when calling
|
||||
.Nm
|
||||
from a
|
||||
.Pa .Xsession
|
||||
or related script.
|
||||
(Note that on some machines it
|
||||
may be necessary to redirect the input from
|
||||
.Pa /dev/null
|
||||
to make this work.)
|
||||
.El
|
||||
.Sh AUTHOR
|
||||
Tatu Ylonen <ylo@cs.hut.fi>, Markus Friedl
|
||||
|
33
crypto/dist/ssh/ssh-agent.1
vendored
33
crypto/dist/ssh/ssh-agent.1
vendored
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" $NetBSD: ssh-agent.1,v 1.1.1.1 2000/09/28 22:10:27 thorpej Exp $
|
||||
.\" $NetBSD: ssh-agent.1,v 1.1.1.2 2001/01/14 04:50:42 itojun Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -45,12 +45,12 @@
|
||||
.Nd authentication agent for the Secure Shell
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-agent
|
||||
.Op Fl c Li | Fl s
|
||||
.Op Fl k
|
||||
.Oo
|
||||
.Ar command
|
||||
.Op Ar args ...
|
||||
.Oc
|
||||
.Ar args ...
|
||||
.Nm ssh-agent
|
||||
.Op Fl c Li | Fl s
|
||||
.Nm ssh-agent
|
||||
.Fl k
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a program to hold private keys used for public key (RSA or DSA)
|
||||
@ -193,11 +193,24 @@ fi
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa $HOME/.ssh/identity
|
||||
Contains the RSA authentication identity of the user.
|
||||
This file should not be readable by anyone but the user.
|
||||
It is possible to
|
||||
specify a passphrase when generating the key; that passphrase will be
|
||||
used to encrypt the private part of this file.
|
||||
This file is not used by
|
||||
.Nm
|
||||
but is normally added to the agent using
|
||||
.Xr ssh-add 1
|
||||
at login time.
|
||||
.It Pa $HOME/.ssh/id_dsa
|
||||
Contains the DSA authentication identity of the user.
|
||||
.It Pa /tmp/ssh-XXXXXXXX/agent.<pid>
|
||||
Unix-domain sockets used to communicate with the
|
||||
authentication agent. These sockets should only be readable by the
|
||||
owner. The sockets should get automatically removed when the agent
|
||||
exits.
|
||||
Unix-domain sockets used to contain the connection to the
|
||||
authentication agent.
|
||||
These sockets should only be readable by the owner.
|
||||
The sockets should get automatically removed when the agent exits.
|
||||
.El
|
||||
.Sh AUTHOR
|
||||
Tatu Ylonen <ylo@cs.hut.fi>, Markus Friedl
|
||||
|
225
crypto/dist/ssh/ssh-dss.c
vendored
Normal file
225
crypto/dist/ssh/ssh-dss.c
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
/* $NetBSD: ssh-dss.c,v 1.1.1.1 2001/01/14 04:51:07 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 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.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: ssh-dss.c,v 1.2 2000/12/19 23:17:58 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ssh-dss.c,v 1.1.1.1 2001/01/14 04:51:07 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "key.h"
|
||||
#include "ssh-dss.h"
|
||||
|
||||
#define INTBLOB_LEN 20
|
||||
#define SIGBLOB_LEN (2*INTBLOB_LEN)
|
||||
|
||||
int
|
||||
ssh_dss_sign(
|
||||
Key *key,
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
u_char *digest;
|
||||
u_char *ret;
|
||||
DSA_SIG *sig;
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
u_int rlen;
|
||||
u_int slen;
|
||||
u_int len;
|
||||
u_char sigblob[SIGBLOB_LEN];
|
||||
Buffer b;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
error("ssh_dss_sign: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
digest = xmalloc(evp_md->md_size);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
|
||||
if (sig == NULL) {
|
||||
fatal("ssh_dss_sign: cannot sign");
|
||||
}
|
||||
|
||||
rlen = BN_num_bytes(sig->r);
|
||||
slen = BN_num_bytes(sig->s);
|
||||
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
|
||||
error("bad sig size %d %d", rlen, slen);
|
||||
DSA_SIG_free(sig);
|
||||
return -1;
|
||||
}
|
||||
debug("sig size %d %d", rlen, slen);
|
||||
|
||||
memset(sigblob, 0, SIGBLOB_LEN);
|
||||
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
|
||||
BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
debug("datafellows");
|
||||
ret = xmalloc(SIGBLOB_LEN);
|
||||
memcpy(ret, sigblob, SIGBLOB_LEN);
|
||||
if (lenp != NULL)
|
||||
*lenp = SIGBLOB_LEN;
|
||||
if (sigp != NULL)
|
||||
*sigp = ret;
|
||||
} else {
|
||||
/* ietf-drafts */
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, "ssh-dss");
|
||||
buffer_put_string(&b, sigblob, SIGBLOB_LEN);
|
||||
len = buffer_len(&b);
|
||||
ret = xmalloc(len);
|
||||
memcpy(ret, buffer_ptr(&b), len);
|
||||
buffer_free(&b);
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (sigp != NULL)
|
||||
*sigp = ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
ssh_dss_verify(
|
||||
Key *key,
|
||||
u_char *signature, int signaturelen,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
Buffer b;
|
||||
u_char *digest;
|
||||
DSA_SIG *sig;
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
u_char *sigblob;
|
||||
char *txt;
|
||||
u_int len, dlen;
|
||||
int rlen;
|
||||
int ret;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
error("ssh_dss_verify: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(datafellows & SSH_BUG_SIGBLOB) &&
|
||||
signaturelen == SIGBLOB_LEN) {
|
||||
datafellows |= ~SSH_BUG_SIGBLOB;
|
||||
log("autodetect SSH_BUG_SIGBLOB");
|
||||
} else if ((datafellows & SSH_BUG_SIGBLOB) &&
|
||||
signaturelen != SIGBLOB_LEN) {
|
||||
log("autoremove SSH_BUG_SIGBLOB");
|
||||
datafellows &= ~SSH_BUG_SIGBLOB;
|
||||
}
|
||||
|
||||
debug("len %d datafellows %d", signaturelen, datafellows);
|
||||
|
||||
/* fetch signature */
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
sigblob = signature;
|
||||
len = signaturelen;
|
||||
} else {
|
||||
/* ietf-drafts */
|
||||
char *ktype;
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, (char *) signature, signaturelen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
if (strcmp("ssh-dss", ktype) != 0) {
|
||||
error("ssh_dss_verify: cannot handle type %s", ktype);
|
||||
buffer_free(&b);
|
||||
return -1;
|
||||
}
|
||||
sigblob = (u_char *)buffer_get_string(&b, &len);
|
||||
rlen = buffer_len(&b);
|
||||
if(rlen != 0) {
|
||||
error("remaining bytes in signature %d", rlen);
|
||||
buffer_free(&b);
|
||||
return -1;
|
||||
}
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
}
|
||||
|
||||
if (len != SIGBLOB_LEN) {
|
||||
fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
|
||||
}
|
||||
|
||||
/* parse signature */
|
||||
sig = DSA_SIG_new();
|
||||
sig->r = BN_new();
|
||||
sig->s = BN_new();
|
||||
BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
|
||||
BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
|
||||
|
||||
if (!(datafellows & SSH_BUG_SIGBLOB)) {
|
||||
memset(sigblob, 0, len);
|
||||
xfree(sigblob);
|
||||
}
|
||||
|
||||
/* sha1 the data */
|
||||
dlen = evp_md->md_size;
|
||||
digest = xmalloc(dlen);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
ret = DSA_do_verify(digest, dlen, sig, key->dsa);
|
||||
|
||||
memset(digest, 0, dlen);
|
||||
xfree(digest);
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
switch (ret) {
|
||||
case 1:
|
||||
txt = "correct";
|
||||
break;
|
||||
case 0:
|
||||
txt = "incorrect";
|
||||
break;
|
||||
case -1:
|
||||
default:
|
||||
txt = "error";
|
||||
break;
|
||||
}
|
||||
debug("ssh_dss_verify: signature %s", txt);
|
||||
return ret;
|
||||
}
|
39
crypto/dist/ssh/ssh-dss.h
vendored
Normal file
39
crypto/dist/ssh/ssh-dss.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2000 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.
|
||||
*/
|
||||
#ifndef DSA_H
|
||||
#define DSA_H
|
||||
|
||||
int
|
||||
ssh_dss_sign(
|
||||
Key *key,
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen);
|
||||
|
||||
int
|
||||
ssh_dss_verify(
|
||||
Key *key,
|
||||
u_char *signature, int signaturelen,
|
||||
u_char *data, int datalen);
|
||||
|
||||
#endif
|
70
crypto/dist/ssh/ssh-keygen.1
vendored
70
crypto/dist/ssh/ssh-keygen.1
vendored
@ -1,6 +1,6 @@
|
||||
.\" -*- nroff -*-
|
||||
.\"
|
||||
.\" $NetBSD: ssh-keygen.1,v 1.1.1.1 2000/09/28 22:10:29 thorpej Exp $
|
||||
.\" $NetBSD: ssh-keygen.1,v 1.1.1.2 2001/01/14 04:50:44 itojun Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -45,8 +45,9 @@
|
||||
.Nd generate Secure Shell authentication keys
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-keygen
|
||||
.Op Fl dq
|
||||
.Op Fl q
|
||||
.Op Fl b Ar bits
|
||||
.Op Fl t Ar type
|
||||
.Op Fl N Ar new_passphrase
|
||||
.Op Fl C Ar comment
|
||||
.Op Fl f Ar output_keyfile
|
||||
@ -81,12 +82,12 @@ generates and manages authentication keys for
|
||||
.Nm
|
||||
defaults to generating an RSA key for use by protocols 1.3 and 1.5;
|
||||
specifying the
|
||||
.Fl d
|
||||
flag will create a DSA key for use by protocol 2.0.
|
||||
.Fl t
|
||||
allows you to create a key for use by protocol 2.0.
|
||||
.Pp
|
||||
Normally each user wishing to use Secure Shell
|
||||
with RSA or DSA authentication runs this once to create the
|
||||
authentication key in
|
||||
with RSA or DSA authentication runs this once to create the authentication
|
||||
key in
|
||||
.Pa $HOME/.ssh/identity
|
||||
or
|
||||
.Pa $HOME/.ssh/id_dsa .
|
||||
@ -107,13 +108,14 @@ The passphrase may be empty to indicate no passphrase
|
||||
arbitrary length.
|
||||
Good passphrases are 10-30 characters long and are
|
||||
not simple sentences or otherwise easily guessable (English
|
||||
prose has only 1-2 bits of entropy per word, and makes very bad
|
||||
prose has only 1-2 bits of entropy per word, and provides very bad
|
||||
passphrases).
|
||||
The passphrase can be changed later by using the
|
||||
.Fl p
|
||||
option.
|
||||
.Pp
|
||||
There is no way to recover a lost passphrase. If the passphrase is
|
||||
There is no way to recover a lost passphrase.
|
||||
If the passphrase is
|
||||
lost or forgotten, you will have to generate a new key and copy the
|
||||
corresponding public key to other machines.
|
||||
.Pp
|
||||
@ -157,6 +159,17 @@ Silence
|
||||
Used by
|
||||
.Pa /etc/rc.d/sshd
|
||||
when creating a new key.
|
||||
.It Fl t Ar type
|
||||
Specifies the type of the key to create.
|
||||
The possible values are
|
||||
.Dq rsa1
|
||||
for protocol version 1 and
|
||||
.Dq rsa
|
||||
or
|
||||
.Dq dsa
|
||||
for protocol version 2.
|
||||
The default is
|
||||
.Dq rsa .
|
||||
.It Fl C Ar comment
|
||||
Provides the new comment.
|
||||
.It Fl N Ar new_passphrase
|
||||
@ -168,36 +181,40 @@ If RSA support is functional, immediately exits with code 0. If RSA
|
||||
support is not functional, exits with code 1. This flag will be
|
||||
removed once the RSA patent expires.
|
||||
.It Fl x
|
||||
This option will read a private OpenSSH-compatible DSA format file and
|
||||
print a SSH2-compatible public key to stdout.
|
||||
This option will read a private
|
||||
OpenSSH DSA format file and print a SSH2-compatible public key to stdout.
|
||||
.It Fl X
|
||||
This option will read a SSH2-compatible public key file and print an
|
||||
OpenSSH-compatible DSA public key to stdout.
|
||||
This option will read a unencrypted
|
||||
SSH2-compatible private (or public) key file and
|
||||
print an OpenSSH compatible private (or public) key to stdout.
|
||||
.It Fl y
|
||||
This option will read a private OpenSSH-compatible DSA format file and
|
||||
print an OpenSSH-compatible DSA public key to stdout.
|
||||
This option will read a private
|
||||
OpenSSH format file and print an OpenSSH public key to stdout.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa $HOME/.ssh/identity
|
||||
Contains the RSA authentication identity of the user.
|
||||
This file should not be readable by anyone but the user.
|
||||
It is possible to specify a passphrase when generating the key; that
|
||||
passphrase will be used to encrypt the private part of this file using
|
||||
3DES. This file is not automatically accessed by
|
||||
It is possible to
|
||||
specify a passphrase when generating the key; that passphrase will be
|
||||
used to encrypt the private part of this file using 3DES.
|
||||
This file is not automatically accessed by
|
||||
.Nm
|
||||
but it is offered as the default file for the private key.
|
||||
.Xr sshd 8
|
||||
will read this file when a login attempt is made.
|
||||
.It Pa $HOME/.ssh/identity.pub
|
||||
Contains the public key for authentication. The contents of this file
|
||||
should be added to
|
||||
Contains the public key for authentication.
|
||||
The contents of this file should be added to
|
||||
.Pa $HOME/.ssh/authorized_keys
|
||||
on all machines where you wish to log in using RSA authentication.
|
||||
on all machines
|
||||
where you wish to log in using RSA authentication.
|
||||
There is no need to keep the contents of this file secret.
|
||||
.It Pa $HOME/.ssh/id_dsa
|
||||
Contains the DSA authentication identity of the user. This file
|
||||
should not be readable by anyone but the user. It is possible to
|
||||
Contains the DSA authentication identity of the user.
|
||||
This file should not be readable by anyone but the user.
|
||||
It is possible to
|
||||
specify a passphrase when generating the key; that passphrase will be
|
||||
used to encrypt the private part of this file using 3DES.
|
||||
This file is not automatically accessed by
|
||||
@ -206,13 +223,14 @@ but it is offered as the default file for the private key.
|
||||
.Xr sshd 8
|
||||
will read this file when a login attempt is made.
|
||||
.It Pa $HOME/.ssh/id_dsa.pub
|
||||
Contains the public key for authentication. The contents of this
|
||||
file should be added to
|
||||
Contains the public key for authentication.
|
||||
The contents of this file should be added to
|
||||
.Pa $HOME/.ssh/authorized_keys2
|
||||
on all machines where you wish to log in using DSA authentication.
|
||||
on all machines
|
||||
where you wish to log in using public key authentication.
|
||||
There is no need to keep the contents of this file secret.
|
||||
.El
|
||||
.Sh AUTHOR
|
||||
.Sh AUTHORS
|
||||
Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
|
95
crypto/dist/ssh/ssh-keyscan.1
vendored
Normal file
95
crypto/dist/ssh/ssh-keyscan.1
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
.Dd January 1, 1996
|
||||
.Dt ssh-keyscan 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ssh-keyscan
|
||||
.Nd gather ssh public keys
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-keyscan
|
||||
.Op Fl t Ar timeout
|
||||
.Op Ar -- | host | addrlist namelist
|
||||
.Op Fl f Ar files ...
|
||||
.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
|
||||
.Pa ssh_known_hosts
|
||||
files.
|
||||
.Nm
|
||||
provides a minimal interface suitable for use by shell and perl
|
||||
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
|
||||
hosts can be collected in tens of seconds, even when some of those
|
||||
hosts are down or do not run ssh. You do not need login access to the
|
||||
machines you are scanning, nor does does the scanning process involve
|
||||
any encryption.
|
||||
.Sh SECURITY
|
||||
If you make an ssh_known_hosts file using
|
||||
.Nm
|
||||
without verifying the keys, you will be vulnerable to
|
||||
.I man in the middle
|
||||
attacks.
|
||||
On the other hand, if your security model allows such a risk,
|
||||
.Nm
|
||||
can help you detect tampered keyfiles or man in the middle attacks which
|
||||
have begun after you created your ssh_known_hosts file.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width Ds
|
||||
.It Fl t
|
||||
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.
|
||||
.It Fl f
|
||||
Read hosts or
|
||||
.Pa addrlist namelist
|
||||
pairs from this file, one per line.
|
||||
If
|
||||
.Pa -
|
||||
is supplied instead of a filename,
|
||||
.Nm
|
||||
will read hosts or
|
||||
.Pa addrlist namelist
|
||||
pairs from the standard input.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Pp
|
||||
Print the host key for machine
|
||||
.Pa hostname :
|
||||
.Bd -literal
|
||||
ssh-keyscan hostname
|
||||
.Ed
|
||||
.Pp
|
||||
Find all hosts from the file
|
||||
.Pa ssh_hosts
|
||||
which have new or different keys from those in the sorted file
|
||||
.Pa ssh_known_hosts :
|
||||
.Bd -literal
|
||||
ssh-keyscan -f ssh_hosts | sort -u - ssh_known_hosts | \e\
|
||||
diff ssh_known_hosts -
|
||||
.Ed
|
||||
.Pp
|
||||
.Sh FILES
|
||||
.Pp
|
||||
.Pa Input format:
|
||||
1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
|
||||
.Pp
|
||||
.Pa Output format:
|
||||
host-or-namelist bits exponent modulus
|
||||
.Pp
|
||||
.Pa /etc/ssh_known_hosts
|
||||
.Sh BUGS
|
||||
It generates "Connection closed by remote host" messages on the consoles
|
||||
of all the machines it scans.
|
||||
This is because it opens a connection to the ssh port, reads the public
|
||||
key, and drops the connection as soon as it gets the key.
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1
|
||||
.Xr sshd 8
|
||||
.Sh AUTHOR
|
||||
David Mazieres <dm@lcs.mit.edu>
|
607
crypto/dist/ssh/ssh-keyscan.c
vendored
Normal file
607
crypto/dist/ssh/ssh-keyscan.c
vendored
Normal file
@ -0,0 +1,607 @@
|
||||
/* $NetBSD: ssh-keyscan.c,v 1.1.1.1 2001/01/14 04:51:09 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
|
||||
*
|
||||
* Modification and redistribution in source and binary forms is
|
||||
* permitted provided that due credit is given to the author and the
|
||||
* OpenBSD project (for instance by leaving this copyright notice
|
||||
* intact).
|
||||
*/
|
||||
|
||||
/* OpenBSD: ssh-keyscan.c,v 1.6 2000/12/19 23:17:58 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ssh-keyscan.c,v 1.1.1.1 2001/01/14 04:51:09 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "key.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
|
||||
static int argno = 1; /* Number of argument currently being parsed */
|
||||
|
||||
int family = AF_UNSPEC; /* IPv4, IPv6 or both */
|
||||
|
||||
#define PORT 22
|
||||
#define MAXMAXFD 256
|
||||
|
||||
/* The number of seconds after which to give up on a TCP connection */
|
||||
int timeout = 5;
|
||||
|
||||
int maxfd;
|
||||
#define maxcon (maxfd - 10)
|
||||
|
||||
extern char *__progname;
|
||||
fd_set read_wait;
|
||||
int ncon;
|
||||
|
||||
/*
|
||||
* Keep a connection structure for each file descriptor. The state
|
||||
* associated with file descriptor n is held in fdcon[n].
|
||||
*/
|
||||
typedef struct Connection {
|
||||
u_char c_status; /* State of connection on this file desc. */
|
||||
#define CS_UNUSED 0 /* File descriptor unused */
|
||||
#define CS_CON 1 /* Waiting to connect/read greeting */
|
||||
#define CS_SIZE 2 /* Waiting to read initial packet size */
|
||||
#define CS_KEYS 3 /* Waiting to read public key packet */
|
||||
int c_fd; /* Quick lookup: c->c_fd == c - fdcon */
|
||||
int c_plen; /* Packet length field for ssh packet */
|
||||
int c_len; /* Total bytes which must be read. */
|
||||
int c_off; /* Length of data read so far. */
|
||||
char *c_namebase; /* Address to free for c_name and c_namelist */
|
||||
char *c_name; /* Hostname of connection for errors */
|
||||
char *c_namelist; /* Pointer to other possible addresses */
|
||||
char *c_output_name; /* Hostname of connection for output */
|
||||
char *c_data; /* Data read from this fd */
|
||||
struct timeval c_tv; /* Time at which connection gets aborted */
|
||||
TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */
|
||||
} con;
|
||||
|
||||
TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */
|
||||
con *fdcon;
|
||||
|
||||
/*
|
||||
* This is just a wrapper around fgets() to make it usable.
|
||||
*/
|
||||
|
||||
/* Stress-test. Increase this later. */
|
||||
#define LINEBUF_SIZE 16
|
||||
|
||||
typedef struct {
|
||||
char *buf;
|
||||
u_int size;
|
||||
int lineno;
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
void (*errfun) (const char *,...);
|
||||
} Linebuf;
|
||||
|
||||
static inline Linebuf *
|
||||
Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
|
||||
{
|
||||
Linebuf *lb;
|
||||
|
||||
if (!(lb = malloc(sizeof(*lb)))) {
|
||||
if (errfun)
|
||||
(*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
|
||||
return (NULL);
|
||||
}
|
||||
if (filename) {
|
||||
lb->filename = filename;
|
||||
if (!(lb->stream = fopen(filename, "r"))) {
|
||||
free(lb);
|
||||
if (errfun)
|
||||
(*errfun) ("%s: %s\n", filename, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
lb->filename = "(stdin)";
|
||||
lb->stream = stdin;
|
||||
}
|
||||
|
||||
if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) {
|
||||
if (errfun)
|
||||
(*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
|
||||
free(lb);
|
||||
return (NULL);
|
||||
}
|
||||
lb->errfun = errfun;
|
||||
lb->lineno = 0;
|
||||
return (lb);
|
||||
}
|
||||
|
||||
static inline void
|
||||
Linebuf_free(Linebuf * lb)
|
||||
{
|
||||
fclose(lb->stream);
|
||||
free(lb->buf);
|
||||
free(lb);
|
||||
}
|
||||
|
||||
static inline void
|
||||
Linebuf_restart(Linebuf * lb)
|
||||
{
|
||||
clearerr(lb->stream);
|
||||
rewind(lb->stream);
|
||||
lb->lineno = 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
Linebuf_lineno(Linebuf * lb)
|
||||
{
|
||||
return (lb->lineno);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
getline(Linebuf * lb)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
lb->lineno++;
|
||||
for (;;) {
|
||||
/* Read a line */
|
||||
if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) {
|
||||
if (ferror(lb->stream) && lb->errfun)
|
||||
(*lb->errfun) ("%s: %s\n", lb->filename, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
n = strlen(lb->buf);
|
||||
|
||||
/* Return it or an error if it fits */
|
||||
if (n > 0 && lb->buf[n - 1] == '\n') {
|
||||
lb->buf[n - 1] = '\0';
|
||||
return (lb->buf);
|
||||
}
|
||||
if (n != lb->size - 1) {
|
||||
if (lb->errfun)
|
||||
(*lb->errfun) ("%s: skipping incomplete last line\n", lb->filename);
|
||||
return (NULL);
|
||||
}
|
||||
/* Double the buffer if we need more space */
|
||||
if (!(lb->buf = realloc(lb->buf, (lb->size *= 2)))) {
|
||||
if (lb->errfun)
|
||||
(*lb->errfun) ("linebuf (%s): realloc failed\n", lb->filename);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
fdlim_get(int hard)
|
||||
{
|
||||
struct rlimit rlfd;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
|
||||
return (-1);
|
||||
if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)
|
||||
return 10000;
|
||||
else
|
||||
return hard ? rlfd.rlim_max : rlfd.rlim_cur;
|
||||
}
|
||||
|
||||
static int
|
||||
fdlim_set(int lim)
|
||||
{
|
||||
struct rlimit rlfd;
|
||||
if (lim <= 0)
|
||||
return (-1);
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
|
||||
return (-1);
|
||||
rlfd.rlim_cur = lim;
|
||||
if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is an strsep function that returns a null field for adjacent
|
||||
* separators. This is the same as the 4.4BSD strsep, but different from the
|
||||
* one in the GNU libc.
|
||||
*/
|
||||
static inline char *
|
||||
xstrsep(char **str, const char *delim)
|
||||
{
|
||||
char *s, *e;
|
||||
|
||||
if (!**str)
|
||||
return (NULL);
|
||||
|
||||
s = *str;
|
||||
e = s + strcspn(s, delim);
|
||||
|
||||
if (*e != '\0')
|
||||
*e++ = '\0';
|
||||
*str = e;
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next non-null token (like GNU strsep). Strsep() will return a
|
||||
* null token for two adjacent separators, so we may have to loop.
|
||||
*/
|
||||
static char *
|
||||
strnnsep(char **stringp, char *delim)
|
||||
{
|
||||
char *tok;
|
||||
|
||||
do {
|
||||
tok = xstrsep(stringp, delim);
|
||||
} while (tok && *tok == '\0');
|
||||
return (tok);
|
||||
}
|
||||
|
||||
static void
|
||||
keyprint(char *host, char *output_name, char *kd, int len)
|
||||
{
|
||||
static Key *rsa;
|
||||
static Buffer msg;
|
||||
|
||||
if (rsa == NULL) {
|
||||
buffer_init(&msg);
|
||||
rsa = key_new(KEY_RSA1);
|
||||
}
|
||||
buffer_append(&msg, kd, len);
|
||||
buffer_consume(&msg, 8 - (len & 7)); /* padding */
|
||||
if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) {
|
||||
error("%s: invalid packet type", host);
|
||||
buffer_clear(&msg);
|
||||
return;
|
||||
}
|
||||
buffer_consume(&msg, 8); /* cookie */
|
||||
|
||||
/* server key */
|
||||
(void) buffer_get_int(&msg);
|
||||
buffer_get_bignum(&msg, rsa->rsa->e);
|
||||
buffer_get_bignum(&msg, rsa->rsa->n);
|
||||
|
||||
/* host key */
|
||||
(void) buffer_get_int(&msg);
|
||||
buffer_get_bignum(&msg, rsa->rsa->e);
|
||||
buffer_get_bignum(&msg, rsa->rsa->n);
|
||||
buffer_clear(&msg);
|
||||
|
||||
fprintf(stdout, "%s ", output_name ? output_name : host);
|
||||
key_write(rsa, stdout);
|
||||
fputs("\n", stdout);
|
||||
}
|
||||
|
||||
static int
|
||||
tcpconnect(char *host)
|
||||
{
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char strport[NI_MAXSERV];
|
||||
int gaierr, s = -1;
|
||||
|
||||
snprintf(strport, sizeof strport, "%d", PORT);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
|
||||
fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));
|
||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
||||
s = socket(ai->ai_family, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
error("socket: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if (fcntl(s, F_SETFL, O_NDELAY) < 0)
|
||||
fatal("F_SETFL: %s", strerror(errno));
|
||||
if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 &&
|
||||
errno != EINPROGRESS)
|
||||
error("connect (`%s'): %s", host, strerror(errno));
|
||||
else
|
||||
break;
|
||||
close(s);
|
||||
s = -1;
|
||||
}
|
||||
freeaddrinfo(aitop);
|
||||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
conalloc(char *iname, char *oname)
|
||||
{
|
||||
int s;
|
||||
char *namebase, *name, *namelist;
|
||||
|
||||
namebase = namelist = xstrdup(iname);
|
||||
|
||||
do {
|
||||
name = xstrsep(&namelist, ",");
|
||||
if (!name) {
|
||||
free(namebase);
|
||||
return (-1);
|
||||
}
|
||||
} while ((s = tcpconnect(name)) < 0);
|
||||
|
||||
if (s >= maxfd)
|
||||
fatal("conalloc: fdno %d too high", s);
|
||||
if (fdcon[s].c_status)
|
||||
fatal("conalloc: attempt to reuse fdno %d", s);
|
||||
|
||||
fdcon[s].c_fd = s;
|
||||
fdcon[s].c_status = CS_CON;
|
||||
fdcon[s].c_namebase = namebase;
|
||||
fdcon[s].c_name = name;
|
||||
fdcon[s].c_namelist = namelist;
|
||||
fdcon[s].c_output_name = xstrdup(oname);
|
||||
fdcon[s].c_data = (char *) &fdcon[s].c_plen;
|
||||
fdcon[s].c_len = 4;
|
||||
fdcon[s].c_off = 0;
|
||||
gettimeofday(&fdcon[s].c_tv, NULL);
|
||||
fdcon[s].c_tv.tv_sec += timeout;
|
||||
TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
|
||||
FD_SET(s, &read_wait);
|
||||
ncon++;
|
||||
return (s);
|
||||
}
|
||||
|
||||
static void
|
||||
confree(int s)
|
||||
{
|
||||
close(s);
|
||||
if (s >= maxfd || fdcon[s].c_status == CS_UNUSED)
|
||||
fatal("confree: attempt to free bad fdno %d", s);
|
||||
free(fdcon[s].c_namebase);
|
||||
free(fdcon[s].c_output_name);
|
||||
if (fdcon[s].c_status == CS_KEYS)
|
||||
free(fdcon[s].c_data);
|
||||
fdcon[s].c_status = CS_UNUSED;
|
||||
TAILQ_REMOVE(&tq, &fdcon[s], c_link);
|
||||
FD_CLR(s, &read_wait);
|
||||
ncon--;
|
||||
}
|
||||
|
||||
static void
|
||||
contouch(int s)
|
||||
{
|
||||
TAILQ_REMOVE(&tq, &fdcon[s], c_link);
|
||||
gettimeofday(&fdcon[s].c_tv, NULL);
|
||||
fdcon[s].c_tv.tv_sec += timeout;
|
||||
TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
|
||||
}
|
||||
|
||||
static int
|
||||
conrecycle(int s)
|
||||
{
|
||||
int ret;
|
||||
con *c = &fdcon[s];
|
||||
char *iname, *oname;
|
||||
|
||||
iname = xstrdup(c->c_namelist);
|
||||
oname = c->c_output_name;
|
||||
c->c_output_name = NULL;/* prevent it from being freed */
|
||||
confree(s);
|
||||
ret = conalloc(iname, oname);
|
||||
free(iname);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
congreet(int s)
|
||||
{
|
||||
char buf[80];
|
||||
int n;
|
||||
con *c = &fdcon[s];
|
||||
|
||||
n = read(s, buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
if (errno != ECONNREFUSED)
|
||||
error("read (%s): %s", c->c_name, strerror(errno));
|
||||
conrecycle(s);
|
||||
return;
|
||||
}
|
||||
if (buf[n - 1] != '\n') {
|
||||
error("%s: bad greeting", c->c_name);
|
||||
confree(s);
|
||||
return;
|
||||
}
|
||||
buf[n - 1] = '\0';
|
||||
fprintf(stderr, "# %s %s\n", c->c_name, buf);
|
||||
n = snprintf(buf, sizeof buf, "SSH-1.5-OpenSSH-keyscan\r\n");
|
||||
if (write(s, buf, n) != n) {
|
||||
error("write (%s): %s", c->c_name, strerror(errno));
|
||||
confree(s);
|
||||
return;
|
||||
}
|
||||
c->c_status = CS_SIZE;
|
||||
contouch(s);
|
||||
}
|
||||
|
||||
static void
|
||||
conread(int s)
|
||||
{
|
||||
int n;
|
||||
con *c = &fdcon[s];
|
||||
|
||||
if (c->c_status == CS_CON) {
|
||||
congreet(s);
|
||||
return;
|
||||
}
|
||||
n = read(s, c->c_data + c->c_off, c->c_len - c->c_off);
|
||||
if (n < 0) {
|
||||
error("read (%s): %s", c->c_name, strerror(errno));
|
||||
confree(s);
|
||||
return;
|
||||
}
|
||||
c->c_off += n;
|
||||
|
||||
if (c->c_off == c->c_len)
|
||||
switch (c->c_status) {
|
||||
case CS_SIZE:
|
||||
c->c_plen = htonl(c->c_plen);
|
||||
c->c_len = c->c_plen + 8 - (c->c_plen & 7);
|
||||
c->c_off = 0;
|
||||
c->c_data = xmalloc(c->c_len);
|
||||
c->c_status = CS_KEYS;
|
||||
break;
|
||||
case CS_KEYS:
|
||||
keyprint(c->c_name, c->c_output_name, c->c_data, c->c_plen);
|
||||
confree(s);
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
fatal("conread: invalid status %d", c->c_status);
|
||||
break;
|
||||
}
|
||||
|
||||
contouch(s);
|
||||
}
|
||||
|
||||
static void
|
||||
conloop(void)
|
||||
{
|
||||
fd_set r, e;
|
||||
struct timeval seltime, now;
|
||||
int i;
|
||||
con *c;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
c = tq.tqh_first;
|
||||
|
||||
if (c &&
|
||||
(c->c_tv.tv_sec > now.tv_sec ||
|
||||
(c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) {
|
||||
seltime = c->c_tv;
|
||||
seltime.tv_sec -= now.tv_sec;
|
||||
seltime.tv_usec -= now.tv_usec;
|
||||
if ((int) seltime.tv_usec < 0) {
|
||||
seltime.tv_usec += 1000000;
|
||||
seltime.tv_sec--;
|
||||
}
|
||||
} else
|
||||
seltime.tv_sec = seltime.tv_usec = 0;
|
||||
|
||||
r = e = read_wait;
|
||||
select(maxfd, &r, NULL, &e, &seltime);
|
||||
for (i = 0; i < maxfd; i++)
|
||||
if (FD_ISSET(i, &e)) {
|
||||
error("%s: exception!", fdcon[i].c_name);
|
||||
confree(i);
|
||||
} else if (FD_ISSET(i, &r))
|
||||
conread(i);
|
||||
|
||||
c = tq.tqh_first;
|
||||
while (c &&
|
||||
(c->c_tv.tv_sec < now.tv_sec ||
|
||||
(c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) {
|
||||
int s = c->c_fd;
|
||||
c = c->c_link.tqe_next;
|
||||
conrecycle(s);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
nexthost(int argc, char **argv)
|
||||
{
|
||||
static Linebuf *lb;
|
||||
|
||||
for (;;) {
|
||||
if (!lb) {
|
||||
if (argno >= argc)
|
||||
return (NULL);
|
||||
if (argv[argno][0] != '-')
|
||||
return (argv[argno++]);
|
||||
if (!strcmp(argv[argno], "--")) {
|
||||
if (++argno >= argc)
|
||||
return (NULL);
|
||||
return (argv[argno++]);
|
||||
} else if (!strncmp(argv[argno], "-f", 2)) {
|
||||
char *fname;
|
||||
if (argv[argno][2])
|
||||
fname = &argv[argno++][2];
|
||||
else if (++argno >= argc) {
|
||||
error("missing filename for `-f'");
|
||||
return (NULL);
|
||||
} else
|
||||
fname = argv[argno++];
|
||||
if (!strcmp(fname, "-"))
|
||||
fname = NULL;
|
||||
lb = Linebuf_alloc(fname, error);
|
||||
} else
|
||||
error("ignoring invalid/misplaced option `%s'", argv[argno++]);
|
||||
} else {
|
||||
char *line;
|
||||
line = getline(lb);
|
||||
if (line)
|
||||
return (line);
|
||||
Linebuf_free(lb);
|
||||
lb = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fatal("usage: %s [-t timeout] { [--] host | -f file } ...", __progname);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *host = NULL;
|
||||
|
||||
TAILQ_INIT(&tq);
|
||||
|
||||
if (argc <= argno)
|
||||
usage();
|
||||
|
||||
if (argv[1][0] == '-' && argv[1][1] == 't') {
|
||||
argno++;
|
||||
if (argv[1][2])
|
||||
timeout = atoi(&argv[1][2]);
|
||||
else {
|
||||
if (argno >= argc)
|
||||
usage();
|
||||
timeout = atoi(argv[argno++]);
|
||||
}
|
||||
if (timeout <= 0)
|
||||
usage();
|
||||
}
|
||||
if (argc <= argno)
|
||||
usage();
|
||||
|
||||
maxfd = fdlim_get(1);
|
||||
if (maxfd < 0)
|
||||
fatal("%s: fdlim_get: bad value", __progname);
|
||||
if (maxfd > MAXMAXFD)
|
||||
maxfd = MAXMAXFD;
|
||||
if (maxcon <= 0)
|
||||
fatal("%s: not enough file descriptors", __progname);
|
||||
if (maxfd > fdlim_get(0))
|
||||
fdlim_set(maxfd);
|
||||
fdcon = xmalloc(maxfd * sizeof(con));
|
||||
|
||||
do {
|
||||
while (ncon < maxcon) {
|
||||
char *name;
|
||||
|
||||
host = nexthost(argc, argv);
|
||||
if (host == NULL)
|
||||
break;
|
||||
name = strnnsep(&host, " \t\n");
|
||||
conalloc(name, *host ? host : name);
|
||||
}
|
||||
conloop();
|
||||
} while (host);
|
||||
while (ncon > 0)
|
||||
conloop();
|
||||
|
||||
return (0);
|
||||
}
|
172
crypto/dist/ssh/ssh-rsa.c
vendored
Normal file
172
crypto/dist/ssh/ssh-rsa.c
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
/* $NetBSD: ssh-rsa.c,v 1.1.1.1 2001/01/14 04:51:09 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 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.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: ssh-rsa.c,v 1.2 2000/12/19 23:17:58 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ssh-rsa.c,v 1.1.1.1 2001/01/14 04:51:09 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "key.h"
|
||||
#include "ssh-rsa.h"
|
||||
|
||||
#define INTBLOB_LEN 20
|
||||
#define SIGBLOB_LEN (2*INTBLOB_LEN)
|
||||
|
||||
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
|
||||
int
|
||||
ssh_rsa_sign(
|
||||
Key *key,
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
u_char *digest, *sig, *ret;
|
||||
u_int slen, dlen, len;
|
||||
int ok;
|
||||
Buffer b;
|
||||
|
||||
if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
|
||||
error("ssh_rsa_sign: no RSA key");
|
||||
return -1;
|
||||
}
|
||||
slen = RSA_size(key->rsa);
|
||||
sig = xmalloc(slen);
|
||||
|
||||
dlen = evp_md->md_size;
|
||||
digest = xmalloc(dlen);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
ok = RSA_sign(NID_sha1, digest, dlen, sig, &len, key->rsa);
|
||||
memset(digest, 'd', dlen);
|
||||
xfree(digest);
|
||||
|
||||
if (ok != 1) {
|
||||
int ecode = ERR_get_error();
|
||||
error("ssh_rsa_sign: RSA_sign failed: %s", ERR_error_string(ecode, NULL));
|
||||
xfree(sig);
|
||||
return -1;
|
||||
}
|
||||
if (len < slen) {
|
||||
int diff = slen - len;
|
||||
debug("slen %d > len %d", slen, len);
|
||||
memmove(sig + diff, sig, len);
|
||||
memset(sig, 0, diff);
|
||||
} else if (len > slen) {
|
||||
error("ssh_rsa_sign: slen %d slen2 %d", slen, len);
|
||||
xfree(sig);
|
||||
return -1;
|
||||
}
|
||||
/* encode signature */
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, "ssh-rsa");
|
||||
buffer_put_string(&b, sig, slen);
|
||||
len = buffer_len(&b);
|
||||
ret = xmalloc(len);
|
||||
memcpy(ret, buffer_ptr(&b), len);
|
||||
buffer_free(&b);
|
||||
memset(sig, 's', slen);
|
||||
xfree(sig);
|
||||
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (sigp != NULL)
|
||||
*sigp = ret;
|
||||
debug2("ssh_rsa_sign: done");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_rsa_verify(
|
||||
Key *key,
|
||||
u_char *signature, int signaturelen,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
Buffer b;
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
char *ktype;
|
||||
u_char *sigblob, *digest;
|
||||
u_int len, dlen;
|
||||
int rlen;
|
||||
int ret;
|
||||
|
||||
if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
|
||||
error("ssh_rsa_verify: no RSA key");
|
||||
return -1;
|
||||
}
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, (char *) signature, signaturelen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
if (strcmp("ssh-rsa", ktype) != 0) {
|
||||
error("ssh_rsa_verify: cannot handle type %s", ktype);
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
return -1;
|
||||
}
|
||||
xfree(ktype);
|
||||
sigblob = (u_char *)buffer_get_string(&b, &len);
|
||||
rlen = buffer_len(&b);
|
||||
buffer_free(&b);
|
||||
if(rlen != 0) {
|
||||
error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dlen = evp_md->md_size;
|
||||
digest = xmalloc(dlen);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
ret = RSA_verify(NID_sha1, digest, dlen, sigblob, len, key->rsa);
|
||||
memset(digest, 'd', dlen);
|
||||
xfree(digest);
|
||||
memset(sigblob, 's', len);
|
||||
xfree(sigblob);
|
||||
if (ret == 0) {
|
||||
int ecode = ERR_get_error();
|
||||
error("ssh_rsa_verify: RSA_verify failed: %s", ERR_error_string(ecode, NULL));
|
||||
}
|
||||
debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
|
||||
return ret;
|
||||
}
|
39
crypto/dist/ssh/ssh-rsa.h
vendored
Normal file
39
crypto/dist/ssh/ssh-rsa.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2000 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.
|
||||
*/
|
||||
#ifndef SSH_RSA_H
|
||||
#define SSH_RSA_H
|
||||
|
||||
int
|
||||
ssh_rsa_sign(
|
||||
Key *key,
|
||||
u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen);
|
||||
|
||||
int
|
||||
ssh_rsa_verify(
|
||||
Key *key,
|
||||
u_char *signature, int signaturelen,
|
||||
u_char *data, int datalen);
|
||||
|
||||
#endif
|
10
crypto/dist/ssh/ssh2.h
vendored
10
crypto/dist/ssh/ssh2.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ssh2.h,v 1.1.1.1 2000/09/28 22:10:34 thorpej Exp $ */
|
||||
/* $NetBSD: ssh2.h,v 1.1.1.2 2001/01/14 04:50:52 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -55,7 +55,7 @@
|
||||
* 192-255 Local extensions
|
||||
*/
|
||||
|
||||
/* from OpenBSD: ssh2.h,v 1.4 2000/09/07 20:27:54 deraadt Exp */
|
||||
/* from OpenBSD: ssh2.h,v 1.5 2000/10/11 04:02:17 provos Exp */
|
||||
|
||||
/* transport layer: generic */
|
||||
|
||||
@ -76,6 +76,12 @@
|
||||
#define SSH2_MSG_KEXDH_INIT 30
|
||||
#define SSH2_MSG_KEXDH_REPLY 31
|
||||
|
||||
/* dh-group-exchange */
|
||||
#define SSH2_MSG_KEX_DH_GEX_REQUEST 30
|
||||
#define SSH2_MSG_KEX_DH_GEX_GROUP 31
|
||||
#define SSH2_MSG_KEX_DH_GEX_INIT 32
|
||||
#define SSH2_MSG_KEX_DH_GEX_REPLY 33
|
||||
|
||||
/* user authentication: generic */
|
||||
|
||||
#define SSH2_MSG_USERAUTH_REQUEST 50
|
||||
|
138
crypto/dist/ssh/sshconnect.c
vendored
138
crypto/dist/ssh/sshconnect.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sshconnect.c,v 1.1.1.1 2000/09/28 22:10:36 thorpej Exp $ */
|
||||
/* $NetBSD: sshconnect.c,v 1.1.1.2 2001/01/14 04:50:53 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -14,11 +14,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: sshconnect.c,v 1.79 2000/09/17 15:52:51 markus Exp */
|
||||
/* from OpenBSD: sshconnect.c,v 1.89 2001/01/04 22:41:03 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sshconnect.c,v 1.1.1.1 2000/09/28 22:10:36 thorpej Exp $");
|
||||
__RCSID("$NetBSD: sshconnect.c,v 1.1.1.2 2001/01/14 04:50:53 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -124,8 +124,8 @@ ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid,
|
||||
|
||||
/* Execute the proxy command. Note that we gave up any
|
||||
extra privileges above. */
|
||||
execv(_PATH_BSHELL, argv);
|
||||
perror(_PATH_BSHELL);
|
||||
execv(argv[0], argv);
|
||||
perror(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
/* Parent. */
|
||||
@ -252,7 +252,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
|
||||
|
||||
/* Create a socket for connecting. */
|
||||
sock = ssh_create_socket(original_real_uid,
|
||||
!anonymous && geteuid() == 0 && port < IPPORT_RESERVED,
|
||||
!anonymous && geteuid() == 0,
|
||||
ai->ai_family);
|
||||
if (sock < 0)
|
||||
continue;
|
||||
@ -321,6 +321,7 @@ ssh_exchange_identification(void)
|
||||
int remote_major, remote_minor, i, mismatch;
|
||||
int connection_in = packet_get_connection_in();
|
||||
int connection_out = packet_get_connection_out();
|
||||
int minor1 = PROTOCOL_MINOR_1;
|
||||
|
||||
/* Read other side\'s version identification. */
|
||||
for (;;) {
|
||||
@ -374,9 +375,10 @@ ssh_exchange_identification(void)
|
||||
}
|
||||
if (remote_minor < 3) {
|
||||
fatal("Remote machine has too old SSH software version.");
|
||||
} else if (remote_minor == 3) {
|
||||
} else if (remote_minor == 3 || remote_minor == 4) {
|
||||
/* We speak 1.3, too. */
|
||||
enable_compat13();
|
||||
minor1 = 3;
|
||||
if (options.forward_agent) {
|
||||
log("Agent forwarding disabled for protocol 1.3");
|
||||
options.forward_agent = 0;
|
||||
@ -402,7 +404,7 @@ ssh_exchange_identification(void)
|
||||
/* Send our own protocol version identification. */
|
||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
|
||||
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
||||
compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1,
|
||||
compat20 ? PROTOCOL_MINOR_2 : minor1,
|
||||
SSH_VERSION);
|
||||
if (atomic_write(connection_out, buf, strlen(buf)) != strlen(buf))
|
||||
fatal("write: %.100s", strerror(errno));
|
||||
@ -419,7 +421,7 @@ read_yes_or_no(const char *prompt, int defval)
|
||||
FILE *f;
|
||||
int retval = -1;
|
||||
|
||||
if (isatty(0))
|
||||
if (isatty(STDIN_FILENO))
|
||||
f = stdin;
|
||||
else
|
||||
f = fopen(_PATH_TTY, "rw");
|
||||
@ -473,6 +475,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
HostStatus ip_status;
|
||||
int local = 0, host_ip_differ = 0;
|
||||
char ntop[NI_MAXHOST];
|
||||
int host_line, ip_line;
|
||||
const char *host_file = NULL, *ip_file = NULL;
|
||||
|
||||
/*
|
||||
* Force accepting of the host key for loopback/localhost. The
|
||||
@ -494,23 +498,40 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
local = 0;
|
||||
break;
|
||||
}
|
||||
if (local) {
|
||||
debug("Forcing accepting of host key for loopback/localhost.");
|
||||
if (local && options.host_key_alias == NULL) {
|
||||
debug("Forcing accepting of host key for "
|
||||
"loopback/localhost.");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn off check_host_ip for proxy connects, since
|
||||
* we don't have the remote ip-address
|
||||
* We don't have the remote ip-address for connections
|
||||
* using a proxy command
|
||||
*/
|
||||
if (options.proxy_command != NULL && options.check_host_ip)
|
||||
options.check_host_ip = 0;
|
||||
|
||||
if (options.check_host_ip) {
|
||||
if (options.proxy_command == NULL) {
|
||||
if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop),
|
||||
NULL, 0, NI_NUMERICHOST) != 0)
|
||||
fatal("check_host_key: getnameinfo failed");
|
||||
ip = xstrdup(ntop);
|
||||
} else {
|
||||
ip = xstrdup("<no hostip for proxy command>");
|
||||
}
|
||||
/*
|
||||
* Turn off check_host_ip if the connection is to localhost, via proxy
|
||||
* command or if we don't have a hostname to compare with
|
||||
*/
|
||||
if (options.check_host_ip &&
|
||||
(local || strcmp(host, ip) == 0 || options.proxy_command != NULL))
|
||||
options.check_host_ip = 0;
|
||||
|
||||
/*
|
||||
* Allow the user to record the key under a different name. This is
|
||||
* useful for ssh tunneling over forwarded connections or if you run
|
||||
* multiple sshd's on different ports on the same machine.
|
||||
*/
|
||||
if (options.host_key_alias != NULL) {
|
||||
host = options.host_key_alias;
|
||||
debug("using hostkeyalias: %s", host);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -523,19 +544,25 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
* Check if the host key is present in the user\'s list of known
|
||||
* hosts or in the systemwide list.
|
||||
*/
|
||||
host_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key);
|
||||
if (host_status == HOST_NEW)
|
||||
host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key);
|
||||
host_file = user_hostfile;
|
||||
host_status = check_host_in_hostfile(host_file, host, host_key, file_key, &host_line);
|
||||
if (host_status == HOST_NEW) {
|
||||
host_file = system_hostfile;
|
||||
host_status = check_host_in_hostfile(host_file, host, host_key, file_key, &host_line);
|
||||
}
|
||||
/*
|
||||
* Also perform check for the ip address, skip the check if we are
|
||||
* localhost or the hostname was an ip address to begin with
|
||||
*/
|
||||
if (options.check_host_ip && !local && strcmp(host, ip)) {
|
||||
if (options.check_host_ip) {
|
||||
Key *ip_key = key_new(host_key->type);
|
||||
ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key);
|
||||
|
||||
if (ip_status == HOST_NEW)
|
||||
ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key);
|
||||
ip_file = user_hostfile;
|
||||
ip_status = check_host_in_hostfile(ip_file, ip, host_key, ip_key, &ip_line);
|
||||
if (ip_status == HOST_NEW) {
|
||||
ip_file = system_hostfile;
|
||||
ip_status = check_host_in_hostfile(ip_file, ip, host_key, ip_key, &ip_line);
|
||||
}
|
||||
if (host_status == HOST_CHANGED &&
|
||||
(ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
|
||||
host_ip_differ = 1;
|
||||
@ -551,17 +578,14 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
/* The host is known and the key matches. */
|
||||
debug("Host '%.200s' is known and matches the %s host key.",
|
||||
host, type);
|
||||
if (options.check_host_ip) {
|
||||
if (ip_status == HOST_NEW) {
|
||||
if (!add_host_to_hostfile(user_hostfile, ip, host_key))
|
||||
log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).",
|
||||
type, ip, user_hostfile);
|
||||
else
|
||||
log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.",
|
||||
type, ip);
|
||||
} else if (ip_status != HOST_OK)
|
||||
log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'",
|
||||
type, host, ip);
|
||||
debug("Found key in %s:%d", host_file, host_line);
|
||||
if (options.check_host_ip && ip_status == HOST_NEW) {
|
||||
if (!add_host_to_hostfile(user_hostfile, ip, host_key))
|
||||
log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).",
|
||||
type, ip, user_hostfile);
|
||||
else
|
||||
log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.",
|
||||
type, ip);
|
||||
}
|
||||
break;
|
||||
case HOST_NEW:
|
||||
@ -573,16 +597,15 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
} else if (options.strict_host_key_checking == 2) {
|
||||
/* The default */
|
||||
char prompt[1024];
|
||||
char *fp = key_fingerprint(host_key);
|
||||
snprintf(prompt, sizeof(prompt),
|
||||
"The authenticity of host '%.200s' can't be established.\n"
|
||||
"The authenticity of host '%.200s (%s)' can't be established.\n"
|
||||
"%s key fingerprint is %s.\n"
|
||||
"Are you sure you want to continue connecting (yes/no)? ",
|
||||
host, type, fp);
|
||||
host, ip, type, key_fingerprint(host_key));
|
||||
if (!read_yes_or_no(prompt, -1))
|
||||
fatal("Aborted by user!\n");
|
||||
}
|
||||
if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) {
|
||||
if (options.check_host_ip && ip_status == HOST_NEW) {
|
||||
snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
|
||||
hostp = hostline;
|
||||
} else
|
||||
@ -612,7 +635,9 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
error("and the key for the according IP address %s", ip);
|
||||
error("%s. This could either mean that", msg);
|
||||
error("DNS SPOOFING is happening or the IP address for the host");
|
||||
error("and its host key have changed at the same time");
|
||||
error("and its host key have changed at the same time.");
|
||||
if (ip_status != HOST_NEW)
|
||||
error("Offending key for IP in %s:%d", ip_file, ip_line);
|
||||
}
|
||||
/* The host key has changed. */
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
@ -621,9 +646,12 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
|
||||
error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
|
||||
error("It is also possible that the %s host key has just been changed.", type);
|
||||
error("The fingerprint for the %s key sent by the remote host is\n%s.",
|
||||
type, key_fingerprint(host_key));
|
||||
error("Please contact your system administrator.");
|
||||
error("Add correct host key in %.100s to get rid of this message.",
|
||||
user_hostfile);
|
||||
user_hostfile);
|
||||
error("Offending key in %s:%d", host_file, host_line);
|
||||
|
||||
/*
|
||||
* If strict host key checking is in use, the user will have
|
||||
@ -645,6 +673,14 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
error("Agent forwarding is disabled to avoid trojan horses.");
|
||||
options.forward_agent = 0;
|
||||
}
|
||||
if (options.forward_x11) {
|
||||
error("X11 forwarding is disabled to avoid trojan horses.");
|
||||
options.forward_x11 = 0;
|
||||
}
|
||||
if (options.num_local_forwards > 0 || options.num_remote_forwards > 0) {
|
||||
error("Port forwarding is disabled to avoid trojan horses.");
|
||||
options.num_local_forwards = options.num_remote_forwards = 0;
|
||||
}
|
||||
/*
|
||||
* XXX Should permit the user to change to use the new id.
|
||||
* This could be done by converting the host key to an
|
||||
@ -654,8 +690,24 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (options.check_host_ip)
|
||||
xfree(ip);
|
||||
|
||||
if (options.check_host_ip && host_status != HOST_CHANGED &&
|
||||
ip_status == HOST_CHANGED) {
|
||||
log("Warning: the %s host key for '%.200s' "
|
||||
"differs from the key for the IP address '%.30s'",
|
||||
type, host, ip);
|
||||
if (host_status == HOST_OK)
|
||||
log("Matching host key in %s:%d", host_file, host_line);
|
||||
log("Offending key for IP in %s:%d", ip_file, ip_line);
|
||||
if (options.strict_host_key_checking == 1) {
|
||||
fatal("Exiting, you have requested strict checking.");
|
||||
} else if (options.strict_host_key_checking == 2) {
|
||||
if (!read_yes_or_no("Continue?", -1))
|
||||
fatal("Aborted by user!\n");
|
||||
}
|
||||
}
|
||||
|
||||
xfree(ip);
|
||||
}
|
||||
|
||||
/*
|
||||
|
121
crypto/dist/ssh/sshconnect1.c
vendored
121
crypto/dist/ssh/sshconnect1.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sshconnect1.c,v 1.1.1.1 2000/09/28 22:10:37 thorpej Exp $ */
|
||||
/* $NetBSD: sshconnect1.c,v 1.1.1.2 2001/01/14 04:50:55 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -14,11 +14,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: sshconnect1.c,v 1.6 2000/09/07 20:27:54 deraadt Exp */
|
||||
/* from OpenBSD: sshconnect1.c,v 1.13 2000/12/19 23:17:58 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sshconnect1.c,v 1.1.1.1 2000/09/28 22:10:37 thorpej Exp $");
|
||||
__RCSID("$NetBSD: sshconnect1.c,v 1.1.1.2 2001/01/14 04:50:55 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -34,7 +34,6 @@ __RCSID("$NetBSD: sshconnect1.c,v 1.1.1.1 2000/09/28 22:10:37 thorpej Exp $");
|
||||
#include "ssh.h"
|
||||
#include "buffer.h"
|
||||
#include "packet.h"
|
||||
#include "cipher.h"
|
||||
#include "mpaux.h"
|
||||
#include "uidswap.h"
|
||||
#include "readconf.h"
|
||||
@ -44,8 +43,8 @@ __RCSID("$NetBSD: sshconnect1.c,v 1.1.1.1 2000/09/28 22:10:37 thorpej Exp $");
|
||||
#include "authfile.h"
|
||||
|
||||
/* Session id for the current session. */
|
||||
unsigned char session_id[16];
|
||||
unsigned int supported_authentications = 0;
|
||||
u_char session_id[16];
|
||||
u_int supported_authentications = 0;
|
||||
|
||||
extern Options options;
|
||||
extern char *__progname;
|
||||
@ -60,8 +59,8 @@ try_agent_authentication(void)
|
||||
int type;
|
||||
char *comment;
|
||||
AuthenticationConnection *auth;
|
||||
unsigned char response[16];
|
||||
unsigned int i;
|
||||
u_char response[16];
|
||||
u_int i;
|
||||
int plen, clen;
|
||||
Key *key;
|
||||
BIGNUM *challenge;
|
||||
@ -72,7 +71,7 @@ try_agent_authentication(void)
|
||||
return 0;
|
||||
|
||||
challenge = BN_new();
|
||||
key = key_new(KEY_RSA);
|
||||
key = key_new(KEY_RSA1);
|
||||
|
||||
/* Loop through identities served by the agent. */
|
||||
for (key = ssh_get_first_identity(auth, &comment, 1);
|
||||
@ -156,7 +155,7 @@ try_agent_authentication(void)
|
||||
static void
|
||||
respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
|
||||
{
|
||||
unsigned char buf[32], response[16];
|
||||
u_char buf[32], response[16];
|
||||
MD5_CTX md;
|
||||
int i, len;
|
||||
|
||||
@ -206,7 +205,7 @@ try_rsa_authentication(const char *authfile)
|
||||
int plen, clen;
|
||||
|
||||
/* Try to load identification for the authentication key. */
|
||||
public = key_new(KEY_RSA);
|
||||
public = key_new(KEY_RSA1);
|
||||
if (!load_public_key(authfile, public, &comment)) {
|
||||
key_free(public);
|
||||
/* Could not load it. Fail. */
|
||||
@ -247,7 +246,7 @@ try_rsa_authentication(const char *authfile)
|
||||
|
||||
debug("Received RSA challenge from server.");
|
||||
|
||||
private = key_new(KEY_RSA);
|
||||
private = key_new(KEY_RSA1);
|
||||
/*
|
||||
* Load the private key. Try first with empty passphrase; if it
|
||||
* fails, ask for a passphrase.
|
||||
@ -451,7 +450,7 @@ try_kerberos_authentication(void)
|
||||
debug("Kerberos V4 authentication accepted.");
|
||||
|
||||
/* Get server's response. */
|
||||
reply = packet_get_string((unsigned int *) &auth.length);
|
||||
reply = packet_get_string((u_int *) &auth.length);
|
||||
memcpy(auth.dat, reply, auth.length);
|
||||
xfree(reply);
|
||||
|
||||
@ -516,7 +515,7 @@ send_kerberos_tgt(void)
|
||||
debug("Kerberos V4 ticket expired: %s", TKT_FILE);
|
||||
return 0;
|
||||
}
|
||||
creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer);
|
||||
creds_to_radix(creds, (u_char *)buffer, sizeof buffer);
|
||||
xfree(creds);
|
||||
|
||||
packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
|
||||
@ -555,10 +554,10 @@ send_afs_tokens(void)
|
||||
p = buf;
|
||||
|
||||
/* Get secret token. */
|
||||
memcpy(&creds.ticket_st.length, p, sizeof(unsigned int));
|
||||
memcpy(&creds.ticket_st.length, p, sizeof(u_int));
|
||||
if (creds.ticket_st.length > MAX_KTXT_LEN)
|
||||
break;
|
||||
p += sizeof(unsigned int);
|
||||
p += sizeof(u_int);
|
||||
memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
|
||||
p += creds.ticket_st.length;
|
||||
|
||||
@ -584,7 +583,7 @@ send_afs_tokens(void)
|
||||
creds.pinst[0] = '\0';
|
||||
|
||||
/* Encode token, ship it off. */
|
||||
if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0)
|
||||
if (creds_to_radix(&creds, (u_char*) buffer, sizeof buffer) <= 0)
|
||||
break;
|
||||
packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
|
||||
packet_put_string(buffer, strlen(buffer));
|
||||
@ -613,38 +612,42 @@ try_skey_authentication(void)
|
||||
{
|
||||
int type, i;
|
||||
int payload_len;
|
||||
unsigned int clen;
|
||||
u_int clen;
|
||||
char prompt[1024];
|
||||
char *challenge, *response;
|
||||
|
||||
debug("Doing skey authentication.");
|
||||
|
||||
/* request a challenge */
|
||||
packet_start(SSH_CMSG_AUTH_TIS);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
type = packet_read(&payload_len);
|
||||
if (type != SSH_SMSG_FAILURE &&
|
||||
type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
|
||||
packet_disconnect("Protocol error: got %d in response "
|
||||
"to skey-auth", type);
|
||||
}
|
||||
if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
|
||||
debug("No challenge for skey authentication.");
|
||||
return 0;
|
||||
}
|
||||
challenge = packet_get_string(&clen);
|
||||
packet_integrity_check(payload_len, (4 + clen), type);
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! "
|
||||
"Reponse will be transmitted in clear text.");
|
||||
fprintf(stderr, "%s\n", challenge);
|
||||
xfree(challenge);
|
||||
fflush(stderr);
|
||||
for (i = 0; i < options.number_of_password_prompts; i++) {
|
||||
/* request a challenge */
|
||||
packet_start(SSH_CMSG_AUTH_TIS);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
type = packet_read(&payload_len);
|
||||
if (type != SSH_SMSG_FAILURE &&
|
||||
type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
|
||||
packet_disconnect("Protocol error: got %d in response "
|
||||
"to skey-auth", type);
|
||||
}
|
||||
if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
|
||||
debug("No challenge for skey authentication.");
|
||||
return 0;
|
||||
}
|
||||
challenge = packet_get_string(&clen);
|
||||
packet_integrity_check(payload_len, (4 + clen), type);
|
||||
snprintf(prompt, sizeof prompt, "%s\nResponse: ", challenge);
|
||||
xfree(challenge);
|
||||
if (i != 0)
|
||||
error("Permission denied, please try again.");
|
||||
response = read_passphrase("Response: ", 0);
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! "
|
||||
"Reponse will be transmitted in clear text.");
|
||||
response = read_passphrase(prompt, 0);
|
||||
if (strcmp(response, "") == 0) {
|
||||
xfree(response);
|
||||
break;
|
||||
}
|
||||
packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
|
||||
packet_put_string(response, strlen(response));
|
||||
memset(response, 0, strlen(response));
|
||||
@ -656,7 +659,7 @@ try_skey_authentication(void)
|
||||
return 1;
|
||||
if (type != SSH_SMSG_FAILURE)
|
||||
packet_disconnect("Protocol error: got %d in response "
|
||||
"to skey-auth-reponse", type);
|
||||
"to skey-auth-reponse", type);
|
||||
}
|
||||
/* failure */
|
||||
return 0;
|
||||
@ -708,10 +711,10 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||
Key k;
|
||||
int bits, rbits;
|
||||
int ssh_cipher_default = SSH_CIPHER_3DES;
|
||||
unsigned char session_key[SSH_SESSION_KEY_LENGTH];
|
||||
unsigned char cookie[8];
|
||||
unsigned int supported_ciphers;
|
||||
unsigned int server_flags, client_flags;
|
||||
u_char session_key[SSH_SESSION_KEY_LENGTH];
|
||||
u_char cookie[8];
|
||||
u_int supported_ciphers;
|
||||
u_int server_flags, client_flags;
|
||||
int payload_len, clen, sum_len = 0;
|
||||
u_int32_t rand = 0;
|
||||
|
||||
@ -770,7 +773,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||
packet_integrity_check(payload_len,
|
||||
8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
|
||||
SSH_SMSG_PUBLIC_KEY);
|
||||
k.type = KEY_RSA;
|
||||
k.type = KEY_RSA1;
|
||||
k.rsa = host_key;
|
||||
check_host_key(host, hostaddr, &k,
|
||||
options.user_hostfile, options.system_hostfile);
|
||||
@ -843,19 +846,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||
RSA_free(public_key);
|
||||
RSA_free(host_key);
|
||||
|
||||
if (options.cipher == SSH_CIPHER_ILLEGAL) {
|
||||
log("No valid SSH1 cipher, using %.100s instead.",
|
||||
cipher_name(SSH_FALLBACK_CIPHER));
|
||||
options.cipher = SSH_FALLBACK_CIPHER;
|
||||
} else if (options.cipher == SSH_CIPHER_NOT_SET) {
|
||||
if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default))
|
||||
if (options.cipher == SSH_CIPHER_NOT_SET) {
|
||||
if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
|
||||
options.cipher = ssh_cipher_default;
|
||||
else {
|
||||
debug("Cipher %s not supported, using %.100s instead.",
|
||||
cipher_name(ssh_cipher_default),
|
||||
cipher_name(SSH_FALLBACK_CIPHER));
|
||||
options.cipher = SSH_FALLBACK_CIPHER;
|
||||
}
|
||||
} else if (options.cipher == SSH_CIPHER_ILLEGAL ||
|
||||
!(cipher_mask_ssh1(1) & (1 << options.cipher))) {
|
||||
log("No valid SSH1 cipher, using %.100s instead.",
|
||||
cipher_name(ssh_cipher_default));
|
||||
options.cipher = ssh_cipher_default;
|
||||
}
|
||||
/* Check that the selected cipher is supported. */
|
||||
if (!(supported_ciphers & (1 << options.cipher)))
|
||||
@ -1013,7 +1011,8 @@ ssh_userauth(
|
||||
|
||||
/* Try RSA authentication for each identity. */
|
||||
for (i = 0; i < options.num_identity_files; i++)
|
||||
if (try_rsa_authentication(options.identity_files[i]))
|
||||
if (options.identity_files_type[i] == KEY_RSA1 &&
|
||||
try_rsa_authentication(options.identity_files[i]))
|
||||
return;
|
||||
}
|
||||
/* Try skey authentication if the server supports it. */
|
||||
|
614
crypto/dist/ssh/sshconnect2.c
vendored
614
crypto/dist/ssh/sshconnect2.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sshconnect2.c,v 1.1.1.1 2000/09/28 22:10:38 thorpej Exp $ */
|
||||
/* $NetBSD: sshconnect2.c,v 1.1.1.2 2001/01/14 04:50:57 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: sshconnect2.c,v 1.21 2000/09/27 21:41:34 markus Exp */
|
||||
/* from OpenBSD: sshconnect2.c,v 1.35 2001/01/04 22:21:26 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sshconnect2.c,v 1.1.1.1 2000/09/28 22:10:38 thorpej Exp $");
|
||||
__RCSID("$NetBSD: sshconnect2.c,v 1.1.1.2 2001/01/14 04:50:57 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -45,7 +45,6 @@ __RCSID("$NetBSD: sshconnect2.c,v 1.1.1.1 2000/09/28 22:10:38 thorpej Exp $");
|
||||
#include "rsa.h"
|
||||
#include "buffer.h"
|
||||
#include "packet.h"
|
||||
#include "cipher.h"
|
||||
#include "uidswap.h"
|
||||
#include "compat.h"
|
||||
#include "readconf.h"
|
||||
@ -54,12 +53,15 @@ __RCSID("$NetBSD: sshconnect2.c,v 1.1.1.1 2000/09/28 22:10:38 thorpej Exp $");
|
||||
#include "kex.h"
|
||||
#include "myproposal.h"
|
||||
#include "key.h"
|
||||
#include "dsa.h"
|
||||
#include "sshconnect.h"
|
||||
#include "authfile.h"
|
||||
#include "cli.h"
|
||||
#include "dispatch.h"
|
||||
#include "authfd.h"
|
||||
|
||||
void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
|
||||
void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
|
||||
|
||||
/* import */
|
||||
extern char *client_version_string;
|
||||
extern char *server_version_string;
|
||||
@ -69,32 +71,110 @@ extern Options options;
|
||||
* SSH2 key exchange
|
||||
*/
|
||||
|
||||
unsigned char *session_id2 = NULL;
|
||||
u_char *session_id2 = NULL;
|
||||
int session_id2_len = 0;
|
||||
|
||||
static void
|
||||
ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||
Buffer *client_kexinit, Buffer *server_kexinit)
|
||||
void
|
||||
ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
{
|
||||
int i, plen;
|
||||
Kex *kex;
|
||||
Buffer *client_kexinit, *server_kexinit;
|
||||
char *sprop[PROPOSAL_MAX];
|
||||
|
||||
if (options.ciphers == (char *)-1) {
|
||||
log("No valid ciphers for protocol version 2 given, using defaults.");
|
||||
options.ciphers = NULL;
|
||||
}
|
||||
if (options.ciphers != NULL) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
|
||||
}
|
||||
if (options.compression) {
|
||||
myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
|
||||
myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
|
||||
} else {
|
||||
myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
|
||||
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
|
||||
}
|
||||
|
||||
/* buffers with raw kexinit messages */
|
||||
server_kexinit = xmalloc(sizeof(*server_kexinit));
|
||||
buffer_init(server_kexinit);
|
||||
client_kexinit = kex_init(myproposal);
|
||||
|
||||
/* algorithm negotiation */
|
||||
kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
|
||||
kex = kex_choose_conf(myproposal, sprop, 0);
|
||||
for (i = 0; i < PROPOSAL_MAX; i++)
|
||||
xfree(sprop[i]);
|
||||
|
||||
/* server authentication and session key agreement */
|
||||
switch(kex->kex_type) {
|
||||
case DH_GRP1_SHA1:
|
||||
ssh_dh1_client(kex, host, hostaddr,
|
||||
client_kexinit, server_kexinit);
|
||||
break;
|
||||
case DH_GEX_SHA1:
|
||||
ssh_dhgex_client(kex, host, hostaddr, client_kexinit,
|
||||
server_kexinit);
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported key exchange %d", kex->kex_type);
|
||||
}
|
||||
|
||||
buffer_free(client_kexinit);
|
||||
buffer_free(server_kexinit);
|
||||
xfree(client_kexinit);
|
||||
xfree(server_kexinit);
|
||||
|
||||
debug("Wait SSH2_MSG_NEWKEYS.");
|
||||
packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
|
||||
packet_done();
|
||||
debug("GOT SSH2_MSG_NEWKEYS.");
|
||||
|
||||
debug("send SSH2_MSG_NEWKEYS.");
|
||||
packet_start(SSH2_MSG_NEWKEYS);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
debug("done: send SSH2_MSG_NEWKEYS.");
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
/* send 1st encrypted/maced/compressed message */
|
||||
packet_start(SSH2_MSG_IGNORE);
|
||||
packet_put_cstring("markus");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
#endif
|
||||
debug("done: KEX2.");
|
||||
}
|
||||
|
||||
/* diffie-hellman-group1-sha1 */
|
||||
|
||||
void
|
||||
ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||
Buffer *client_kexinit, Buffer *server_kexinit)
|
||||
{
|
||||
#ifdef DEBUG_KEXDH
|
||||
int i;
|
||||
#endif
|
||||
int plen, dlen;
|
||||
unsigned int klen, kout;
|
||||
u_int klen, kout;
|
||||
char *signature = NULL;
|
||||
unsigned int slen;
|
||||
u_int slen;
|
||||
char *server_host_key_blob = NULL;
|
||||
Key *server_host_key;
|
||||
unsigned int sbloblen;
|
||||
u_int sbloblen;
|
||||
DH *dh;
|
||||
BIGNUM *dh_server_pub = 0;
|
||||
BIGNUM *shared_secret = 0;
|
||||
unsigned char *kbuf;
|
||||
unsigned char *hash;
|
||||
u_char *kbuf;
|
||||
u_char *hash;
|
||||
|
||||
debug("Sending SSH2_MSG_KEXDH_INIT.");
|
||||
/* generate and send 'e', client DH public key */
|
||||
dh = dh_new_group1();
|
||||
dh_gen_key(dh);
|
||||
packet_start(SSH2_MSG_KEXDH_INIT);
|
||||
packet_put_bignum2(dh->pub_key);
|
||||
packet_send();
|
||||
@ -119,12 +199,12 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||
|
||||
/* key, cert */
|
||||
server_host_key_blob = packet_get_string(&sbloblen);
|
||||
server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
|
||||
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
|
||||
if (server_host_key == NULL)
|
||||
fatal("cannot decode server_host_key_blob");
|
||||
|
||||
check_host_key(host, hostaddr, server_host_key,
|
||||
options.user_hostfile2, options.system_hostfile2);
|
||||
options.user_hostfile2, options.system_hostfile2);
|
||||
|
||||
/* DH paramter f, server public DH key */
|
||||
dh_server_pub = BN_new();
|
||||
@ -181,8 +261,8 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||
fprintf(stderr, "%02x", (hash[i])&0xff);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
|
||||
fatal("dsa_verify failed for server_host_key");
|
||||
if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
|
||||
fatal("key_verify failed for server_host_key");
|
||||
key_free(server_host_key);
|
||||
|
||||
kex_derive_keys(kex, hash, shared_secret);
|
||||
@ -194,72 +274,177 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||
memcpy(session_id2, hash, session_id2_len);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
/* diffie-hellman-group-exchange-sha1 */
|
||||
|
||||
/*
|
||||
* Estimates the group order for a Diffie-Hellman group that has an
|
||||
* attack complexity approximately the same as O(2**bits). Estimate
|
||||
* with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
|
||||
*/
|
||||
|
||||
static int
|
||||
dh_estimate(int bits)
|
||||
{
|
||||
int i, plen;
|
||||
Kex *kex;
|
||||
Buffer *client_kexinit, *server_kexinit;
|
||||
char *sprop[PROPOSAL_MAX];
|
||||
|
||||
if (bits < 64)
|
||||
return (512); /* O(2**63) */
|
||||
if (bits < 128)
|
||||
return (1024); /* O(2**86) */
|
||||
if (bits < 192)
|
||||
return (2048); /* O(2**116) */
|
||||
return (4096); /* O(2**156) */
|
||||
}
|
||||
|
||||
if (options.ciphers != NULL) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
|
||||
} else if (options.cipher == SSH_CIPHER_3DES) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] =
|
||||
(char *) cipher_name(SSH_CIPHER_3DES_CBC);
|
||||
} else if (options.cipher == SSH_CIPHER_BLOWFISH) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] =
|
||||
(char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC);
|
||||
}
|
||||
if (options.compression) {
|
||||
myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
|
||||
myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
|
||||
} else {
|
||||
myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
|
||||
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
|
||||
}
|
||||
void
|
||||
ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||
Buffer *client_kexinit, Buffer *server_kexinit)
|
||||
{
|
||||
#ifdef DEBUG_KEXDH
|
||||
int i;
|
||||
#endif
|
||||
int plen, dlen;
|
||||
u_int klen, kout;
|
||||
char *signature = NULL;
|
||||
u_int slen, nbits;
|
||||
char *server_host_key_blob = NULL;
|
||||
Key *server_host_key;
|
||||
u_int sbloblen;
|
||||
DH *dh;
|
||||
BIGNUM *dh_server_pub = 0;
|
||||
BIGNUM *shared_secret = 0;
|
||||
BIGNUM *p = 0, *g = 0;
|
||||
u_char *kbuf;
|
||||
u_char *hash;
|
||||
|
||||
/* buffers with raw kexinit messages */
|
||||
server_kexinit = xmalloc(sizeof(*server_kexinit));
|
||||
buffer_init(server_kexinit);
|
||||
client_kexinit = kex_init(myproposal);
|
||||
nbits = dh_estimate(kex->enc[MODE_OUT].cipher->key_len * 8);
|
||||
|
||||
/* algorithm negotiation */
|
||||
kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
|
||||
kex = kex_choose_conf(myproposal, sprop, 0);
|
||||
for (i = 0; i < PROPOSAL_MAX; i++)
|
||||
xfree(sprop[i]);
|
||||
|
||||
/* server authentication and session key agreement */
|
||||
ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit);
|
||||
|
||||
buffer_free(client_kexinit);
|
||||
buffer_free(server_kexinit);
|
||||
xfree(client_kexinit);
|
||||
xfree(server_kexinit);
|
||||
|
||||
debug("Wait SSH2_MSG_NEWKEYS.");
|
||||
packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
|
||||
packet_done();
|
||||
debug("GOT SSH2_MSG_NEWKEYS.");
|
||||
|
||||
debug("send SSH2_MSG_NEWKEYS.");
|
||||
packet_start(SSH2_MSG_NEWKEYS);
|
||||
debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
|
||||
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
|
||||
packet_put_int(nbits);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
debug("done: send SSH2_MSG_NEWKEYS.");
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
/* send 1st encrypted/maced/compressed message */
|
||||
packet_start(SSH2_MSG_IGNORE);
|
||||
packet_put_cstring("markus");
|
||||
fprintf(stderr, "\nnbits = %d", nbits);
|
||||
#endif
|
||||
|
||||
debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
|
||||
|
||||
packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
|
||||
|
||||
debug("Got SSH2_MSG_KEX_DH_GEX_GROUP.");
|
||||
|
||||
if ((p = BN_new()) == NULL)
|
||||
fatal("BN_new");
|
||||
packet_get_bignum2(p, &dlen);
|
||||
if ((g = BN_new()) == NULL)
|
||||
fatal("BN_new");
|
||||
packet_get_bignum2(g, &dlen);
|
||||
if ((dh = dh_new_group(g, p)) == NULL)
|
||||
fatal("dh_new_group");
|
||||
|
||||
dh_gen_key(dh);
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "\np= ");
|
||||
BN_print_fp(stderr, dh->p);
|
||||
fprintf(stderr, "\ng= ");
|
||||
BN_print_fp(stderr, dh->g);
|
||||
fprintf(stderr, "\npub= ");
|
||||
BN_print_fp(stderr, dh->pub_key);
|
||||
fprintf(stderr, "\n");
|
||||
DHparams_print_fp(stderr, dh);
|
||||
#endif
|
||||
|
||||
debug("Sending SSH2_MSG_KEX_DH_GEX_INIT.");
|
||||
/* generate and send 'e', client DH public key */
|
||||
packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
|
||||
packet_put_bignum2(dh->pub_key);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
debug("Wait SSH2_MSG_KEX_DH_GEX_REPLY.");
|
||||
|
||||
packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
|
||||
|
||||
debug("Got 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");
|
||||
|
||||
check_host_key(host, hostaddr, server_host_key,
|
||||
options.user_hostfile2, options.system_hostfile2);
|
||||
|
||||
/* DH paramter f, server public DH key */
|
||||
dh_server_pub = BN_new();
|
||||
if (dh_server_pub == NULL)
|
||||
fatal("dh_server_pub == NULL");
|
||||
packet_get_bignum2(dh_server_pub, &dlen);
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "\ndh_server_pub= ");
|
||||
BN_print_fp(stderr, dh_server_pub);
|
||||
fprintf(stderr, "\n");
|
||||
debug("bits %d", BN_num_bits(dh_server_pub));
|
||||
#endif
|
||||
debug("done: KEX2.");
|
||||
|
||||
/* signed H */
|
||||
signature = packet_get_string(&slen);
|
||||
packet_done();
|
||||
|
||||
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
|
||||
debug("shared secret: len %d/%d", klen, kout);
|
||||
fprintf(stderr, "shared secret == ");
|
||||
for (i = 0; i< kout; i++)
|
||||
fprintf(stderr, "%02x", (kbuf[i])&0xff);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
shared_secret = BN_new();
|
||||
|
||||
BN_bin2bn(kbuf, kout, shared_secret);
|
||||
memset(kbuf, 0, klen);
|
||||
xfree(kbuf);
|
||||
|
||||
/* calc and verify H */
|
||||
hash = kex_hash_gex(
|
||||
client_version_string,
|
||||
server_version_string,
|
||||
buffer_ptr(client_kexinit), buffer_len(client_kexinit),
|
||||
buffer_ptr(server_kexinit), buffer_len(server_kexinit),
|
||||
server_host_key_blob, sbloblen,
|
||||
nbits, dh->p, dh->g,
|
||||
dh->pub_key,
|
||||
dh_server_pub,
|
||||
shared_secret
|
||||
);
|
||||
xfree(server_host_key_blob);
|
||||
DH_free(dh);
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "hash == ");
|
||||
for (i = 0; i< 20; i++)
|
||||
fprintf(stderr, "%02x", (hash[i])&0xff);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
|
||||
fatal("key_verify failed for server_host_key");
|
||||
key_free(server_host_key);
|
||||
|
||||
kex_derive_keys(kex, hash, shared_secret);
|
||||
packet_set_kex(kex);
|
||||
|
||||
/* save session id */
|
||||
session_id2_len = 20;
|
||||
session_id2 = xmalloc(session_id2_len);
|
||||
memcpy(session_id2, hash, session_id2_len);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -271,15 +456,15 @@ typedef struct Authmethod Authmethod;
|
||||
|
||||
typedef int sign_cb_fn(
|
||||
Authctxt *authctxt, Key *key,
|
||||
unsigned char **sigp, int *lenp, unsigned char *data, int datalen);
|
||||
u_char **sigp, int *lenp, u_char *data, int datalen);
|
||||
|
||||
struct Authctxt {
|
||||
const char *server_user;
|
||||
const char *host;
|
||||
const char *service;
|
||||
AuthenticationConnection *agent;
|
||||
int success;
|
||||
Authmethod *method;
|
||||
int success;
|
||||
};
|
||||
struct Authmethod {
|
||||
char *name; /* string to compare against server's list */
|
||||
@ -290,22 +475,36 @@ struct Authmethod {
|
||||
|
||||
void input_userauth_success(int type, int plen, void *ctxt);
|
||||
void input_userauth_failure(int type, int plen, void *ctxt);
|
||||
void input_userauth_banner(int type, int plen, void *ctxt);
|
||||
void input_userauth_error(int type, int plen, void *ctxt);
|
||||
void input_userauth_info_req(int type, int plen, void *ctxt);
|
||||
|
||||
int userauth_none(Authctxt *authctxt);
|
||||
int userauth_pubkey(Authctxt *authctxt);
|
||||
int userauth_passwd(Authctxt *authctxt);
|
||||
int userauth_kbdint(Authctxt *authctxt);
|
||||
|
||||
void authmethod_clear(void);
|
||||
Authmethod *authmethod_get(char *auth_list);
|
||||
Authmethod *authmethod_get(char *authlist);
|
||||
Authmethod *authmethod_lookup(const char *name);
|
||||
|
||||
Authmethod authmethods[] = {
|
||||
{"publickey",
|
||||
userauth_pubkey,
|
||||
&options.dsa_authentication,
|
||||
&options.pubkey_authentication,
|
||||
NULL},
|
||||
{"password",
|
||||
userauth_passwd,
|
||||
&options.password_authentication,
|
||||
&options.batch_mode},
|
||||
{"keyboard-interactive",
|
||||
userauth_kbdint,
|
||||
&options.kbd_interactive_authentication,
|
||||
&options.batch_mode},
|
||||
{"none",
|
||||
userauth_none,
|
||||
NULL,
|
||||
NULL},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
@ -342,32 +541,41 @@ ssh_userauth2(const char *server_user, char *host)
|
||||
authctxt.host = host;
|
||||
authctxt.service = "ssh-connection"; /* service name */
|
||||
authctxt.success = 0;
|
||||
authctxt.method = NULL;
|
||||
authctxt.method = authmethod_lookup("none");
|
||||
if (authctxt.method == NULL)
|
||||
fatal("ssh_userauth2: internal error: cannot send userauth none request");
|
||||
authmethod_clear();
|
||||
|
||||
/* initial userauth request */
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
packet_put_cstring(authctxt.server_user);
|
||||
packet_put_cstring(authctxt.service);
|
||||
packet_put_cstring("none");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
authmethod_clear();
|
||||
userauth_none(&authctxt);
|
||||
|
||||
dispatch_init(&input_userauth_error);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
|
||||
dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
|
||||
|
||||
if (authctxt.agent != NULL)
|
||||
ssh_close_authentication_connection(authctxt.agent);
|
||||
|
||||
debug("ssh-userauth2 successfull");
|
||||
debug("ssh-userauth2 successful: method %s", authctxt.method->name);
|
||||
}
|
||||
void
|
||||
input_userauth_error(int type, int plen, void *ctxt)
|
||||
{
|
||||
fatal("input_userauth_error: bad message during authentication");
|
||||
fatal("input_userauth_error: bad message during authentication: "
|
||||
"type %d", type);
|
||||
}
|
||||
void
|
||||
input_userauth_banner(int type, int plen, void *ctxt)
|
||||
{
|
||||
char *msg, *lang;
|
||||
debug3("input_userauth_banner");
|
||||
msg = packet_get_string(NULL);
|
||||
lang = packet_get_string(NULL);
|
||||
fprintf(stderr, "%s", msg);
|
||||
xfree(msg);
|
||||
xfree(lang);
|
||||
}
|
||||
void
|
||||
input_userauth_success(int type, int plen, void *ctxt)
|
||||
@ -384,12 +592,11 @@ input_userauth_failure(int type, int plen, void *ctxt)
|
||||
Authctxt *authctxt = ctxt;
|
||||
char *authlist = NULL;
|
||||
int partial;
|
||||
int dlen;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_failure: no authentication context");
|
||||
|
||||
authlist = packet_get_string(&dlen);
|
||||
authlist = packet_get_string(NULL);
|
||||
partial = packet_get_char();
|
||||
packet_done();
|
||||
|
||||
@ -398,12 +605,12 @@ input_userauth_failure(int type, int plen, void *ctxt)
|
||||
debug("authentications that can continue: %s", authlist);
|
||||
|
||||
for (;;) {
|
||||
/* try old method or get next method */
|
||||
method = authmethod_get(authlist);
|
||||
if (method == NULL)
|
||||
fatal("Unable to find an authentication method");
|
||||
authctxt->method = method;
|
||||
if (method->userauth(authctxt) != 0) {
|
||||
debug2("we sent a packet, wait for reply");
|
||||
debug2("we sent a %s packet, wait for reply", method->name);
|
||||
break;
|
||||
} else {
|
||||
debug2("we did not send a packet, disable method");
|
||||
@ -413,6 +620,19 @@ input_userauth_failure(int type, int plen, void *ctxt)
|
||||
xfree(authlist);
|
||||
}
|
||||
|
||||
int
|
||||
userauth_none(Authctxt *authctxt)
|
||||
{
|
||||
/* initial userauth request */
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
packet_put_cstring(authctxt->server_user);
|
||||
packet_put_cstring(authctxt->service);
|
||||
packet_put_cstring(authctxt->method->name);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
userauth_passwd(Authctxt *authctxt)
|
||||
{
|
||||
@ -432,7 +652,7 @@ userauth_passwd(Authctxt *authctxt)
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
packet_put_cstring(authctxt->server_user);
|
||||
packet_put_cstring(authctxt->service);
|
||||
packet_put_cstring("password");
|
||||
packet_put_cstring(authctxt->method->name);
|
||||
packet_put_char(0);
|
||||
packet_put_cstring(password);
|
||||
memset(password, 0, strlen(password));
|
||||
@ -446,31 +666,40 @@ static int
|
||||
sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||
{
|
||||
Buffer b;
|
||||
unsigned char *blob, *signature;
|
||||
u_char *blob, *signature;
|
||||
int bloblen, slen;
|
||||
int skip = 0;
|
||||
int ret = -1;
|
||||
int have_sig = 1;
|
||||
|
||||
dsa_make_key_blob(k, &blob, &bloblen);
|
||||
|
||||
debug3("sign_and_send_pubkey");
|
||||
if (key_to_blob(k, &blob, &bloblen) == 0) {
|
||||
/* we cannot handle this key */
|
||||
debug3("sign_and_send_pubkey: cannot handle key");
|
||||
return 0;
|
||||
}
|
||||
/* data to be signed */
|
||||
buffer_init(&b);
|
||||
if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) {
|
||||
buffer_put_string(&b, session_id2, session_id2_len);
|
||||
skip = buffer_len(&b);
|
||||
} else {
|
||||
if (datafellows & SSH_OLD_SESSIONID) {
|
||||
buffer_append(&b, session_id2, session_id2_len);
|
||||
skip = session_id2_len;
|
||||
} else {
|
||||
buffer_put_string(&b, session_id2, session_id2_len);
|
||||
skip = buffer_len(&b);
|
||||
}
|
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
||||
buffer_put_cstring(&b, authctxt->server_user);
|
||||
buffer_put_cstring(&b,
|
||||
datafellows & SSH_BUG_PUBKEYAUTH ?
|
||||
datafellows & SSH_BUG_PKSERVICE ?
|
||||
"ssh-userauth" :
|
||||
authctxt->service);
|
||||
buffer_put_cstring(&b, "publickey");
|
||||
buffer_put_char(&b, 1);
|
||||
buffer_put_cstring(&b, KEX_DSS);
|
||||
if (datafellows & SSH_BUG_PKAUTH) {
|
||||
buffer_put_char(&b, have_sig);
|
||||
} else {
|
||||
buffer_put_cstring(&b, authctxt->method->name);
|
||||
buffer_put_char(&b, have_sig);
|
||||
buffer_put_cstring(&b, key_ssh_name(k));
|
||||
}
|
||||
buffer_put_string(&b, blob, bloblen);
|
||||
|
||||
/* generate signature */
|
||||
@ -480,18 +709,19 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||
buffer_free(&b);
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG_DSS
|
||||
#ifdef DEBUG_PK
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
if (datafellows & SSH_BUG_PUBKEYAUTH) {
|
||||
if (datafellows & SSH_BUG_PKSERVICE) {
|
||||
buffer_clear(&b);
|
||||
buffer_append(&b, session_id2, session_id2_len);
|
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
||||
buffer_put_cstring(&b, authctxt->server_user);
|
||||
buffer_put_cstring(&b, authctxt->service);
|
||||
buffer_put_cstring(&b, "publickey");
|
||||
buffer_put_char(&b, 1);
|
||||
buffer_put_cstring(&b, KEX_DSS);
|
||||
buffer_put_cstring(&b, authctxt->method->name);
|
||||
buffer_put_char(&b, have_sig);
|
||||
if (!(datafellows & SSH_BUG_PKAUTH))
|
||||
buffer_put_cstring(&b, key_ssh_name(k));
|
||||
buffer_put_string(&b, blob, bloblen);
|
||||
}
|
||||
xfree(blob);
|
||||
@ -517,11 +747,10 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||
}
|
||||
|
||||
/* sign callback */
|
||||
static int
|
||||
dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
|
||||
unsigned char *data, int datalen)
|
||||
static int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
return dsa_sign(key, sigp, lenp, data, datalen);
|
||||
return key_sign(key, sigp, lenp, data, datalen);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -537,14 +766,13 @@ userauth_pubkey_identity(Authctxt *authctxt, char *filename)
|
||||
}
|
||||
debug("try pubkey: %s", filename);
|
||||
|
||||
k = key_new(KEY_DSA);
|
||||
k = key_new(KEY_UNSPEC);
|
||||
if (!load_private_key(filename, "", k, NULL)) {
|
||||
int success = 0;
|
||||
char *passphrase;
|
||||
char prompt[300];
|
||||
snprintf(prompt, sizeof prompt,
|
||||
"Enter passphrase for %s key '%.100s': ",
|
||||
key_type(k), filename);
|
||||
"Enter passphrase for key '%.100s': ", filename);
|
||||
for (i = 0; i < options.number_of_password_prompts; i++) {
|
||||
passphrase = read_passphrase(prompt, 0);
|
||||
if (strcmp(passphrase, "") != 0) {
|
||||
@ -565,15 +793,14 @@ userauth_pubkey_identity(Authctxt *authctxt, char *filename)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb);
|
||||
ret = sign_and_send_pubkey(authctxt, k, key_sign_cb);
|
||||
key_free(k);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* sign callback */
|
||||
static int
|
||||
agent_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
|
||||
unsigned char *data, int datalen)
|
||||
static int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
||||
u_char *data, int datalen)
|
||||
{
|
||||
return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
|
||||
}
|
||||
@ -582,24 +809,26 @@ static int
|
||||
userauth_pubkey_agent(Authctxt *authctxt)
|
||||
{
|
||||
static int called = 0;
|
||||
int ret = 0;
|
||||
char *comment;
|
||||
Key *k;
|
||||
int ret;
|
||||
|
||||
if (called == 0) {
|
||||
k = ssh_get_first_identity(authctxt->agent, &comment, 2);
|
||||
if (ssh_get_num_identities(authctxt->agent, 2) == 0)
|
||||
debug2("userauth_pubkey_agent: no keys at all");
|
||||
called = 1;
|
||||
} else {
|
||||
k = ssh_get_next_identity(authctxt->agent, &comment, 2);
|
||||
}
|
||||
k = ssh_get_next_identity(authctxt->agent, &comment, 2);
|
||||
if (k == NULL) {
|
||||
debug2("no more DSA keys from agent");
|
||||
return 0;
|
||||
debug2("userauth_pubkey_agent: no more keys");
|
||||
} else {
|
||||
debug("userauth_pubkey_agent: trying agent key %s", comment);
|
||||
xfree(comment);
|
||||
ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
|
||||
key_free(k);
|
||||
}
|
||||
debug("trying DSA agent key %s", comment);
|
||||
xfree(comment);
|
||||
ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
|
||||
key_free(k);
|
||||
if (ret == 0)
|
||||
debug2("userauth_pubkey_agent: no message sent");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -609,13 +838,106 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
static int idx = 0;
|
||||
int sent = 0;
|
||||
|
||||
if (authctxt->agent != NULL)
|
||||
sent = userauth_pubkey_agent(authctxt);
|
||||
while (sent == 0 && idx < options.num_identity_files2)
|
||||
sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]);
|
||||
if (authctxt->agent != NULL) {
|
||||
do {
|
||||
sent = userauth_pubkey_agent(authctxt);
|
||||
} while(!sent && authctxt->agent->howmany > 0);
|
||||
}
|
||||
while (!sent && idx < options.num_identity_files) {
|
||||
if (options.identity_files_type[idx] != KEY_RSA1)
|
||||
sent = userauth_pubkey_identity(authctxt,
|
||||
options.identity_files[idx]);
|
||||
idx++;
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send userauth request message specifying keyboard-interactive method.
|
||||
*/
|
||||
int
|
||||
userauth_kbdint(Authctxt *authctxt)
|
||||
{
|
||||
static int attempt = 0;
|
||||
|
||||
if (attempt++ >= options.number_of_password_prompts)
|
||||
return 0;
|
||||
|
||||
debug2("userauth_kbdint");
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
packet_put_cstring(authctxt->server_user);
|
||||
packet_put_cstring(authctxt->service);
|
||||
packet_put_cstring(authctxt->method->name);
|
||||
packet_put_cstring(""); /* lang */
|
||||
packet_put_cstring(options.kbd_interactive_devices ?
|
||||
options.kbd_interactive_devices : "");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* parse SSH2_MSG_USERAUTH_INFO_REQUEST, prompt user and send
|
||||
* SSH2_MSG_USERAUTH_INFO_RESPONSE
|
||||
*/
|
||||
void
|
||||
input_userauth_info_req(int type, int plen, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
char *name = NULL;
|
||||
char *inst = NULL;
|
||||
char *lang = NULL;
|
||||
char *prompt = NULL;
|
||||
char *response = NULL;
|
||||
u_int num_prompts, i;
|
||||
int echo = 0;
|
||||
|
||||
debug2("input_userauth_info_req");
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_req: no authentication context");
|
||||
|
||||
name = packet_get_string(NULL);
|
||||
inst = packet_get_string(NULL);
|
||||
lang = packet_get_string(NULL);
|
||||
|
||||
if (strlen(name) > 0)
|
||||
cli_mesg(name);
|
||||
xfree(name);
|
||||
|
||||
if (strlen(inst) > 0)
|
||||
cli_mesg(inst);
|
||||
xfree(inst);
|
||||
xfree(lang); /* unused */
|
||||
|
||||
num_prompts = packet_get_int();
|
||||
/*
|
||||
* Begin to build info response packet based on prompts requested.
|
||||
* We commit to providing the correct number of responses, so if
|
||||
* further on we run into a problem that prevents this, we have to
|
||||
* be sure and clean this up and send a correct error response.
|
||||
*/
|
||||
packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
|
||||
packet_put_int(num_prompts);
|
||||
|
||||
for (i = 0; i < num_prompts; i++) {
|
||||
prompt = packet_get_string(NULL);
|
||||
echo = packet_get_char();
|
||||
|
||||
response = cli_prompt(prompt, echo);
|
||||
|
||||
packet_put_cstring(response);
|
||||
memset(response, 0, strlen(response));
|
||||
xfree(response);
|
||||
xfree(prompt);
|
||||
}
|
||||
packet_done(); /* done with parsing incoming message. */
|
||||
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
}
|
||||
|
||||
/* find auth method */
|
||||
|
||||
@ -670,7 +992,7 @@ authmethod_is_enabled(Authmethod *method)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Authmethod *
|
||||
Authmethod *
|
||||
authmethod_lookup(const char *name)
|
||||
{
|
||||
Authmethod *method = NULL;
|
||||
@ -693,7 +1015,7 @@ authmethod_lookup(const char *name)
|
||||
Authmethod *
|
||||
authmethod_get(char *authlist)
|
||||
{
|
||||
char *name = NULL;
|
||||
char *name = NULL, *authname_old;
|
||||
Authmethod *method = NULL;
|
||||
|
||||
/* Use a suitable default if we're passed a nil list. */
|
||||
@ -702,6 +1024,7 @@ authmethod_get(char *authlist)
|
||||
|
||||
if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
|
||||
/* start over if passed a different list */
|
||||
debug3("start over, passed a different list");
|
||||
authmethod_clear();
|
||||
authlist_current = xstrdup(authlist);
|
||||
authlist_working = xstrdup(authlist);
|
||||
@ -716,22 +1039,27 @@ authmethod_get(char *authlist)
|
||||
}
|
||||
|
||||
while (name != NULL) {
|
||||
debug3("authmethod_lookup %s", name);
|
||||
method = authmethod_lookup(name);
|
||||
if (method != NULL && authmethod_is_enabled(method))
|
||||
if (method != NULL && authmethod_is_enabled(method)) {
|
||||
debug3("authmethod_is_enabled %s", name);
|
||||
break;
|
||||
}
|
||||
name = strtok_r(NULL, DELIM, &authlist_state);
|
||||
method = NULL;
|
||||
}
|
||||
|
||||
if (authname_current != NULL)
|
||||
xfree(authname_current);
|
||||
|
||||
if (name != NULL) {
|
||||
authname_old = authname_current;
|
||||
if (method != NULL) {
|
||||
debug("next auth method to try is %s", name);
|
||||
authname_current = xstrdup(name);
|
||||
return method;
|
||||
} else {
|
||||
debug("no more auth methods to try");
|
||||
authname_current = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (authname_old != NULL)
|
||||
xfree(authname_old);
|
||||
|
||||
return (method);
|
||||
}
|
||||
|
623
crypto/dist/ssh/sshd.c
vendored
623
crypto/dist/ssh/sshd.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sshd.c,v 1.1.1.1 2000/09/28 22:10:42 thorpej Exp $ */
|
||||
/* $NetBSD: sshd.c,v 1.1.1.2 2001/01/14 04:51:03 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -41,11 +41,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: sshd.c,v 1.128 2000/09/17 15:38:59 markus Exp */
|
||||
/* from OpenBSD: sshd.c,v 1.145 2001/01/04 22:25:58 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sshd.c,v 1.1.1.1 2000/09/28 22:10:42 thorpej Exp $");
|
||||
__RCSID("$NetBSD: sshd.c,v 1.1.1.2 2001/01/14 04:51:03 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -72,7 +72,7 @@ __RCSID("$NetBSD: sshd.c,v 1.1.1.1 2000/09/28 22:10:42 thorpej Exp $");
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "key.h"
|
||||
#include "dsa.h"
|
||||
#include "dh.h"
|
||||
|
||||
#include "auth.h"
|
||||
#include "myproposal.h"
|
||||
@ -89,6 +89,8 @@ int deny_severity = LOG_WARNING;
|
||||
#define O_NOCTTY 0
|
||||
#endif
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
/* Server configuration options. */
|
||||
ServerOptions options;
|
||||
|
||||
@ -112,12 +114,12 @@ int debug_flag = 0;
|
||||
/* Flag indicating that the daemon is being started from inetd. */
|
||||
int inetd_flag = 0;
|
||||
|
||||
/* Flag indicating that sshd should not detach and become a daemon. */
|
||||
int no_daemon_flag = 0;
|
||||
|
||||
/* debug goes to stderr unless inetd_flag is set */
|
||||
int log_stderr = 0;
|
||||
|
||||
/* argv[0] without path. */
|
||||
char *av0;
|
||||
|
||||
/* Saved arguments to main(). */
|
||||
char **saved_argv;
|
||||
|
||||
@ -145,9 +147,11 @@ char *server_version_string = NULL;
|
||||
* not very useful. Currently, memory locking is not implemented.
|
||||
*/
|
||||
struct {
|
||||
RSA *private_key; /* Private part of empheral server key. */
|
||||
RSA *host_key; /* Private part of host key. */
|
||||
Key *dsa_host_key; /* Private DSA host key. */
|
||||
Key *server_key; /* empheral server key */
|
||||
Key *ssh1_host_key; /* ssh1 host key */
|
||||
Key **host_keys; /* all private host keys */
|
||||
int have_ssh1_key;
|
||||
int have_ssh2_key;
|
||||
} sensitive_data;
|
||||
|
||||
/*
|
||||
@ -159,24 +163,23 @@ int key_used = 0;
|
||||
/* This is set to true when SIGHUP is received. */
|
||||
int received_sighup = 0;
|
||||
|
||||
/* Public side of the server key. This value is regenerated regularly with
|
||||
the private key. */
|
||||
RSA *public_key;
|
||||
|
||||
/* session identifier, used by RSA-auth */
|
||||
unsigned char session_id[16];
|
||||
u_char session_id[16];
|
||||
|
||||
/* same for ssh2 */
|
||||
unsigned char *session_id2 = NULL;
|
||||
u_char *session_id2 = NULL;
|
||||
int session_id2_len = 0;
|
||||
|
||||
/* record remote hostname or ip */
|
||||
unsigned int utmp_len = MAXHOSTNAMELEN;
|
||||
u_int utmp_len = MAXHOSTNAMELEN;
|
||||
|
||||
/* Prototypes for various functions defined later in this file. */
|
||||
void do_ssh1_kex(void);
|
||||
void do_ssh2_kex(void);
|
||||
|
||||
void ssh_dh1_server(Kex *, Buffer *_kexinit, Buffer *);
|
||||
void ssh_dhgex_server(Kex *, Buffer *_kexinit, Buffer *);
|
||||
|
||||
/*
|
||||
* Close all listening sockets
|
||||
*/
|
||||
@ -211,7 +214,7 @@ sighup_restart(void)
|
||||
log("Received SIGHUP; restarting.");
|
||||
close_listen_socks();
|
||||
execv(saved_argv[0], saved_argv);
|
||||
log("RESTART FAILED: av0='%s', error: %s.", av0, strerror(errno));
|
||||
log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -268,6 +271,17 @@ grace_alarm_handler(int sig)
|
||||
*/
|
||||
/* XXX do we really want this work to be done in a signal handler ? -m */
|
||||
static void
|
||||
generate_empheral_server_key(void)
|
||||
{
|
||||
log("Generating %s%d bit RSA key.", sensitive_data.server_key ? "new " : "",
|
||||
options.server_key_bits);
|
||||
if (sensitive_data.server_key != NULL)
|
||||
key_free(sensitive_data.server_key);
|
||||
sensitive_data.server_key = key_generate(KEY_RSA1, options.server_key_bits);
|
||||
ssh_random_stir();
|
||||
log("RSA key generation complete.");
|
||||
}
|
||||
static void
|
||||
key_regeneration_alarm(int sig)
|
||||
{
|
||||
int save_errno = errno;
|
||||
@ -275,21 +289,8 @@ key_regeneration_alarm(int sig)
|
||||
/* Check if we should generate a new key. */
|
||||
if (key_used) {
|
||||
/* This should really be done in the background. */
|
||||
log("Generating new %d bit RSA key.", options.server_key_bits);
|
||||
|
||||
if (sensitive_data.private_key != NULL)
|
||||
RSA_free(sensitive_data.private_key);
|
||||
sensitive_data.private_key = RSA_new();
|
||||
|
||||
if (public_key != NULL)
|
||||
RSA_free(public_key);
|
||||
public_key = RSA_new();
|
||||
|
||||
rsa_generate_key(sensitive_data.private_key, public_key,
|
||||
options.server_key_bits);
|
||||
ssh_random_stir();
|
||||
generate_empheral_server_key();
|
||||
key_used = 0;
|
||||
log("RSA key generation complete.");
|
||||
}
|
||||
/* Reschedule the alarm. */
|
||||
signal(SIGALRM, key_regeneration_alarm);
|
||||
@ -338,6 +339,10 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
if (buf[i] == '\r') {
|
||||
buf[i] = '\n';
|
||||
buf[i + 1] = 0;
|
||||
/* Kludge for F-Secure Macintosh < 1.0.2 */
|
||||
if (i == 12 &&
|
||||
strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (buf[i] == '\n') {
|
||||
@ -420,18 +425,93 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
}
|
||||
|
||||
|
||||
/* Destroy the host and server keys. They will no longer be needed. */
|
||||
static void
|
||||
destroy_sensitive_data(void)
|
||||
{
|
||||
/* Destroy the private and public keys. They will no longer be needed. */
|
||||
if (public_key)
|
||||
RSA_free(public_key);
|
||||
if (sensitive_data.private_key)
|
||||
RSA_free(sensitive_data.private_key);
|
||||
if (sensitive_data.host_key)
|
||||
RSA_free(sensitive_data.host_key);
|
||||
if (sensitive_data.dsa_host_key != NULL)
|
||||
key_free(sensitive_data.dsa_host_key);
|
||||
int i;
|
||||
|
||||
if (sensitive_data.server_key) {
|
||||
key_free(sensitive_data.server_key);
|
||||
sensitive_data.server_key = NULL;
|
||||
}
|
||||
for(i = 0; i < options.num_host_key_files; i++) {
|
||||
if (sensitive_data.host_keys[i]) {
|
||||
key_free(sensitive_data.host_keys[i]);
|
||||
sensitive_data.host_keys[i] = NULL;
|
||||
}
|
||||
}
|
||||
sensitive_data.ssh1_host_key = NULL;
|
||||
}
|
||||
static Key *
|
||||
load_private_key_autodetect(const char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
int type;
|
||||
Key *public, *private;
|
||||
|
||||
if (stat(filename, &st) < 0) {
|
||||
perror(filename);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* try to load the public key. right now this only works for RSA1,
|
||||
* since SSH2 keys are fully encrypted
|
||||
*/
|
||||
type = KEY_RSA1;
|
||||
public = key_new(type);
|
||||
if (!load_public_key(filename, public, NULL)) {
|
||||
/* ok, so we will assume this is 'some' key */
|
||||
type = KEY_UNSPEC;
|
||||
}
|
||||
key_free(public);
|
||||
|
||||
/* Ok, try key with empty passphrase */
|
||||
private = key_new(type);
|
||||
if (load_private_key(filename, "", private, NULL)) {
|
||||
debug("load_private_key_autodetect: type %d %s",
|
||||
private->type, key_type(private));
|
||||
return private;
|
||||
}
|
||||
key_free(private);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
list_hostkey_types(void)
|
||||
{
|
||||
static char buf[1024];
|
||||
int i;
|
||||
buf[0] = '\0';
|
||||
for(i = 0; i < options.num_host_key_files; i++) {
|
||||
Key *key = sensitive_data.host_keys[i];
|
||||
if (key == NULL)
|
||||
continue;
|
||||
switch(key->type) {
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
strlcat(buf, key_ssh_name(key), sizeof buf);
|
||||
strlcat(buf, ",", sizeof buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = strlen(buf);
|
||||
if (i > 0 && buf[i-1] == ',')
|
||||
buf[i-1] = '\0';
|
||||
debug("list_hostkey_types: %s", buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Key *
|
||||
get_hostkey_by_type(int type)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < options.num_host_key_files; i++) {
|
||||
Key *key = sensitive_data.host_keys[i];
|
||||
if (key != NULL && key->type == type)
|
||||
return key;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -491,18 +571,14 @@ main(int ac, char **av)
|
||||
int startup_p[2];
|
||||
int startups = 0;
|
||||
|
||||
/* Save argv[0]. */
|
||||
/* Save argv. */
|
||||
saved_argv = av;
|
||||
if (strchr(av[0], '/'))
|
||||
av0 = strrchr(av[0], '/') + 1;
|
||||
else
|
||||
av0 = av[0];
|
||||
|
||||
/* Initialize configuration options to their default values. */
|
||||
initialize_server_options(&options);
|
||||
|
||||
/* Parse command-line arguments. */
|
||||
while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:diqQ46")) != EOF) {
|
||||
while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDiqQ46")) != EOF) {
|
||||
switch (opt) {
|
||||
case '4':
|
||||
IPv4or6 = AF_INET;
|
||||
@ -524,6 +600,9 @@ main(int ac, char **av)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
no_daemon_flag = 1;
|
||||
break;
|
||||
case 'i':
|
||||
inetd_flag = 1;
|
||||
break;
|
||||
@ -551,7 +630,11 @@ main(int ac, char **av)
|
||||
options.key_regeneration_time = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
options.host_key_file = optarg;
|
||||
if (options.num_host_key_files >= MAX_HOSTKEYS) {
|
||||
fprintf(stderr, "too many host keys.\n");
|
||||
exit(1);
|
||||
}
|
||||
options.host_key_files[options.num_host_key_files++] = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
client_version_string = optarg;
|
||||
@ -564,15 +647,16 @@ main(int ac, char **av)
|
||||
case '?':
|
||||
default:
|
||||
fprintf(stderr, "sshd version %s\n", SSH_VERSION);
|
||||
fprintf(stderr, "Usage: %s [options]\n", av0);
|
||||
fprintf(stderr, "Usage: %s [options]\n", __progname);
|
||||
fprintf(stderr, "Options:\n");
|
||||
fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
|
||||
fprintf(stderr, " -d Debugging mode (multiple -d means more debugging)\n");
|
||||
fprintf(stderr, " -i Started from inetd\n");
|
||||
fprintf(stderr, " -D Do not fork into daemon mode\n");
|
||||
fprintf(stderr, " -q Quiet (no logging)\n");
|
||||
fprintf(stderr, " -p port Listen on the specified port (default: 22)\n");
|
||||
fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n");
|
||||
fprintf(stderr, " -g seconds Grace period for authentication (default: 300)\n");
|
||||
fprintf(stderr, " -g seconds Grace period for authentication (default: 600)\n");
|
||||
fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n");
|
||||
fprintf(stderr, " -h file File from which to read host key (default: %s)\n",
|
||||
_PATH_HOST_KEY_FILE);
|
||||
@ -587,7 +671,7 @@ main(int ac, char **av)
|
||||
* Force logging to stderr until we have loaded the private host
|
||||
* key (unless started from inetd)
|
||||
*/
|
||||
log_init(av0,
|
||||
log_init(__progname,
|
||||
options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
|
||||
options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
|
||||
!silent && !inetd_flag, 0, 0);
|
||||
@ -606,39 +690,41 @@ main(int ac, char **av)
|
||||
|
||||
debug("sshd version %.100s", SSH_VERSION);
|
||||
|
||||
sensitive_data.dsa_host_key = NULL;
|
||||
sensitive_data.host_key = NULL;
|
||||
/* load private host keys */
|
||||
sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*));
|
||||
for(i = 0; i < options.num_host_key_files; i++)
|
||||
sensitive_data.host_keys[i] = NULL;
|
||||
sensitive_data.server_key = NULL;
|
||||
sensitive_data.ssh1_host_key = NULL;
|
||||
sensitive_data.have_ssh1_key = 0;
|
||||
sensitive_data.have_ssh2_key = 0;
|
||||
|
||||
/* check if RSA support exists */
|
||||
if ((options.protocol & SSH_PROTO_1) &&
|
||||
rsa_alive() == 0) {
|
||||
log("no RSA support in libssl and libcrypto. See ssl(8)");
|
||||
log("Disabling protocol version 1");
|
||||
for(i = 0; i < options.num_host_key_files; i++) {
|
||||
Key *key = load_private_key_autodetect(options.host_key_files[i]);
|
||||
if (key == NULL) {
|
||||
error("Could not load host key: %.200s: %.100s",
|
||||
options.host_key_files[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
switch(key->type){
|
||||
case KEY_RSA1:
|
||||
sensitive_data.ssh1_host_key = key;
|
||||
sensitive_data.have_ssh1_key = 1;
|
||||
break;
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
sensitive_data.have_ssh2_key = 1;
|
||||
break;
|
||||
}
|
||||
sensitive_data.host_keys[i] = key;
|
||||
}
|
||||
if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
|
||||
log("Disabling protocol version 1. Could not load host key");
|
||||
options.protocol &= ~SSH_PROTO_1;
|
||||
}
|
||||
/* Load the RSA/DSA host key. It must have empty passphrase. */
|
||||
if (options.protocol & SSH_PROTO_1) {
|
||||
Key k;
|
||||
sensitive_data.host_key = RSA_new();
|
||||
k.type = KEY_RSA;
|
||||
k.rsa = sensitive_data.host_key;
|
||||
errno = 0;
|
||||
if (!load_private_key(options.host_key_file, "", &k, NULL)) {
|
||||
error("Could not load host key: %.200s: %.100s",
|
||||
options.host_key_file, strerror(errno));
|
||||
log("Disabling protocol version 1");
|
||||
options.protocol &= ~SSH_PROTO_1;
|
||||
}
|
||||
k.rsa = NULL;
|
||||
}
|
||||
if (options.protocol & SSH_PROTO_2) {
|
||||
sensitive_data.dsa_host_key = key_new(KEY_DSA);
|
||||
if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) {
|
||||
|
||||
error("Could not load DSA host key: %.200s", options.host_dsa_key_file);
|
||||
log("Disabling protocol version 2");
|
||||
options.protocol &= ~SSH_PROTO_2;
|
||||
}
|
||||
if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
|
||||
log("Disabling protocol version 2. Could not load host key");
|
||||
options.protocol &= ~SSH_PROTO_2;
|
||||
}
|
||||
if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) {
|
||||
if (silent == 0)
|
||||
@ -660,11 +746,11 @@ main(int ac, char **av)
|
||||
* hate software patents. I dont know if this can go? Niels
|
||||
*/
|
||||
if (options.server_key_bits >
|
||||
BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED &&
|
||||
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - SSH_KEY_BITS_RESERVED &&
|
||||
options.server_key_bits <
|
||||
BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) {
|
||||
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
|
||||
options.server_key_bits =
|
||||
BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED;
|
||||
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED;
|
||||
debug("Forcing server key to %d bits to make it differ from host key.",
|
||||
options.server_key_bits);
|
||||
}
|
||||
@ -673,7 +759,7 @@ main(int ac, char **av)
|
||||
/* Initialize the log (it is reinitialized below in case we forked). */
|
||||
if (debug_flag && !inetd_flag)
|
||||
log_stderr = 1;
|
||||
log_init(av0, options.log_level, options.log_facility, log_stderr,
|
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr,
|
||||
0, 0);
|
||||
|
||||
/*
|
||||
@ -681,7 +767,7 @@ main(int ac, char **av)
|
||||
* from the controlling terminal, and fork. The original process
|
||||
* exits.
|
||||
*/
|
||||
if (!debug_flag && !inetd_flag) {
|
||||
if (!(debug_flag || inetd_flag || no_daemon_flag)) {
|
||||
#ifdef TIOCNOTTY
|
||||
int fd;
|
||||
#endif /* TIOCNOTTY */
|
||||
@ -698,12 +784,9 @@ main(int ac, char **av)
|
||||
#endif /* TIOCNOTTY */
|
||||
}
|
||||
/* Reinitialize the log (because of the fork above). */
|
||||
log_init(av0, options.log_level, options.log_facility, log_stderr,
|
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr,
|
||||
0, 0);
|
||||
|
||||
/* Do not display messages to stdout in RSA code. */
|
||||
rsa_set_verbose(0);
|
||||
|
||||
/* Initialize the random number generator. */
|
||||
ssh_random_stir();
|
||||
|
||||
@ -725,16 +808,8 @@ main(int ac, char **av)
|
||||
* ttyfd happens to be one of those.
|
||||
*/
|
||||
debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);
|
||||
|
||||
if (options.protocol & SSH_PROTO_1) {
|
||||
public_key = RSA_new();
|
||||
sensitive_data.private_key = RSA_new();
|
||||
log("Generating %d bit RSA key.", options.server_key_bits);
|
||||
rsa_generate_key(sensitive_data.private_key, public_key,
|
||||
options.server_key_bits);
|
||||
ssh_random_stir();
|
||||
log("RSA key generation complete.");
|
||||
}
|
||||
if (options.protocol & SSH_PROTO_1)
|
||||
generate_empheral_server_key();
|
||||
} else {
|
||||
for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
|
||||
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
||||
@ -798,27 +873,20 @@ main(int ac, char **av)
|
||||
|
||||
if (!debug_flag) {
|
||||
/*
|
||||
* Record our pid in /etc/sshd_pid to make it easier
|
||||
* to kill the correct sshd. We don\'t want to do
|
||||
* this before the bind above because the bind will
|
||||
* Record our pid in /var/run/sshd.pid to make it
|
||||
* easier to kill the correct sshd. We don't want to
|
||||
* do this before the bind above because the bind will
|
||||
* fail if there already is a daemon, and this will
|
||||
* overwrite any old pid in the file.
|
||||
*/
|
||||
f = fopen(options.pid_file, "w");
|
||||
if (f) {
|
||||
fprintf(f, "%u\n", (unsigned int) getpid());
|
||||
fprintf(f, "%u\n", (u_int) getpid());
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
if (options.protocol & SSH_PROTO_1) {
|
||||
public_key = RSA_new();
|
||||
sensitive_data.private_key = RSA_new();
|
||||
|
||||
log("Generating %d bit RSA key.", options.server_key_bits);
|
||||
rsa_generate_key(sensitive_data.private_key, public_key,
|
||||
options.server_key_bits);
|
||||
ssh_random_stir();
|
||||
log("RSA key generation complete.");
|
||||
generate_empheral_server_key();
|
||||
|
||||
/* Schedule server key regeneration alarm. */
|
||||
signal(SIGALRM, key_regeneration_alarm);
|
||||
@ -876,7 +944,7 @@ main(int ac, char **av)
|
||||
/*
|
||||
* the read end of the pipe is ready
|
||||
* if the child has closed the pipe
|
||||
* after successfull authentication
|
||||
* after successful authentication
|
||||
* or if the child has died
|
||||
*/
|
||||
close(startup_pipes[i]);
|
||||
@ -955,10 +1023,7 @@ main(int ac, char **av)
|
||||
close_listen_socks();
|
||||
sock_in = newsock;
|
||||
sock_out = newsock;
|
||||
log_init(av0,
|
||||
options.log_level,
|
||||
options.log_facility,
|
||||
log_stderr, 0, 0);
|
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1024,7 +1089,7 @@ main(int ac, char **av)
|
||||
{
|
||||
struct request_info req;
|
||||
|
||||
request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL);
|
||||
request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, NULL);
|
||||
fromhost(&req);
|
||||
|
||||
if (!hosts_access(&req)) {
|
||||
@ -1052,16 +1117,17 @@ main(int ac, char **av)
|
||||
|
||||
sshd_exchange_identification(sock_in, sock_out);
|
||||
/*
|
||||
* Check that the connection comes from a privileged port. Rhosts-
|
||||
* and Rhosts-RSA-Authentication only make sense from priviledged
|
||||
* Check that the connection comes from a privileged port.
|
||||
* Rhosts-Authentication only makes sense from priviledged
|
||||
* programs. Of course, if the intruder has root access on his local
|
||||
* machine, he can connect from any port. So do not use these
|
||||
* authentication methods from machines that you do not trust.
|
||||
*/
|
||||
if (remote_port >= IPPORT_RESERVED ||
|
||||
remote_port < IPPORT_RESERVED / 2) {
|
||||
debug("Rhosts Authentication disabled, "
|
||||
"originating port not trusted.");
|
||||
options.rhosts_authentication = 0;
|
||||
options.rhosts_rsa_authentication = 0;
|
||||
}
|
||||
#ifdef KRB4
|
||||
if (!packet_connection_is_ipv4() &&
|
||||
@ -1111,14 +1177,14 @@ main(int ac, char **av)
|
||||
* SSH1 key exchange
|
||||
*/
|
||||
void
|
||||
do_ssh1_kex()
|
||||
do_ssh1_kex(void)
|
||||
{
|
||||
int i, len;
|
||||
int plen, slen;
|
||||
BIGNUM *session_key_int;
|
||||
unsigned char session_key[SSH_SESSION_KEY_LENGTH];
|
||||
unsigned char cookie[8];
|
||||
unsigned int cipher_type, auth_mask, protocol_flags;
|
||||
u_char session_key[SSH_SESSION_KEY_LENGTH];
|
||||
u_char cookie[8];
|
||||
u_int cipher_type, auth_mask, protocol_flags;
|
||||
u_int32_t rand = 0;
|
||||
|
||||
/*
|
||||
@ -1149,20 +1215,20 @@ do_ssh1_kex()
|
||||
packet_put_char(cookie[i]);
|
||||
|
||||
/* Store our public server RSA key. */
|
||||
packet_put_int(BN_num_bits(public_key->n));
|
||||
packet_put_bignum(public_key->e);
|
||||
packet_put_bignum(public_key->n);
|
||||
packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n));
|
||||
packet_put_bignum(sensitive_data.server_key->rsa->e);
|
||||
packet_put_bignum(sensitive_data.server_key->rsa->n);
|
||||
|
||||
/* Store our public host RSA key. */
|
||||
packet_put_int(BN_num_bits(sensitive_data.host_key->n));
|
||||
packet_put_bignum(sensitive_data.host_key->e);
|
||||
packet_put_bignum(sensitive_data.host_key->n);
|
||||
packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n));
|
||||
packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e);
|
||||
packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n);
|
||||
|
||||
/* Put protocol flags. */
|
||||
packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
|
||||
|
||||
/* Declare which ciphers we support. */
|
||||
packet_put_int(cipher_mask1());
|
||||
packet_put_int(cipher_mask_ssh1(0));
|
||||
|
||||
/* Declare supported authentication types. */
|
||||
auth_mask = 0;
|
||||
@ -1185,7 +1251,7 @@ do_ssh1_kex()
|
||||
auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
if (options.skey_authentication)
|
||||
if (options.skey_authentication == 1)
|
||||
auth_mask |= 1 << SSH_AUTH_TIS;
|
||||
#endif
|
||||
if (options.password_authentication)
|
||||
@ -1196,9 +1262,9 @@ do_ssh1_kex()
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
debug("Sent %d bit public key and %d bit host key.",
|
||||
BN_num_bits(public_key->n),
|
||||
BN_num_bits(sensitive_data.host_key->n));
|
||||
debug("Sent %d bit server key and %d bit host key.",
|
||||
BN_num_bits(sensitive_data.server_key->rsa->n),
|
||||
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n));
|
||||
|
||||
/* Read clients reply (cipher type and session key). */
|
||||
packet_read_expect(&plen, SSH_CMSG_SESSION_KEY);
|
||||
@ -1206,7 +1272,7 @@ do_ssh1_kex()
|
||||
/* Get cipher type and check whether we accept this. */
|
||||
cipher_type = packet_get_char();
|
||||
|
||||
if (!(cipher_mask() & (1 << cipher_type)))
|
||||
if (!(cipher_mask_ssh1(0) & (1 << cipher_type)))
|
||||
packet_disconnect("Warning: client selects unsupported cipher.");
|
||||
|
||||
/* Get check bytes from the packet. These must match those we
|
||||
@ -1230,42 +1296,39 @@ do_ssh1_kex()
|
||||
* Decrypt it using our private server key and private host key (key
|
||||
* with larger modulus first).
|
||||
*/
|
||||
if (BN_cmp(sensitive_data.private_key->n,
|
||||
sensitive_data.host_key->n) > 0) {
|
||||
if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) {
|
||||
/* Private key has bigger modulus. */
|
||||
if (BN_num_bits(sensitive_data.private_key->n) <
|
||||
BN_num_bits(sensitive_data.host_key->n) +
|
||||
SSH_KEY_BITS_RESERVED) {
|
||||
fatal("do_connection: %s: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
|
||||
get_remote_ipaddr(),
|
||||
BN_num_bits(sensitive_data.private_key->n),
|
||||
BN_num_bits(sensitive_data.host_key->n),
|
||||
SSH_KEY_BITS_RESERVED);
|
||||
if (BN_num_bits(sensitive_data.server_key->rsa->n) <
|
||||
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
|
||||
fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
|
||||
get_remote_ipaddr(),
|
||||
BN_num_bits(sensitive_data.server_key->rsa->n),
|
||||
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
|
||||
SSH_KEY_BITS_RESERVED);
|
||||
}
|
||||
rsa_private_decrypt(session_key_int, session_key_int,
|
||||
sensitive_data.private_key);
|
||||
sensitive_data.server_key->rsa);
|
||||
rsa_private_decrypt(session_key_int, session_key_int,
|
||||
sensitive_data.host_key);
|
||||
sensitive_data.ssh1_host_key->rsa);
|
||||
} else {
|
||||
/* Host key has bigger modulus (or they are equal). */
|
||||
if (BN_num_bits(sensitive_data.host_key->n) <
|
||||
BN_num_bits(sensitive_data.private_key->n) +
|
||||
SSH_KEY_BITS_RESERVED) {
|
||||
fatal("do_connection: %s: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d",
|
||||
get_remote_ipaddr(),
|
||||
BN_num_bits(sensitive_data.host_key->n),
|
||||
BN_num_bits(sensitive_data.private_key->n),
|
||||
SSH_KEY_BITS_RESERVED);
|
||||
if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) <
|
||||
BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
|
||||
fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d",
|
||||
get_remote_ipaddr(),
|
||||
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
|
||||
BN_num_bits(sensitive_data.server_key->rsa->n),
|
||||
SSH_KEY_BITS_RESERVED);
|
||||
}
|
||||
rsa_private_decrypt(session_key_int, session_key_int,
|
||||
sensitive_data.host_key);
|
||||
sensitive_data.ssh1_host_key->rsa);
|
||||
rsa_private_decrypt(session_key_int, session_key_int,
|
||||
sensitive_data.private_key);
|
||||
sensitive_data.server_key->rsa);
|
||||
}
|
||||
|
||||
compute_session_id(session_id, cookie,
|
||||
sensitive_data.host_key->n,
|
||||
sensitive_data.private_key->n);
|
||||
sensitive_data.ssh1_host_key->rsa->n,
|
||||
sensitive_data.server_key->rsa->n);
|
||||
|
||||
/* Destroy the private and public keys. They will no longer be needed. */
|
||||
destroy_sensitive_data();
|
||||
@ -1279,8 +1342,8 @@ do_ssh1_kex()
|
||||
len = BN_num_bytes(session_key_int);
|
||||
if (len < 0 || len > sizeof(session_key))
|
||||
fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d",
|
||||
get_remote_ipaddr(),
|
||||
len, (int)sizeof(session_key));
|
||||
get_remote_ipaddr(),
|
||||
len, sizeof(session_key));
|
||||
memset(session_key, 0, sizeof(session_key));
|
||||
BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len);
|
||||
|
||||
@ -1309,22 +1372,12 @@ do_ssh1_kex()
|
||||
* SSH2 key exchange: diffie-hellman-group1-sha1
|
||||
*/
|
||||
void
|
||||
do_ssh2_kex()
|
||||
do_ssh2_kex(void)
|
||||
{
|
||||
Buffer *server_kexinit;
|
||||
Buffer *client_kexinit;
|
||||
int payload_len, dlen;
|
||||
int slen;
|
||||
unsigned int klen, kout;
|
||||
unsigned char *signature = NULL;
|
||||
unsigned char *server_host_key_blob = NULL;
|
||||
unsigned int sbloblen;
|
||||
DH *dh;
|
||||
BIGNUM *dh_client_pub = 0;
|
||||
BIGNUM *shared_secret = 0;
|
||||
int payload_len;
|
||||
int i;
|
||||
unsigned char *kbuf;
|
||||
unsigned char *hash;
|
||||
Kex *kex;
|
||||
char *cprop[PROPOSAL_MAX];
|
||||
|
||||
@ -1334,6 +1387,8 @@ do_ssh2_kex()
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
|
||||
}
|
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
|
||||
|
||||
server_kexinit = kex_init(myproposal);
|
||||
client_kexinit = xmalloc(sizeof(*client_kexinit));
|
||||
buffer_init(client_kexinit);
|
||||
@ -1344,7 +1399,71 @@ do_ssh2_kex()
|
||||
for (i = 0; i < PROPOSAL_MAX; i++)
|
||||
xfree(cprop[i]);
|
||||
|
||||
switch (kex->kex_type) {
|
||||
case DH_GRP1_SHA1:
|
||||
ssh_dh1_server(kex, client_kexinit, server_kexinit);
|
||||
break;
|
||||
case DH_GEX_SHA1:
|
||||
ssh_dhgex_server(kex, client_kexinit, server_kexinit);
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported key exchange %d", kex->kex_type);
|
||||
}
|
||||
|
||||
debug("send SSH2_MSG_NEWKEYS.");
|
||||
packet_start(SSH2_MSG_NEWKEYS);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
debug("done: send SSH2_MSG_NEWKEYS.");
|
||||
|
||||
debug("Wait SSH2_MSG_NEWKEYS.");
|
||||
packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
|
||||
debug("GOT SSH2_MSG_NEWKEYS.");
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
/* send 1st encrypted/maced/compressed message */
|
||||
packet_start(SSH2_MSG_IGNORE);
|
||||
packet_put_cstring("markus");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
#endif
|
||||
|
||||
debug("done: KEX2.");
|
||||
}
|
||||
|
||||
/*
|
||||
* SSH2 key exchange
|
||||
*/
|
||||
|
||||
/* diffie-hellman-group1-sha1 */
|
||||
|
||||
void
|
||||
ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
|
||||
{
|
||||
#ifdef DEBUG_KEXDH
|
||||
int i;
|
||||
#endif
|
||||
int payload_len, dlen;
|
||||
int slen;
|
||||
u_char *signature = NULL;
|
||||
u_char *server_host_key_blob = NULL;
|
||||
u_int sbloblen;
|
||||
u_int klen, kout;
|
||||
u_char *kbuf;
|
||||
u_char *hash;
|
||||
BIGNUM *shared_secret = 0;
|
||||
DH *dh;
|
||||
BIGNUM *dh_client_pub = 0;
|
||||
Key *hostkey;
|
||||
|
||||
hostkey = get_hostkey_by_type(kex->hostkey_type);
|
||||
if (hostkey == NULL)
|
||||
fatal("Unsupported hostkey type %d", kex->hostkey_type);
|
||||
|
||||
/* KEXDH */
|
||||
/* generate DH key */
|
||||
dh = dh_new_group1(); /* XXX depends on 'kex' */
|
||||
dh_gen_key(dh);
|
||||
|
||||
debug("Wait SSH2_MSG_KEXDH_INIT.");
|
||||
packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT);
|
||||
@ -1362,9 +1481,6 @@ do_ssh2_kex()
|
||||
debug("bits %d", BN_num_bits(dh_client_pub));
|
||||
#endif
|
||||
|
||||
/* generate DH key */
|
||||
dh = dh_new_group1(); /* XXX depends on 'kex' */
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "\np= ");
|
||||
BN_print_fp(stderr, dh->p);
|
||||
@ -1396,7 +1512,7 @@ do_ssh2_kex()
|
||||
xfree(kbuf);
|
||||
|
||||
/* XXX precompute? */
|
||||
dsa_make_key_blob(sensitive_data.dsa_host_key, &server_host_key_blob, &sbloblen);
|
||||
key_to_blob(hostkey, &server_host_key_blob, &sbloblen);
|
||||
|
||||
/* calc H */ /* XXX depends on 'kex' */
|
||||
hash = kex_hash(
|
||||
@ -1427,7 +1543,7 @@ do_ssh2_kex()
|
||||
|
||||
/* sign H */
|
||||
/* XXX hashlen depends on KEX */
|
||||
dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20);
|
||||
key_sign(hostkey, &signature, &slen, hash, 20);
|
||||
|
||||
destroy_sensitive_data();
|
||||
|
||||
@ -1446,23 +1562,146 @@ do_ssh2_kex()
|
||||
|
||||
/* have keys, free DH */
|
||||
DH_free(dh);
|
||||
}
|
||||
|
||||
debug("send SSH2_MSG_NEWKEYS.");
|
||||
packet_start(SSH2_MSG_NEWKEYS);
|
||||
/* diffie-hellman-group-exchange-sha1 */
|
||||
|
||||
void
|
||||
ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
|
||||
{
|
||||
#ifdef DEBUG_KEXDH
|
||||
int i;
|
||||
#endif
|
||||
int payload_len, dlen;
|
||||
int slen, nbits;
|
||||
u_char *signature = NULL;
|
||||
u_char *server_host_key_blob = NULL;
|
||||
u_int sbloblen;
|
||||
u_int klen, kout;
|
||||
u_char *kbuf;
|
||||
u_char *hash;
|
||||
BIGNUM *shared_secret = 0;
|
||||
DH *dh;
|
||||
BIGNUM *dh_client_pub = 0;
|
||||
Key *hostkey;
|
||||
|
||||
hostkey = get_hostkey_by_type(kex->hostkey_type);
|
||||
if (hostkey == NULL)
|
||||
fatal("Unsupported hostkey type %d", kex->hostkey_type);
|
||||
|
||||
/* KEXDHGEX */
|
||||
debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST.");
|
||||
packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_REQUEST);
|
||||
nbits = packet_get_int();
|
||||
dh = choose_dh(nbits);
|
||||
|
||||
debug("Sending SSH2_MSG_KEX_DH_GEX_GROUP.");
|
||||
packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
|
||||
packet_put_bignum2(dh->p);
|
||||
packet_put_bignum2(dh->g);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
debug("done: send SSH2_MSG_NEWKEYS.");
|
||||
|
||||
debug("Wait SSH2_MSG_NEWKEYS.");
|
||||
packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
|
||||
debug("GOT SSH2_MSG_NEWKEYS.");
|
||||
/* Compute our exchange value in parallel with the client */
|
||||
|
||||
dh_gen_key(dh);
|
||||
|
||||
debug("Wait SSH2_MSG_KEX_DH_GEX_INIT.");
|
||||
packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_INIT);
|
||||
|
||||
/* key, cert */
|
||||
dh_client_pub = BN_new();
|
||||
if (dh_client_pub == NULL)
|
||||
fatal("dh_client_pub == NULL");
|
||||
packet_get_bignum2(dh_client_pub, &dlen);
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
/* send 1st encrypted/maced/compressed message */
|
||||
packet_start(SSH2_MSG_IGNORE);
|
||||
packet_put_cstring("markus");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
fprintf(stderr, "\ndh_client_pub= ");
|
||||
BN_print_fp(stderr, dh_client_pub);
|
||||
fprintf(stderr, "\n");
|
||||
debug("bits %d", BN_num_bits(dh_client_pub));
|
||||
#endif
|
||||
debug("done: KEX2.");
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "\np= ");
|
||||
BN_print_fp(stderr, dh->p);
|
||||
fprintf(stderr, "\ng= ");
|
||||
bn_print(dh->g);
|
||||
fprintf(stderr, "\npub= ");
|
||||
BN_print_fp(stderr, dh->pub_key);
|
||||
fprintf(stderr, "\n");
|
||||
DHparams_print_fp(stderr, dh);
|
||||
#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
|
||||
debug("shared secret: len %d/%d", klen, kout);
|
||||
fprintf(stderr, "shared secret == ");
|
||||
for (i = 0; i< kout; i++)
|
||||
fprintf(stderr, "%02x", (kbuf[i])&0xff);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
shared_secret = BN_new();
|
||||
|
||||
BN_bin2bn(kbuf, kout, shared_secret);
|
||||
memset(kbuf, 0, klen);
|
||||
xfree(kbuf);
|
||||
|
||||
/* XXX precompute? */
|
||||
key_to_blob(hostkey, &server_host_key_blob, &sbloblen);
|
||||
|
||||
/* calc H */ /* XXX depends on 'kex' */
|
||||
hash = kex_hash_gex(
|
||||
client_version_string,
|
||||
server_version_string,
|
||||
buffer_ptr(client_kexinit), buffer_len(client_kexinit),
|
||||
buffer_ptr(server_kexinit), buffer_len(server_kexinit),
|
||||
(char *)server_host_key_blob, sbloblen,
|
||||
nbits, dh->p, dh->g,
|
||||
dh_client_pub,
|
||||
dh->pub_key,
|
||||
shared_secret
|
||||
);
|
||||
buffer_free(client_kexinit);
|
||||
buffer_free(server_kexinit);
|
||||
xfree(client_kexinit);
|
||||
xfree(server_kexinit);
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "hash == ");
|
||||
for (i = 0; i< 20; i++)
|
||||
fprintf(stderr, "%02x", (hash[i])&0xff);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
/* save session id := H */
|
||||
/* XXX hashlen depends on KEX */
|
||||
session_id2_len = 20;
|
||||
session_id2 = xmalloc(session_id2_len);
|
||||
memcpy(session_id2, hash, session_id2_len);
|
||||
|
||||
/* sign H */
|
||||
/* XXX hashlen depends on KEX */
|
||||
key_sign(hostkey, &signature, &slen, hash, 20);
|
||||
|
||||
destroy_sensitive_data();
|
||||
|
||||
/* send server hostkey, DH pubkey 'f' and singed H */
|
||||
packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
|
||||
packet_put_string((char *)server_host_key_blob, sbloblen);
|
||||
packet_put_bignum2(dh->pub_key); /* f */
|
||||
packet_put_string((char *)signature, slen);
|
||||
packet_send();
|
||||
xfree(signature);
|
||||
xfree(server_host_key_blob);
|
||||
packet_write_wait();
|
||||
|
||||
kex_derive_keys(kex, hash, shared_secret);
|
||||
packet_set_kex(kex);
|
||||
|
||||
/* have keys, free DH */
|
||||
DH_free(dh);
|
||||
}
|
||||
|
8
crypto/dist/ssh/tildexpand.c
vendored
8
crypto/dist/ssh/tildexpand.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tildexpand.c,v 1.1.1.1 2000/09/28 22:10:42 thorpej Exp $ */
|
||||
/* $NetBSD: tildexpand.c,v 1.1.1.2 2001/01/14 04:51:03 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -12,11 +12,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: tildexpand.c,v 1.8 2000/09/07 20:27:55 deraadt Exp */
|
||||
/* from OpenBSD: tildexpand.c,v 1.9 2000/12/19 23:17:59 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: tildexpand.c,v 1.1.1.1 2000/09/28 22:10:42 thorpej Exp $");
|
||||
__RCSID("$NetBSD: tildexpand.c,v 1.1.1.2 2001/01/14 04:51:03 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -32,7 +32,7 @@ char *
|
||||
tilde_expand_filename(const char *filename, uid_t my_uid)
|
||||
{
|
||||
const char *cp;
|
||||
unsigned int userlen;
|
||||
u_int userlen;
|
||||
char *expanded;
|
||||
struct passwd *pw;
|
||||
char user[100];
|
||||
|
15
crypto/dist/ssh/uidswap.c
vendored
15
crypto/dist/ssh/uidswap.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: uidswap.c,v 1.1.1.1 2000/09/28 22:10:43 thorpej Exp $ */
|
||||
/* $NetBSD: uidswap.c,v 1.1.1.2 2001/01/14 04:51:04 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -13,11 +13,11 @@
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* from OpenBSD: uidswap.c,v 1.9 2000/09/07 20:27:55 deraadt Exp */
|
||||
/* from OpenBSD: uidswap.c,v 1.12 2000/12/29 10:48:56 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: uidswap.c,v 1.1.1.1 2000/09/28 22:10:43 thorpej Exp $");
|
||||
__RCSID("$NetBSD: uidswap.c,v 1.1.1.2 2001/01/14 04:51:04 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -38,12 +38,9 @@ __RCSID("$NetBSD: uidswap.c,v 1.1.1.1 2000/09/28 22:10:43 thorpej Exp $");
|
||||
/* Lets assume that posix saved ids also work with seteuid, even though that
|
||||
is not part of the posix specification. */
|
||||
#define SAVED_IDS_WORK_WITH_SETEUID
|
||||
#endif /* _POSIX_SAVED_IDS */
|
||||
|
||||
#ifdef SAVED_IDS_WORK_WITH_SETEUID
|
||||
/* Saved effective uid. */
|
||||
static uid_t saved_euid = 0;
|
||||
#endif
|
||||
#endif /* _POSIX_SAVED_IDS */
|
||||
|
||||
/*
|
||||
* Temporarily changes to the given uid. If the effective user
|
||||
@ -59,7 +56,7 @@ temporarily_use_uid(uid_t uid)
|
||||
/* Set the effective uid to the given (unprivileged) uid. */
|
||||
if (seteuid(uid) == -1)
|
||||
debug("seteuid %u: %.100s", (u_int) uid, strerror(errno));
|
||||
#else /* SAVED_IDS_WORK_WITH_SETUID */
|
||||
#else /* SAVED_IDS_WORK_WITH_SETEUID */
|
||||
/* Propagate the privileged uid to all of our uids. */
|
||||
if (setuid(geteuid()) < 0)
|
||||
debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno));
|
||||
@ -74,7 +71,7 @@ temporarily_use_uid(uid_t uid)
|
||||
* Restores to the original uid.
|
||||
*/
|
||||
void
|
||||
restore_uid()
|
||||
restore_uid(void)
|
||||
{
|
||||
#ifdef SAVED_IDS_WORK_WITH_SETEUID
|
||||
/* Set the effective uid back to the saved uid. */
|
||||
|
16
crypto/dist/ssh/util.c
vendored
16
crypto/dist/ssh/util.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: util.c,v 1.1.1.1 2000/09/28 22:10:43 thorpej Exp $ */
|
||||
/* $NetBSD: util.c,v 1.1.1.2 2001/01/14 04:50:05 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -24,14 +24,15 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: util.c,v 1.5 2000/09/07 20:27:55 deraadt Exp */
|
||||
/* from OpenBSD: util.c,v 1.6 2000/10/27 07:32:19 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: util.c,v 1.1.1.1 2000/09/28 22:10:43 thorpej Exp $");
|
||||
__RCSID("$NetBSD: util.c,v 1.1.1.2 2001/01/14 04:50:05 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "ssh.h"
|
||||
|
||||
char *
|
||||
@ -53,18 +54,15 @@ void
|
||||
set_nonblock(int fd)
|
||||
{
|
||||
int val;
|
||||
if (isatty(fd)) {
|
||||
/* do not mess with tty's */
|
||||
debug("no set_nonblock for tty fd %d", fd);
|
||||
return;
|
||||
}
|
||||
val = fcntl(fd, F_GETFL, 0);
|
||||
if (val < 0) {
|
||||
error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (val & O_NONBLOCK)
|
||||
if (val & O_NONBLOCK) {
|
||||
debug("fd %d IS O_NONBLOCK", fd);
|
||||
return;
|
||||
}
|
||||
debug("fd %d setting O_NONBLOCK", fd);
|
||||
val |= O_NONBLOCK;
|
||||
if (fcntl(fd, F_SETFL, val) == -1)
|
||||
|
14
crypto/dist/ssh/uuencode.c
vendored
14
crypto/dist/ssh/uuencode.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: uuencode.c,v 1.1.1.1 2000/09/28 22:10:45 thorpej Exp $ */
|
||||
/* $NetBSD: uuencode.c,v 1.1.1.2 2001/01/14 04:51:05 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -24,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* from OpenBSD: uuencode.c,v 1.7 2000/09/07 20:27:55 deraadt Exp */
|
||||
/* from OpenBSD: uuencode.c,v 1.8 2000/12/19 23:17:59 markus Exp */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: uuencode.c,v 1.1.1.1 2000/09/28 22:10:45 thorpej Exp $");
|
||||
__RCSID("$NetBSD: uuencode.c,v 1.1.1.2 2001/01/14 04:51:05 itojun Exp $");
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
@ -38,14 +38,14 @@ __RCSID("$NetBSD: uuencode.c,v 1.1.1.1 2000/09/28 22:10:45 thorpej Exp $");
|
||||
#include <resolv.h>
|
||||
|
||||
int
|
||||
uuencode(unsigned char *src, unsigned int srclength,
|
||||
uuencode(u_char *src, u_int srclength,
|
||||
char *target, size_t targsize)
|
||||
{
|
||||
return __b64_ntop(src, srclength, target, targsize);
|
||||
}
|
||||
|
||||
int
|
||||
uudecode(const char *src, unsigned char *target, size_t targsize)
|
||||
uudecode(const char *src, u_char *target, size_t targsize)
|
||||
{
|
||||
int len;
|
||||
char *encoded, *p;
|
||||
@ -65,9 +65,9 @@ uudecode(const char *src, unsigned char *target, size_t targsize)
|
||||
}
|
||||
|
||||
void
|
||||
dump_base64(FILE *fp, unsigned char *data, int len)
|
||||
dump_base64(FILE *fp, u_char *data, int len)
|
||||
{
|
||||
unsigned char *buf = xmalloc(2*len);
|
||||
u_char *buf = xmalloc(2*len);
|
||||
int i, n;
|
||||
n = uuencode(data, len, buf, 2*len);
|
||||
for (i = 0; i < n; i++) {
|
||||
|
8
crypto/dist/ssh/uuencode.h
vendored
8
crypto/dist/ssh/uuencode.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: uuencode.h,v 1.1.1.1 2000/09/28 22:10:45 thorpej Exp $ */
|
||||
/* $NetBSD: uuencode.h,v 1.1.1.2 2001/01/14 04:51:05 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
#ifndef UUENCODE_H
|
||||
#define UUENCODE_H
|
||||
int uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize);
|
||||
int uudecode(const char *src, unsigned char *target, size_t targsize);
|
||||
void dump_base64(FILE *fp, unsigned char *data, int len);
|
||||
int uuencode(u_char *src, u_int srclength, char *target, size_t targsize);
|
||||
int uudecode(const char *src, u_char *target, size_t targsize);
|
||||
void dump_base64(FILE *fp, u_char *data, int len);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user