NetBSD Secure Shell, based on OpenSSH 2.3.0 around 1/5/2001

This commit is contained in:
itojun 2001-01-14 04:49:51 +00:00
parent 6f0dfa5049
commit bfbf0e0d31
82 changed files with 4988 additions and 1522 deletions

View File

@ -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"

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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"

View File

@ -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
View 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);
}
}

View File

@ -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;
}

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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;
}
/*

View File

@ -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 */

View File

@ -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]);

View File

@ -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);

View File

@ -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

View File

@ -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
View 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
View 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 */

View File

@ -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(&reg, check[i].pat, REG_EXTENDED|REG_NOSUB);
if (ret != 0) {
regerror(ret, &reg, ebuf, sizeof(ebuf));
ebuf[sizeof(ebuf)-1] = '\0';
error("regerror: %s", ebuf);
continue;
}
ret = regexec(&reg, version, 0, NULL, 0);
regfree(&reg);
if (ret == 0) {
debug("match: %s pat %s", version, check[i].pat);
datafellows = check[i].bugs;
return;
}
}
debug("no match: %s", version);
}
#define SEP ","

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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 ++) {

View File

@ -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 */

View File

@ -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
View 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
View 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

View File

@ -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); \

View File

@ -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");

View File

@ -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

View File

@ -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. */

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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 },

View File

@ -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;

View File

@ -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;) {

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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 ""

View File

@ -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);

View File

@ -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

View File

@ -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
View File

@ -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));
}
}
}

View File

@ -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);

View File

@ -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 */
}

View File

@ -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;

View File

@ -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
View 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
View 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
View File

@ -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
View File

@ -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));

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 .

View File

@ -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

View File

@ -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
View 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
View 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

View File

@ -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
View 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
View 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
View 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
View 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

View File

@ -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

View File

@ -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);
}
/*

View File

@ -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. */

View File

@ -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
View File

@ -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);
}

View File

@ -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];

View File

@ -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. */

View File

@ -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)

View File

@ -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++) {

View File

@ -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