1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

This commit was generated by cvs2svn to compensate for changes in r69587,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Brian Feldman 2000-12-05 02:20:19 +00:00
commit 803a607983
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=69588
45 changed files with 2420 additions and 661 deletions

View File

@ -36,7 +36,7 @@ OpenSSH contains no GPL code.
- The make-ssh-known-hosts script is no longer included - The make-ssh-known-hosts script is no longer included
- TSS has been removed - TSS has been removed
- MD5 is now external, in the OpenSSL library - MD5 is now external, in the OpenSSL library
- RC4 support has been removed - RC4 support has been replaced with ARC4 support from OpenSSL
- Blowfish is now external, in the OpenSSL library - Blowfish is now external, in the OpenSSL library
[The licence continues] [The licence continues]

View File

@ -1,5 +1,7 @@
CFLAGS+= -I${.CURDIR}/.. CFLAGS+= -I${.CURDIR}/..
CFLAGS+= -Wall
.include <bsd.obj.mk> .include <bsd.obj.mk>
.if exists(${.CURDIR}/../lib/${__objdir}) .if exists(${.CURDIR}/../lib/${__objdir})

View File

@ -1,6 +1,6 @@
.\" -*- nroff -*- .\" -*- nroff -*-
.\" .\"
.\" $Id: RFC.nroff,v 1.1 1999/09/26 20:53:32 deraadt Exp $ .\" $OpenBSD: RFC.nroff,v 1.2 2000/10/16 09:38:44 djm Exp $
.\" .\"
.pl 10.0i .pl 10.0i
.po 0 .po 0

View File

@ -24,7 +24,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: atomicio.c,v 1.5 2000/09/07 20:27:49 deraadt Exp $"); RCSID("$OpenBSD: atomicio.c,v 1.7 2000/10/18 18:04:02 markus Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "ssh.h" #include "ssh.h"

View File

@ -14,7 +14,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: auth-options.c,v 1.4 2000/09/07 21:13:36 markus Exp $"); RCSID("$OpenBSD: auth-options.c,v 1.5 2000/10/09 21:32:34 markus Exp $");
#include "ssh.h" #include "ssh.h"
#include "packet.h" #include "packet.h"
@ -33,6 +33,25 @@ char *forced_command = NULL;
/* "environment=" options. */ /* "environment=" options. */
struct envstring *custom_environment = NULL; 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 */ /* return 1 if access is granted, 0 if not. side effect: sets key option flags */
int int
auth_parse_options(struct passwd *pw, char *options, unsigned long linenum) auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
@ -40,6 +59,10 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
const char *cp; const char *cp;
if (!options) if (!options)
return 1; return 1;
/* reset options */
auth_clear_options();
while (*options && *options != ' ' && *options != '\t') { while (*options && *options != ' ' && *options != '\t') {
cp = "no-port-forwarding"; cp = "no-port-forwarding";
if (strncmp(options, cp, strlen(cp)) == 0) { if (strncmp(options, cp, strlen(cp)) == 0) {
@ -87,9 +110,9 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
} }
if (!*options) { if (!*options) {
debug("%.100s, line %lu: missing end quote", debug("%.100s, line %lu: missing end quote",
SSH_USER_PERMITTED_KEYS, linenum); SSH_USER_PERMITTED_KEYS, linenum);
packet_send_debug("%.100s, line %lu: missing end quote", packet_send_debug("%.100s, line %lu: missing end quote",
SSH_USER_PERMITTED_KEYS, linenum); SSH_USER_PERMITTED_KEYS, linenum);
continue; continue;
} }
forced_command[i] = 0; forced_command[i] = 0;
@ -117,9 +140,9 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
} }
if (!*options) { if (!*options) {
debug("%.100s, line %lu: missing end quote", debug("%.100s, line %lu: missing end quote",
SSH_USER_PERMITTED_KEYS, linenum); SSH_USER_PERMITTED_KEYS, linenum);
packet_send_debug("%.100s, line %lu: missing end quote", packet_send_debug("%.100s, line %lu: missing end quote",
SSH_USER_PERMITTED_KEYS, linenum); SSH_USER_PERMITTED_KEYS, linenum);
continue; continue;
} }
s[i] = 0; s[i] = 0;
@ -175,21 +198,6 @@ auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
get_remote_ipaddr()); get_remote_ipaddr());
packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
get_canonical_hostname()); 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 */ /* deny access */
return 0; return 0;
} }

View File

@ -10,6 +10,9 @@
* incompatible with the protocol description in the RFC file, it must be * incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell". * called by a name other than "ssh" or "Secure Shell".
*/ */
/* $OpenBSD: auth-options.h,v 1.5 2000/10/16 09:38:44 djm Exp $ */
#ifndef AUTH_OPTIONS_H #ifndef AUTH_OPTIONS_H
#define AUTH_OPTIONS_H #define AUTH_OPTIONS_H
/* Flags that may be set in authorized_keys options. */ /* Flags that may be set in authorized_keys options. */
@ -22,4 +25,7 @@ extern struct envstring *custom_environment;
/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ /* 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, unsigned long linenum);
/* reset options flags */
void auth_clear_options(void);
#endif #endif

View File

@ -14,7 +14,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: auth-rhosts.c,v 1.15 2000/09/07 20:27:49 deraadt Exp $"); RCSID("$OpenBSD: auth-rhosts.c,v 1.16 2000/10/03 18:03:03 markus Exp $");
#include "packet.h" #include "packet.h"
#include "ssh.h" #include "ssh.h"
@ -154,6 +154,9 @@ auth_rhosts(struct passwd *pw, const char *client_user)
static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; static const char *rhosts_files[] = {".shosts", ".rhosts", NULL};
unsigned int rhosts_file_index; unsigned int rhosts_file_index;
/* no user given */
if (pw == NULL)
return 0;
/* Switch to the user's uid. */ /* Switch to the user's uid. */
temporarily_use_uid(pw->pw_uid); temporarily_use_uid(pw->pw_uid);
/* /*

View File

@ -20,21 +20,35 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $OpenBSD: auth.h,v 1.7 2000/10/16 09:38:44 djm Exp $
*/ */
#ifndef AUTH_H #ifndef AUTH_H
#define AUTH_H #define AUTH_H
typedef struct Authctxt Authctxt;
struct Authctxt {
int success;
int valid;
int attempt;
char *user;
char *service;
struct passwd *pw;
};
void do_authentication(void); void do_authentication(void);
void do_authentication2(void); void do_authentication2(void);
struct passwd * void userauth_log(Authctxt *authctxt, int authenticated, char *method);
auth_get_user(void); void userauth_reply(Authctxt *authctxt, int authenticated);
int allowed_user(struct passwd * pw); int auth2_skey(Authctxt *authctxt);
int allowed_user(struct passwd * pw);
struct passwd * auth_get_user(void);
#define AUTH_FAIL_MAX 6 #define AUTH_FAIL_MAX 6
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" #define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
#endif #endif

104
crypto/openssh/auth2-skey.c Normal file
View File

@ -0,0 +1,104 @@
#include "includes.h"
RCSID("$OpenBSD: auth2-skey.c,v 1.1 2000/10/11 20:14:38 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);
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;
unsigned 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

@ -11,7 +11,7 @@
* called by a name other than "ssh" or "Secure Shell". * called by a name other than "ssh" or "Secure Shell".
*/ */
/* RCSID("$OpenBSD: authfd.h,v 1.11 2000/09/07 20:27:49 deraadt Exp $"); */ /* RCSID("$OpenBSD: authfd.h,v 1.13 2000/10/09 21:51:00 markus Exp $"); */
#ifndef AUTHFD_H #ifndef AUTHFD_H
#define AUTHFD_H #define AUTHFD_H
@ -29,6 +29,7 @@
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 #define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 #define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
/* private OpenSSH extensions for SSH2 */
#define SSH2_AGENTC_REQUEST_IDENTITIES 11 #define SSH2_AGENTC_REQUEST_IDENTITIES 11
#define SSH2_AGENT_IDENTITIES_ANSWER 12 #define SSH2_AGENT_IDENTITIES_ANSWER 12
#define SSH2_AGENTC_SIGN_REQUEST 13 #define SSH2_AGENTC_SIGN_REQUEST 13
@ -37,6 +38,12 @@
#define SSH2_AGENTC_REMOVE_IDENTITY 18 #define SSH2_AGENTC_REMOVE_IDENTITY 18
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 #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
typedef struct { typedef struct {
int fd; int fd;
Buffer identities; Buffer identities;

View File

@ -10,9 +10,13 @@
* incompatible with the protocol description in the RFC file, it must be * incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell". * called by a name other than "ssh" or "Secure Shell".
*/ */
/* $OpenBSD: authfile.h,v 1.5 2000/10/16 09:38:44 djm Exp $ */
#ifndef AUTHFILE_H #ifndef AUTHFILE_H
#define AUTHFILE_H #define AUTHFILE_H
/* /*
* Saves the authentication (private) key in a file, encrypting it with * Saves the authentication (private) key in a file, encrypting it with
* passphrase. * passphrase.

View File

@ -40,7 +40,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: channels.c,v 1.68 2000/09/07 20:40:29 markus Exp $"); RCSID("$OpenBSD: channels.c,v 1.72 2000/10/27 07:48:22 markus Exp $");
#include "ssh.h" #include "ssh.h"
#include "packet.h" #include "packet.h"
@ -174,7 +174,8 @@ channel_lookup(int id)
*/ */
void void
channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage) channel_register_fds(Channel *c, int rfd, int wfd, int efd,
int extusage, int nonblock)
{ {
/* Update the maximum file descriptor value. */ /* Update the maximum file descriptor value. */
if (rfd > channel_max_fd_value) if (rfd > channel_max_fd_value)
@ -190,12 +191,16 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage)
c->sock = (rfd == wfd) ? rfd : -1; c->sock = (rfd == wfd) ? rfd : -1;
c->efd = efd; c->efd = efd;
c->extended_usage = extusage; c->extended_usage = extusage;
if (rfd != -1)
set_nonblock(rfd); /* enable nonblocking mode */
if (wfd != -1) if (nonblock) {
set_nonblock(wfd); if (rfd != -1)
if (efd != -1) set_nonblock(rfd);
set_nonblock(efd); if (wfd != -1)
set_nonblock(wfd);
if (efd != -1)
set_nonblock(efd);
}
} }
/* /*
@ -205,7 +210,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage)
int int
channel_new(char *ctype, int type, int rfd, int wfd, int efd, channel_new(char *ctype, int type, int rfd, int wfd, int efd,
int window, int maxpack, int extusage, char *remote_name) int window, int maxpack, int extusage, char *remote_name, int nonblock)
{ {
int i, found; int i, found;
Channel *c; Channel *c;
@ -234,7 +239,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
/* There are no free slots. Take last+1 slot and expand the array. */ /* There are no free slots. Take last+1 slot and expand the array. */
found = channels_alloc; found = channels_alloc;
channels_alloc += 10; channels_alloc += 10;
debug("channel: expanding %d", channels_alloc); debug2("channel: expanding %d", channels_alloc);
channels = xrealloc(channels, channels_alloc * sizeof(Channel)); channels = xrealloc(channels, channels_alloc * sizeof(Channel));
for (i = found; i < channels_alloc; i++) for (i = found; i < channels_alloc; i++)
channels[i].type = SSH_CHANNEL_FREE; channels[i].type = SSH_CHANNEL_FREE;
@ -245,7 +250,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
buffer_init(&c->output); buffer_init(&c->output);
buffer_init(&c->extended); buffer_init(&c->extended);
chan_init_iostates(c); chan_init_iostates(c);
channel_register_fds(c, rfd, wfd, efd, extusage); channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
c->self = found; c->self = found;
c->type = type; c->type = type;
c->ctype = ctype; c->ctype = ctype;
@ -269,7 +274,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
int int
channel_allocate(int type, int sock, char *remote_name) channel_allocate(int type, int sock, char *remote_name)
{ {
return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name, 1);
} }
@ -548,7 +553,7 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
newch = channel_new("x11", newch = channel_new("x11",
SSH_CHANNEL_OPENING, newsock, newsock, -1, SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket, c->local_window_max, c->local_maxpacket,
0, xstrdup(buf)); 0, xstrdup(buf), 1);
if (compat20) { if (compat20) {
packet_start(SSH2_MSG_CHANNEL_OPEN); packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring("x11"); packet_put_cstring("x11");
@ -606,7 +611,7 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
newch = channel_new("direct-tcpip", newch = channel_new("direct-tcpip",
SSH_CHANNEL_OPENING, newsock, newsock, -1, SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket, c->local_window_max, c->local_maxpacket,
0, xstrdup(buf)); 0, xstrdup(buf), 1);
if (compat20) { if (compat20) {
packet_start(SSH2_MSG_CHANNEL_OPEN); packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring("direct-tcpip"); packet_put_cstring("direct-tcpip");
@ -737,7 +742,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
buffer_len(&c->extended) > 0) { buffer_len(&c->extended) > 0) {
len = write(c->efd, buffer_ptr(&c->extended), len = write(c->efd, buffer_ptr(&c->extended),
buffer_len(&c->extended)); buffer_len(&c->extended));
debug("channel %d: written %d to efd %d", debug2("channel %d: written %d to efd %d",
c->self, len, c->efd); c->self, len, c->efd);
if (len > 0) { if (len > 0) {
buffer_consume(&c->extended, len); buffer_consume(&c->extended, len);
@ -746,7 +751,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
} else if (c->extended_usage == CHAN_EXTENDED_READ && } else if (c->extended_usage == CHAN_EXTENDED_READ &&
FD_ISSET(c->efd, readset)) { FD_ISSET(c->efd, readset)) {
len = read(c->efd, buf, sizeof(buf)); len = read(c->efd, buf, sizeof(buf));
debug("channel %d: read %d from efd %d", debug2("channel %d: read %d from efd %d",
c->self, len, c->efd); c->self, len, c->efd);
if (len == 0) { if (len == 0) {
debug("channel %d: closing efd %d", debug("channel %d: closing efd %d",
@ -769,7 +774,7 @@ channel_check_window(Channel *c, fd_set * readset, fd_set * writeset)
packet_put_int(c->remote_id); packet_put_int(c->remote_id);
packet_put_int(c->local_consumed); packet_put_int(c->local_consumed);
packet_send(); packet_send();
debug("channel %d: window %d sent adjust %d", debug2("channel %d: window %d sent adjust %d",
c->self, c->local_window, c->self, c->local_window,
c->local_consumed); c->local_consumed);
c->local_window += c->local_consumed; c->local_window += c->local_consumed;
@ -998,7 +1003,7 @@ channel_output_poll()
*/ */
void void
channel_input_data(int type, int plen) channel_input_data(int type, int plen, void *ctxt)
{ {
int id; int id;
char *data; char *data;
@ -1043,7 +1048,7 @@ channel_input_data(int type, int plen)
xfree(data); xfree(data);
} }
void void
channel_input_extended_data(int type, int plen) channel_input_extended_data(int type, int plen, void *ctxt)
{ {
int id; int id;
int tcode; int tcode;
@ -1076,7 +1081,7 @@ channel_input_extended_data(int type, int plen)
xfree(data); xfree(data);
return; return;
} }
debug("channel %d: rcvd ext data %d", c->self, data_len); debug2("channel %d: rcvd ext data %d", c->self, data_len);
c->local_window -= data_len; c->local_window -= data_len;
buffer_append(&c->extended, data, data_len); buffer_append(&c->extended, data, data_len);
xfree(data); xfree(data);
@ -1113,7 +1118,7 @@ channel_not_very_much_buffered_data()
} }
void void
channel_input_ieof(int type, int plen) channel_input_ieof(int type, int plen, void *ctxt)
{ {
int id; int id;
Channel *c; Channel *c;
@ -1128,7 +1133,7 @@ channel_input_ieof(int type, int plen)
} }
void void
channel_input_close(int type, int plen) channel_input_close(int type, int plen, void *ctxt)
{ {
int id; int id;
Channel *c; Channel *c;
@ -1167,7 +1172,7 @@ channel_input_close(int type, int plen)
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
void void
channel_input_oclose(int type, int plen) channel_input_oclose(int type, int plen, void *ctxt)
{ {
int id = packet_get_int(); int id = packet_get_int();
Channel *c = channel_lookup(id); Channel *c = channel_lookup(id);
@ -1178,7 +1183,7 @@ channel_input_oclose(int type, int plen)
} }
void void
channel_input_close_confirmation(int type, int plen) channel_input_close_confirmation(int type, int plen, void *ctxt)
{ {
int id = packet_get_int(); int id = packet_get_int();
Channel *c = channel_lookup(id); Channel *c = channel_lookup(id);
@ -1194,7 +1199,7 @@ channel_input_close_confirmation(int type, int plen)
} }
void void
channel_input_open_confirmation(int type, int plen) channel_input_open_confirmation(int type, int plen, void *ctxt)
{ {
int id, remote_id; int id, remote_id;
Channel *c; Channel *c;
@ -1218,9 +1223,9 @@ channel_input_open_confirmation(int type, int plen)
c->remote_maxpacket = packet_get_int(); c->remote_maxpacket = packet_get_int();
packet_done(); packet_done();
if (c->cb_fn != NULL && c->cb_event == type) { if (c->cb_fn != NULL && c->cb_event == type) {
debug("callback start"); debug2("callback start");
c->cb_fn(c->self, c->cb_arg); c->cb_fn(c->self, c->cb_arg);
debug("callback done"); debug2("callback done");
} }
debug("channel %d: open confirm rwindow %d rmax %d", c->self, debug("channel %d: open confirm rwindow %d rmax %d", c->self,
c->remote_window, c->remote_maxpacket); c->remote_window, c->remote_maxpacket);
@ -1228,7 +1233,7 @@ channel_input_open_confirmation(int type, int plen)
} }
void void
channel_input_open_failure(int type, int plen) channel_input_open_failure(int type, int plen, void *ctxt)
{ {
int id; int id;
Channel *c; Channel *c;
@ -1256,7 +1261,7 @@ channel_input_open_failure(int type, int plen)
} }
void void
channel_input_channel_request(int type, int plen) channel_input_channel_request(int type, int plen, void *ctxt)
{ {
int id; int id;
Channel *c; Channel *c;
@ -1269,19 +1274,19 @@ channel_input_channel_request(int type, int plen)
packet_disconnect("Received request for " packet_disconnect("Received request for "
"non-open channel %d.", id); "non-open channel %d.", id);
if (c->cb_fn != NULL && c->cb_event == type) { if (c->cb_fn != NULL && c->cb_event == type) {
debug("callback start"); debug2("callback start");
c->cb_fn(c->self, c->cb_arg); c->cb_fn(c->self, c->cb_arg);
debug("callback done"); debug2("callback done");
} else { } else {
char *service = packet_get_string(NULL); char *service = packet_get_string(NULL);
debug("channel: %d rcvd request for %s", c->self, service); debug("channel: %d rcvd request for %s", c->self, service);
debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event); debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event);
xfree(service); xfree(service);
} }
} }
void void
channel_input_window_adjust(int type, int plen) channel_input_window_adjust(int type, int plen, void *ctxt)
{ {
Channel *c; Channel *c;
int id, adjust; int id, adjust;
@ -1300,7 +1305,7 @@ channel_input_window_adjust(int type, int plen)
} }
adjust = packet_get_int(); adjust = packet_get_int();
packet_done(); packet_done();
debug("channel %d: rcvd adjust %d", id, adjust); debug2("channel %d: rcvd adjust %d", id, adjust);
c->remote_window += adjust; c->remote_window += adjust;
} }
@ -1510,7 +1515,7 @@ channel_request_local_forwarding(u_short port, const char *host,
"port listener", SSH_CHANNEL_PORT_LISTENER, "port listener", SSH_CHANNEL_PORT_LISTENER,
sock, sock, -1, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, xstrdup("port listener")); 0, xstrdup("port listener"), 1);
strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
channels[ch].host_port = host_port; channels[ch].host_port = host_port;
channels[ch].listening_port = port; channels[ch].listening_port = port;
@ -1652,7 +1657,7 @@ channel_connect_to(const char *host, u_short host_port)
*/ */
void void
channel_input_port_open(int type, int plen) channel_input_port_open(int type, int plen, void *ctxt)
{ {
u_short host_port; u_short host_port;
char *host, *originator_string; char *host, *originator_string;
@ -1800,7 +1805,7 @@ x11_create_display_inet(int screen_number, int x11_display_offset)
(void) channel_new("x11 listener", (void) channel_new("x11 listener",
SSH_CHANNEL_X11_LISTENER, sock, sock, -1, SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
0, xstrdup("X11 inet listener")); 0, xstrdup("X11 inet listener"), 1);
} }
/* Return a suitable value for the DISPLAY environment variable. */ /* Return a suitable value for the DISPLAY environment variable. */
@ -1942,7 +1947,7 @@ x11_connect_display(void)
*/ */
void void
x11_input_open(int type, int plen) x11_input_open(int type, int plen, void *ctxt)
{ {
int remote_channel, sock = 0, newch; int remote_channel, sock = 0, newch;
char *remote_host; char *remote_host;
@ -1986,6 +1991,28 @@ x11_input_open(int type, int plen)
} }
} }
/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
void
deny_input_open(int type, int plen, void *ctxt)
{
int rchan = packet_get_int();
switch(type){
case SSH_SMSG_AGENT_OPEN:
error("Warning: ssh server tried agent forwarding.");
break;
case SSH_SMSG_X11_OPEN:
error("Warning: ssh server tried X11 forwarding.");
break;
default:
error("deny_input_open: type %d plen %d", type, plen);
break;
}
error("Warning: this is probably a break in attempt by a malicious server.");
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(rchan);
packet_send();
}
/* /*
* Requests forwarding of X11 connections, generates fake authentication * Requests forwarding of X11 connections, generates fake authentication
* data, and enables authentication spoofing. * data, and enables authentication spoofing.
@ -2157,7 +2184,7 @@ auth_input_request_forwarding(struct passwd * pw)
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ /* This is called to process an SSH_SMSG_AGENT_OPEN message. */
void void
auth_input_open_request(int type, int plen) auth_input_open_request(int type, int plen, void *ctxt)
{ {
int remch, sock, newch; int remch, sock, newch;
char *dummyname; char *dummyname;
@ -2290,13 +2317,13 @@ channel_register_filter(int id, channel_filter_fn *fn)
} }
void void
channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) channel_set_fds(int id, int rfd, int wfd, int efd,
int extusage, int nonblock)
{ {
Channel *c = channel_lookup(id); Channel *c = channel_lookup(id);
if (c == NULL || c->type != SSH_CHANNEL_LARVAL) if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
fatal("channel_activate for non-larval channel %d.", id); fatal("channel_activate for non-larval channel %d.", id);
channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
channel_register_fds(c, rfd, wfd, efd, extusage);
c->type = SSH_CHANNEL_OPEN; c->type = SSH_CHANNEL_OPEN;
/* XXX window size? */ /* XXX window size? */
c->local_window = c->local_window_max = c->local_maxpacket * 2; c->local_window = c->local_window_max = c->local_maxpacket * 2;

View File

@ -32,7 +32,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/* RCSID("$OpenBSD: channels.h,v 1.19 2000/09/07 21:13:37 markus Exp $"); */ /* RCSID("$OpenBSD: channels.h,v 1.22 2000/10/27 07:48:22 markus Exp $"); */
#ifndef CHANNELS_H #ifndef CHANNELS_H
#define CHANNELS_H #define CHANNELS_H
@ -117,7 +117,6 @@ struct Channel {
#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) #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_open(int id);
void channel_request(int id, char *service, int wantconfirm); void channel_request(int id, char *service, int wantconfirm);
void channel_request_start(int id, char *service, int wantconfirm); void channel_request_start(int id, char *service, int wantconfirm);
@ -129,20 +128,26 @@ Channel *channel_lookup(int id);
int int
channel_new(char *ctype, int type, int rfd, int wfd, int efd, 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 channel_input_channel_request(int type, int plen); void deny_input_open(int type, int plen, void *ctxt);
void channel_input_close(int type, int plen);
void channel_input_close_confirmation(int type, int plen); void channel_input_channel_request(int type, int plen, void *ctxt);
void channel_input_data(int type, int plen); void channel_input_close(int type, int plen, void *ctxt);
void channel_input_extended_data(int type, int plen); void channel_input_close_confirmation(int type, int plen, void *ctxt);
void channel_input_ieof(int type, int plen); void channel_input_data(int type, int plen, void *ctxt);
void channel_input_oclose(int type, int plen); void channel_input_extended_data(int type, int plen, void *ctxt);
void channel_input_open_confirmation(int type, int plen); void channel_input_ieof(int type, int plen, void *ctxt);
void channel_input_open_failure(int type, int plen); void channel_input_oclose(int type, int plen, void *ctxt);
void channel_input_port_open(int type, int plen); void channel_input_open_confirmation(int type, int plen, void *ctxt);
void channel_input_window_adjust(int type, int plen); void channel_input_open_failure(int type, int plen, void *ctxt);
void channel_input_open(int type, int plen); 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. */ /* Sets specific protocol options. */
void channel_set_options(int hostname_in_open); void channel_set_options(int hostname_in_open);
@ -246,7 +251,7 @@ char *x11_create_display_inet(int screen, int x11_display_offset);
* the remote channel number. We should do whatever we want, and respond * the remote channel number. We should do whatever we want, and respond
* with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
*/ */
void x11_input_open(int type, int plen); void x11_input_open(int type, int plen, void *ctxt);
/* /*
* Requests forwarding of X11 connections. This should be called on the * Requests forwarding of X11 connections. This should be called on the
@ -279,7 +284,7 @@ char *auth_get_socket_name(void);
int auth_input_request_forwarding(struct passwd * pw); int auth_input_request_forwarding(struct passwd * pw);
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ /* This is called to process an SSH_SMSG_AGENT_OPEN message. */
void auth_input_open_request(int type, int plen); void auth_input_open_request(int type, int plen, void *ctxt);
/* XXX */ /* XXX */
int channel_connect_to(const char *host, u_short host_port); int channel_connect_to(const char *host, u_short host_port);

196
crypto/openssh/cli.c Normal file
View File

@ -0,0 +1,196 @@
#include "includes.h"
RCSID("$OpenBSD: cli.c,v 1.2 2000/10/16 09:38:44 djm Exp $");
#include "xmalloc.h"
#include "ssh.h"
#include <vis.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()
{
if (!cli_from_stdin && cli_input >= 0)
close(cli_input);
cli_input = -1;
cli_output = -1;
cli_from_stdin = 0;
return;
}
void
intrcatch()
{
intr = 1;
}
static void
cli_echo_disable()
{
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()
{
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/openssh/cli.h 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

@ -59,7 +59,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: clientloop.c,v 1.34 2000/09/07 20:40:30 markus Exp $"); RCSID("$OpenBSD: clientloop.c,v 1.39 2000/10/27 07:48:22 markus Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "ssh.h" #include "ssh.h"
@ -75,6 +75,8 @@ RCSID("$OpenBSD: clientloop.c,v 1.34 2000/09/07 20:40:30 markus Exp $");
#include "buffer.h" #include "buffer.h"
#include "bufaux.h" #include "bufaux.h"
/* import options */
extern Options options; extern Options options;
/* Flag indicating that stdin should be redirected from /dev/null. */ /* Flag indicating that stdin should be redirected from /dev/null. */
@ -335,7 +337,7 @@ client_check_window_change()
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
return; return;
debug("client_check_window_change: changed"); debug2("client_check_window_change: changed");
if (compat20) { if (compat20) {
channel_request_start(session_ident, "window-change", 0); channel_request_start(session_ident, "window-change", 0);
@ -362,8 +364,6 @@ client_check_window_change()
void void
client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
{ {
/*debug("client_wait_until_can_do_something"); */
/* Initialize select masks. */ /* Initialize select masks. */
FD_ZERO(readset); FD_ZERO(readset);
FD_ZERO(writeset); FD_ZERO(writeset);
@ -482,7 +482,6 @@ client_process_net_input(fd_set * readset)
if (FD_ISSET(connection_in, readset)) { if (FD_ISSET(connection_in, readset)) {
/* Read as much as possible. */ /* Read as much as possible. */
len = read(connection_in, buf, sizeof(buf)); len = read(connection_in, buf, sizeof(buf));
/*debug("read connection_in len %d", len); XXX */
if (len == 0) { if (len == 0) {
/* Received EOF. The remote host has closed the connection. */ /* Received EOF. The remote host has closed the connection. */
snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
@ -773,7 +772,7 @@ client_process_output(fd_set * writeset)
void void
client_process_buffered_input_packets() client_process_buffered_input_packets()
{ {
dispatch_run(DISPATCH_NONBLOCK, &quit_pending); dispatch_run(DISPATCH_NONBLOCK, &quit_pending, NULL);
} }
/* scan buf[] for '~' before sending data to the peer */ /* scan buf[] for '~' before sending data to the peer */
@ -853,7 +852,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
client_process_buffered_input_packets(); client_process_buffered_input_packets();
if (compat20 && !channel_still_open()) { if (compat20 && !channel_still_open()) {
debug("!channel_still_open."); debug2("!channel_still_open.");
break; break;
} }
@ -979,7 +978,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/*********/ /*********/
void void
client_input_stdout_data(int type, int plen) client_input_stdout_data(int type, int plen, void *ctxt)
{ {
unsigned int data_len; unsigned int data_len;
char *data = packet_get_string(&data_len); char *data = packet_get_string(&data_len);
@ -990,7 +989,7 @@ client_input_stdout_data(int type, int plen)
xfree(data); xfree(data);
} }
void void
client_input_stderr_data(int type, int plen) client_input_stderr_data(int type, int plen, void *ctxt)
{ {
unsigned int data_len; unsigned int data_len;
char *data = packet_get_string(&data_len); char *data = packet_get_string(&data_len);
@ -1001,7 +1000,7 @@ client_input_stderr_data(int type, int plen)
xfree(data); xfree(data);
} }
void void
client_input_exit_status(int type, int plen) client_input_exit_status(int type, int plen, void *ctxt)
{ {
packet_integrity_check(plen, 4, type); packet_integrity_check(plen, 4, type);
exit_status = packet_get_int(); exit_status = packet_get_int();
@ -1019,7 +1018,7 @@ client_input_exit_status(int type, int plen)
/* XXXX move to generic input handler */ /* XXXX move to generic input handler */
void void
client_input_channel_open(int type, int plen) client_input_channel_open(int type, int plen, void *ctxt)
{ {
Channel *c = NULL; Channel *c = NULL;
char *ctype; char *ctype;
@ -1043,7 +1042,7 @@ client_input_channel_open(int type, int plen)
int originator_port; int originator_port;
originator = packet_get_string(NULL); originator = packet_get_string(NULL);
if (datafellows & SSH_BUG_X11FWD) { if (datafellows & SSH_BUG_X11FWD) {
debug("buggy server: x11 request w/o originator_port"); debug2("buggy server: x11 request w/o originator_port");
originator_port = 0; originator_port = 0;
} else { } else {
originator_port = packet_get_int(); originator_port = packet_get_int();
@ -1056,7 +1055,7 @@ client_input_channel_open(int type, int plen)
if (sock >= 0) { if (sock >= 0) {
id = channel_new("x11", SSH_CHANNEL_X11_OPEN, id = channel_new("x11", SSH_CHANNEL_X11_OPEN,
sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT,
CHAN_X11_PACKET_DEFAULT, 0, xstrdup("x11")); CHAN_X11_PACKET_DEFAULT, 0, xstrdup("x11"), 1);
c = channel_lookup(id); c = channel_lookup(id);
} }
} }
@ -1114,9 +1113,9 @@ client_init_dispatch_13()
dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
&auth_input_open_request : NULL); &auth_input_open_request : &deny_input_open);
dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
&x11_input_open : NULL); &x11_input_open : &deny_input_open);
} }
void void
client_init_dispatch_15() client_init_dispatch_15()
@ -1152,7 +1151,7 @@ client_input_channel_req(int id, void *arg)
c = channel_lookup(id); c = channel_lookup(id);
if (c == NULL) if (c == NULL)
fatal("session_input_channel_req: channel %d: bad channel", id); fatal("client_input_channel_req: channel %d: bad channel", id);
if (session_ident == -1) { if (session_ident == -1) {
error("client_input_channel_req: no channel %d", id); error("client_input_channel_req: no channel %d", id);
@ -1176,7 +1175,7 @@ client_input_channel_req(int id, void *arg)
void void
client_set_session_ident(int id) client_set_session_ident(int id)
{ {
debug("client_set_session_ident: id %d", id); debug2("client_set_session_ident: id %d", id);
session_ident = id; session_ident = id;
channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST,
client_input_channel_req, (void *)0); client_input_channel_req, (void *)0);

View File

@ -23,12 +23,13 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: compat.c,v 1.23 2000/09/07 21:13:37 markus Exp $"); RCSID("$OpenBSD: compat.c,v 1.27 2000/10/31 09:31:58 markus Exp $");
#include "ssh.h" #include "ssh.h"
#include "packet.h" #include "packet.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "compat.h" #include "compat.h"
#include <regex.h>
int compat13 = 0; int compat13 = 0;
int compat20 = 0; int compat20 = 0;
@ -50,27 +51,46 @@ enable_compat13(void)
void void
compat_datafellows(const char *version) compat_datafellows(const char *version)
{ {
int i; int i, ret;
size_t len; char ebuf[1024];
struct { regex_t reg;
char *version; static struct {
char *pat;
int bugs; int bugs;
} check[] = { } check[] = {
{"2.1.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC}, { "^OpenSSH[-_]2\\.[012]", SSH_OLD_SESSIONID },
{"2.0.1", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD}, { "MindTerm", 0 },
{"2.", SSH_BUG_HMAC|SSH_COMPAT_SESSIONID_ENCODING}, { "^2\\.1\\.0 ", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
{NULL, 0} SSH_OLD_SESSIONID },
{ "^2\\.0\\.", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|
SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD },
{ "^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},
{ "^2\\.", SSH_BUG_HMAC}, /* XXX fallback */
{ NULL, 0 }
}; };
/* process table, return first match */ /* process table, return first match */
for (i = 0; check[i].version; i++) { for (i = 0; check[i].pat; i++) {
len = strlen(check[i].version); ret = regcomp(&reg, check[i].pat, REG_EXTENDED|REG_NOSUB);
if (strlen(version) >= len && if (ret != 0) {
(strncmp(version, check[i].version, len) == 0)) { regerror(ret, &reg, ebuf, sizeof(ebuf));
verbose("datafellows: %.200s", version); 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\n", version, check[i].pat);
datafellows = check[i].bugs; datafellows = check[i].bugs;
return; return;
} }
} }
debug("no match: %s", version);
} }
#define SEP "," #define SEP ","

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/* RCSID("$OpenBSD: compat.h,v 1.10 2000/09/07 20:27:50 deraadt Exp $"); */ /* RCSID("$OpenBSD: compat.h,v 1.11 2000/10/14 12:16:56 markus Exp $"); */
#ifndef COMPAT_H #ifndef COMPAT_H
#define COMPAT_H #define COMPAT_H
@ -35,7 +35,7 @@
#define SSH_BUG_PUBKEYAUTH 0x02 #define SSH_BUG_PUBKEYAUTH 0x02
#define SSH_BUG_HMAC 0x04 #define SSH_BUG_HMAC 0x04
#define SSH_BUG_X11FWD 0x08 #define SSH_BUG_X11FWD 0x08
#define SSH_COMPAT_SESSIONID_ENCODING 0x10 #define SSH_OLD_SESSIONID 0x10
void enable_compat13(void); void enable_compat13(void);
void enable_compat20(void); void enable_compat20(void);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: deattack.c,v 1.9 2000/09/07 20:27:51 deraadt Exp $ */ /* $OpenBSD: deattack.c,v 1.10 2000/10/31 13:18:53 markus Exp $ */
/* /*
* Cryptographic attack detector for ssh - source code * Cryptographic attack detector for ssh - source code
@ -85,7 +85,7 @@ int
detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV) detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV)
{ {
static u_int16_t *h = (u_int16_t *) NULL; static u_int16_t *h = (u_int16_t *) NULL;
static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE; static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
register u_int32_t i, j; register u_int32_t i, j;
u_int32_t l; u_int32_t l;
register unsigned char *c; register unsigned char *c;

157
crypto/openssh/dh.c Normal file
View File

@ -0,0 +1,157 @@
/*
* 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.
*/
#include "includes.h"
RCSID("$OpenBSD: dh.c,v 1.2 2000/10/11 20:11:35 markus Exp $");
#include "xmalloc.h"
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include "ssh.h"
#include "buffer.h"
#include "kex.h"
#include "dh.h"
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(DH_PRIMES, "r");
if (!f) {
perror(DH_PRIMES);
log("WARNING: %s does not exist, using old prime", 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", DH_PRIMES);
return (dh_new_group1());
}
f = fopen(DH_PRIMES, "r");
if (!f) {
perror(DH_PRIMES);
exit(1);
}
linenum = 0;
which = arc4random() % 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/openssh/dh.h 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

@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: dispatch.c,v 1.4 2000/09/07 20:27:51 deraadt Exp $"); RCSID("$OpenBSD: dispatch.c,v 1.5 2000/09/21 11:25:34 markus Exp $");
#include "ssh.h" #include "ssh.h"
#include "dispatch.h" #include "dispatch.h"
#include "packet.h" #include "packet.h"
@ -33,7 +33,7 @@ RCSID("$OpenBSD: dispatch.c,v 1.4 2000/09/07 20:27:51 deraadt Exp $");
dispatch_fn *dispatch[DISPATCH_MAX]; dispatch_fn *dispatch[DISPATCH_MAX];
void void
dispatch_protocol_error(int type, int plen) dispatch_protocol_error(int type, int plen, void *ctxt)
{ {
error("Hm, dispatch protocol error: type %d plen %d", type, plen); error("Hm, dispatch protocol error: type %d plen %d", type, plen);
} }
@ -50,7 +50,7 @@ dispatch_set(int type, dispatch_fn *fn)
dispatch[type] = fn; dispatch[type] = fn;
} }
void void
dispatch_run(int mode, int *done) dispatch_run(int mode, int *done, void *ctxt)
{ {
for (;;) { for (;;) {
int plen; int plen;
@ -64,7 +64,7 @@ dispatch_run(int mode, int *done)
return; return;
} }
if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL)
(*dispatch[type])(type, plen); (*dispatch[type])(type, plen, ctxt);
else else
packet_disconnect("protocol error: rcvd type %d", type); packet_disconnect("protocol error: rcvd type %d", type);
if (done != NULL && *done) if (done != NULL && *done)

View File

@ -26,9 +26,9 @@ enum {
DISPATCH_NONBLOCK DISPATCH_NONBLOCK
}; };
typedef void dispatch_fn(int type, int plen); typedef void dispatch_fn(int type, int plen, void *ctxt);
void dispatch_init(dispatch_fn *dflt); void dispatch_init(dispatch_fn *dflt);
void dispatch_set(int type, dispatch_fn *fn); void dispatch_set(int type, dispatch_fn *fn);
void dispatch_run(int mode, int *done); void dispatch_run(int mode, int *done, void *ctxt);
void dispatch_protocol_error(int type, int plen); void dispatch_protocol_error(int type, int plen, void *ctxt);

View File

@ -23,7 +23,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: kex.c,v 1.10 2000/09/07 20:27:51 deraadt Exp $"); RCSID("$OpenBSD: kex.c,v 1.12 2000/10/11 20:27:23 markus Exp $");
#include "ssh.h" #include "ssh.h"
#include "ssh2.h" #include "ssh2.h"
@ -31,7 +31,6 @@ RCSID("$OpenBSD: kex.c,v 1.10 2000/09/07 20:27:51 deraadt Exp $");
#include "buffer.h" #include "buffer.h"
#include "bufaux.h" #include "bufaux.h"
#include "packet.h" #include "packet.h"
#include "cipher.h"
#include "compat.h" #include "compat.h"
#include <openssl/bn.h> #include <openssl/bn.h>
@ -123,11 +122,6 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
int n = BN_num_bits(dh_pub); int n = BN_num_bits(dh_pub);
int bits_set = 0; int bits_set = 0;
/* we only accept g==2 */
if (!BN_is_word(dh->g, 2)) {
log("invalid DH base != 2");
return 0;
}
if (dh_pub->neg) { if (dh_pub->neg) {
log("invalid public DH value: negativ"); log("invalid public DH value: negativ");
return 0; return 0;
@ -145,27 +139,10 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
} }
DH * DH *
dh_new_group1() dh_gen_key(DH *dh)
{ {
static char *group1 = int tries = 0;
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
"FFFFFFFF" "FFFFFFFF";
DH *dh;
int ret, tries = 0;
dh = DH_new();
if(dh == NULL)
fatal("DH_new");
ret = BN_hex2bn(&dh->p, group1);
if(ret<0)
fatal("BN_hex2bn");
dh->g = BN_new();
if(dh->g == NULL)
fatal("DH_new g");
BN_set_word(dh->g, 2);
do { do {
if (DH_generate_key(dh) == 0) if (DH_generate_key(dh) == 0)
fatal("DH_generate_key"); fatal("DH_generate_key");
@ -175,6 +152,52 @@ dh_new_group1()
return dh; return dh;
} }
DH *
dh_new_group_asc(const char *gen, const char *modulus)
{
DH *dh;
int ret;
dh = DH_new();
if (dh == NULL)
fatal("DH_new");
if ((ret = BN_hex2bn(&dh->p, modulus)) < 0)
fatal("BN_hex2bn p");
if ((ret = BN_hex2bn(&dh->g, gen)) < 0)
fatal("BN_hex2bn g");
return (dh_gen_key(dh));
}
DH *
dh_new_group(BIGNUM *gen, BIGNUM *modulus)
{
DH *dh;
dh = DH_new();
if (dh == NULL)
fatal("DH_new");
dh->p = modulus;
dh->g = gen;
return (dh_gen_key(dh));
}
DH *
dh_new_group1()
{
static char *gen = "2", *group1 =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
"FFFFFFFF" "FFFFFFFF";
return (dh_new_group_asc(gen, group1));
}
void void
dump_digest(unsigned char *digest, int len) dump_digest(unsigned char *digest, int len)
{ {
@ -236,6 +259,59 @@ kex_hash(
return digest; return digest;
} }
unsigned 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)
{
Buffer b;
static unsigned char digest[EVP_MAX_MD_SIZE];
EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
buffer_init(&b);
buffer_put_string(&b, client_version_string, strlen(client_version_string));
buffer_put_string(&b, server_version_string, strlen(server_version_string));
/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
buffer_put_int(&b, ckexinitlen+1);
buffer_put_char(&b, SSH2_MSG_KEXINIT);
buffer_append(&b, ckexinit, ckexinitlen);
buffer_put_int(&b, skexinitlen+1);
buffer_put_char(&b, SSH2_MSG_KEXINIT);
buffer_append(&b, skexinit, skexinitlen);
buffer_put_string(&b, serverhostkeyblob, sbloblen);
buffer_put_int(&b, minbits);
buffer_put_bignum2(&b, prime);
buffer_put_bignum2(&b, gen);
buffer_put_bignum2(&b, client_dh_pub);
buffer_put_bignum2(&b, server_dh_pub);
buffer_put_bignum2(&b, shared_secret);
#ifdef DEBUG_KEX
buffer_dump(&b);
#endif
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
EVP_DigestFinal(&md, digest, NULL);
buffer_free(&b);
#ifdef DEBUG_KEX
dump_digest(digest, evp_md->md_size);
#endif
return digest;
}
unsigned char * unsigned char *
derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret) derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret)
{ {
@ -318,28 +394,9 @@ choose_enc(Enc *enc, char *client, char *server)
char *name = get_match(client, server); char *name = get_match(client, server);
if (name == NULL) if (name == NULL)
fatal("no matching cipher found: client %s server %s", client, server); fatal("no matching cipher found: client %s server %s", client, server);
enc->type = cipher_number(name); enc->cipher = cipher_by_name(name);
if (enc->cipher == NULL)
switch (enc->type) { fatal("matching cipher is not supported: %s", name);
case SSH_CIPHER_3DES_CBC:
enc->key_len = 24;
enc->iv_len = 8;
enc->block_size = 8;
break;
case SSH_CIPHER_BLOWFISH_CBC:
case SSH_CIPHER_CAST128_CBC:
enc->key_len = 16;
enc->iv_len = 8;
enc->block_size = 8;
break;
case SSH_CIPHER_ARCFOUR:
enc->key_len = 16;
enc->iv_len = 0;
enc->block_size = 8;
break;
default:
fatal("unsupported cipher %s", name);
}
enc->name = name; enc->name = name;
enc->enabled = 0; enc->enabled = 0;
enc->iv = NULL; enc->iv = NULL;
@ -387,7 +444,11 @@ choose_kex(Kex *k, char *client, char *server)
k->name = get_match(client, server); k->name = get_match(client, server);
if (k->name == NULL) if (k->name == NULL)
fatal("no kex alg"); fatal("no kex alg");
if (strcmp(k->name, KEX_DH1) != 0) if (strcmp(k->name, KEX_DH1) == 0) {
k->kex_type = DH_GRP1_SHA1;
} else if (strcmp(k->name, KEX_DHGEX) == 0) {
k->kex_type = DH_GEX_SHA1;
} else
fatal("bad kex alg %s", k->name); fatal("bad kex alg %s", k->name);
} }
void void
@ -432,10 +493,10 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
need = 0; need = 0;
for (mode = 0; mode < MODE_MAX; mode++) { for (mode = 0; mode < MODE_MAX; mode++) {
if (need < k->enc[mode].key_len) if (need < k->enc[mode].cipher->key_len)
need = k->enc[mode].key_len; need = k->enc[mode].cipher->key_len;
if (need < k->enc[mode].iv_len) if (need < k->enc[mode].cipher->block_size)
need = k->enc[mode].iv_len; need = k->enc[mode].cipher->block_size;
if (need < k->mac[mode].key_len) if (need < k->mac[mode].key_len)
need = k->mac[mode].key_len; need = k->mac[mode].key_len;
} }

View File

@ -24,8 +24,9 @@
#ifndef KEX_H #ifndef KEX_H
#define KEX_H #define KEX_H
#define KEX_DH1 "diffie-hellman-group1-sha1" #define KEX_DH1 "diffie-hellman-group1-sha1"
#define KEX_DSS "ssh-dss" #define KEX_DHGEX "diffie-hellman-group-exchange-sha1"
#define KEX_DSS "ssh-dss"
enum kex_init_proposals { enum kex_init_proposals {
PROPOSAL_KEX_ALGS, PROPOSAL_KEX_ALGS,
@ -47,28 +48,30 @@ enum kex_modes {
MODE_MAX MODE_MAX
}; };
enum kex_exchange {
DH_GRP1_SHA1,
DH_GEX_SHA1
};
typedef struct Kex Kex; typedef struct Kex Kex;
typedef struct Mac Mac; typedef struct Mac Mac;
typedef struct Comp Comp; typedef struct Comp Comp;
typedef struct Enc Enc; typedef struct Enc Enc;
struct Enc { struct Enc {
int type; char *name;
Cipher *cipher;
int enabled; int enabled;
int block_size;
unsigned char *key; unsigned char *key;
unsigned char *iv; unsigned char *iv;
int key_len;
int iv_len;
char *name;
}; };
struct Mac { struct Mac {
EVP_MD *md; char *name;
int enabled; int enabled;
EVP_MD *md;
int mac_len; int mac_len;
unsigned char *key; unsigned char *key;
int key_len; int key_len;
char *name;
}; };
struct Comp { struct Comp {
int type; int type;
@ -83,6 +86,7 @@ struct Kex {
int server; int server;
char *name; char *name;
char *hostkeyalg; char *hostkeyalg;
int kex_type;
}; };
Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); Buffer *kex_init(char *myproposal[PROPOSAL_MAX]);
@ -96,6 +100,8 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX],
int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret);
void packet_set_kex(Kex *k); void packet_set_kex(Kex *k);
int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); 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 *);
DH *dh_new_group1(); DH *dh_new_group1();
unsigned char * unsigned char *
@ -109,4 +115,15 @@ kex_hash(
BIGNUM *server_dh_pub, BIGNUM *server_dh_pub,
BIGNUM *shared_secret); BIGNUM *shared_secret);
unsigned 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 #endif

View File

@ -5,7 +5,8 @@ SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
cipher.c compat.c compress.c crc32.c deattack.c \ cipher.c compat.c compress.c crc32.c deattack.c \
hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \ hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \
rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c atomicio.c \ rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c atomicio.c \
key.c dispatch.c dsa.c kex.c hmac.c uuencode.c util.c key.c dispatch.c dsa.c kex.c hmac.c uuencode.c util.c \
cli.c rijndael.c
NOPROFILE= yes NOPROFILE= yes
NOPIC= yes NOPIC= yes

View File

@ -36,7 +36,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: log-client.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $"); RCSID("$OpenBSD: log-client.c,v 1.12 2000/09/12 20:53:10 markus Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "ssh.h" #include "ssh.h"
@ -57,7 +57,9 @@ log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2)
case SYSLOG_LEVEL_FATAL: case SYSLOG_LEVEL_FATAL:
case SYSLOG_LEVEL_INFO: case SYSLOG_LEVEL_INFO:
case SYSLOG_LEVEL_VERBOSE: case SYSLOG_LEVEL_VERBOSE:
case SYSLOG_LEVEL_DEBUG: case SYSLOG_LEVEL_DEBUG1:
case SYSLOG_LEVEL_DEBUG2:
case SYSLOG_LEVEL_DEBUG3:
log_level = level; log_level = level;
break; break;
default: default:
@ -75,7 +77,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
if (level > log_level) if (level > log_level)
return; return;
if (level == SYSLOG_LEVEL_DEBUG) if (level >= SYSLOG_LEVEL_DEBUG1)
fprintf(stderr, "debug: "); fprintf(stderr, "debug: ");
vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
fprintf(stderr, "%s\r\n", msgbuf); fprintf(stderr, "%s\r\n", msgbuf);

View File

@ -36,7 +36,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: log-server.c,v 1.16 2000/09/07 20:27:52 deraadt Exp $"); RCSID("$OpenBSD: log-server.c,v 1.17 2000/09/12 20:53:10 markus Exp $");
#include <syslog.h> #include <syslog.h>
#include "packet.h" #include "packet.h"
@ -62,7 +62,9 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
case SYSLOG_LEVEL_FATAL: case SYSLOG_LEVEL_FATAL:
case SYSLOG_LEVEL_INFO: case SYSLOG_LEVEL_INFO:
case SYSLOG_LEVEL_VERBOSE: case SYSLOG_LEVEL_VERBOSE:
case SYSLOG_LEVEL_DEBUG: case SYSLOG_LEVEL_DEBUG1:
case SYSLOG_LEVEL_DEBUG2:
case SYSLOG_LEVEL_DEBUG3:
log_level = level; log_level = level;
break; break;
default: default:
@ -138,8 +140,16 @@ do_log(LogLevel level, const char *fmt, va_list args)
case SYSLOG_LEVEL_VERBOSE: case SYSLOG_LEVEL_VERBOSE:
pri = LOG_INFO; pri = LOG_INFO;
break; break;
case SYSLOG_LEVEL_DEBUG: case SYSLOG_LEVEL_DEBUG1:
txt = "debug"; txt = "debug1";
pri = LOG_DEBUG;
break;
case SYSLOG_LEVEL_DEBUG2:
txt = "debug2";
pri = LOG_DEBUG;
break;
case SYSLOG_LEVEL_DEBUG3:
txt = "debug3";
pri = LOG_DEBUG; pri = LOG_DEBUG;
break; break;
default: default:

View File

@ -36,7 +36,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: log.c,v 1.9 2000/09/07 21:13:37 markus Exp $"); RCSID("$OpenBSD: log.c,v 1.11 2000/09/30 16:27:43 markus Exp $");
#include "ssh.h" #include "ssh.h"
#include "xmalloc.h" #include "xmalloc.h"
@ -93,7 +93,25 @@ debug(const char *fmt,...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
do_log(SYSLOG_LEVEL_DEBUG, fmt, args); do_log(SYSLOG_LEVEL_DEBUG1, fmt, args);
va_end(args);
}
void
debug2(const char *fmt,...)
{
va_list args;
va_start(args, fmt);
do_log(SYSLOG_LEVEL_DEBUG2, fmt, args);
va_end(args);
}
void
debug3(const char *fmt,...)
{
va_list args;
va_start(args, fmt);
do_log(SYSLOG_LEVEL_DEBUG3, fmt, args);
va_end(args); va_end(args);
} }
@ -190,7 +208,10 @@ static struct {
{ "ERROR", SYSLOG_LEVEL_ERROR }, { "ERROR", SYSLOG_LEVEL_ERROR },
{ "INFO", SYSLOG_LEVEL_INFO }, { "INFO", SYSLOG_LEVEL_INFO },
{ "VERBOSE", SYSLOG_LEVEL_VERBOSE }, { "VERBOSE", SYSLOG_LEVEL_VERBOSE },
{ "DEBUG", SYSLOG_LEVEL_DEBUG }, { "DEBUG", SYSLOG_LEVEL_DEBUG1 },
{ "DEBUG1", SYSLOG_LEVEL_DEBUG1 },
{ "DEBUG2", SYSLOG_LEVEL_DEBUG2 },
{ "DEBUG3", SYSLOG_LEVEL_DEBUG3 },
{ NULL, 0 } { NULL, 0 }
}; };

View File

@ -21,11 +21,15 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1" #define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1"
#define KEX_DEFAULT_PK_ALG "ssh-dss" #define KEX_DEFAULT_PK_ALG "ssh-dss"
#define KEX_DEFAULT_ENCRYPT "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" #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_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 "" #define KEX_DEFAULT_LANG ""

View File

@ -37,7 +37,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: packet.c,v 1.35 2000/09/07 20:27:52 deraadt Exp $"); RCSID("$OpenBSD: packet.c,v 1.38 2000/10/12 14:21:12 markus Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "buffer.h" #include "buffer.h"
@ -45,7 +45,6 @@ RCSID("$OpenBSD: packet.c,v 1.35 2000/09/07 20:27:52 deraadt Exp $");
#include "bufaux.h" #include "bufaux.h"
#include "ssh.h" #include "ssh.h"
#include "crc32.h" #include "crc32.h"
#include "cipher.h"
#include "getput.h" #include "getput.h"
#include "compress.h" #include "compress.h"
@ -59,6 +58,7 @@ RCSID("$OpenBSD: packet.c,v 1.35 2000/09/07 20:27:52 deraadt Exp $");
#include <openssl/dh.h> #include <openssl/dh.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
#include "buffer.h" #include "buffer.h"
#include "cipher.h"
#include "kex.h" #include "kex.h"
#include "hmac.h" #include "hmac.h"
@ -161,11 +161,14 @@ packet_set_ssh2_format(void)
void void
packet_set_connection(int fd_in, int fd_out) packet_set_connection(int fd_in, int fd_out)
{ {
Cipher *none = cipher_by_name("none");
if (none == NULL)
fatal("packet_set_connection: cannot load cipher 'none'");
connection_in = fd_in; connection_in = fd_in;
connection_out = fd_out; connection_out = fd_out;
cipher_type = SSH_CIPHER_NONE; cipher_type = SSH_CIPHER_NONE;
cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); cipher_init(&send_context, none, (unsigned char *) "", 0, NULL, 0);
cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); cipher_init(&receive_context, none, (unsigned char *) "", 0, NULL, 0);
if (!initialized) { if (!initialized) {
initialized = 1; initialized = 1;
buffer_init(&input); buffer_init(&input);
@ -326,28 +329,18 @@ packet_encrypt(CipherContext * cc, void *dest, void *src,
*/ */
void void
packet_decrypt(CipherContext * cc, void *dest, void *src, packet_decrypt(CipherContext *context, void *dest, void *src, unsigned int bytes)
unsigned int bytes)
{ {
int i;
if ((bytes % 8) != 0)
fatal("packet_decrypt: bad ciphertext length %d", bytes);
/* /*
* Cryptographic attack detector for ssh - Modifications for packet.c * Cryptographic attack detector for ssh - Modifications for packet.c
* (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com)
*/ */
if (!compat20 &&
if (cc->type == SSH_CIPHER_NONE || compat20) { context->cipher->number != SSH_CIPHER_NONE &&
i = DEATTACK_OK; detect_attack(src, bytes, NULL) == DEATTACK_DETECTED)
} else {
i = detect_attack(src, bytes, NULL);
}
if (i == DEATTACK_DETECTED)
packet_disconnect("crc32 compensation attack: network attack detected"); packet_disconnect("crc32 compensation attack: network attack detected");
cipher_decrypt(cc, dest, src, bytes); cipher_decrypt(context, dest, src, bytes);
} }
/* /*
@ -358,14 +351,15 @@ packet_decrypt(CipherContext * cc, void *dest, void *src,
void void
packet_set_encryption_key(const unsigned char *key, unsigned int keylen, packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
int cipher) int number)
{ {
Cipher *cipher = cipher_by_number(number);
if (cipher == NULL)
fatal("packet_set_encryption_key: unknown cipher number %d", number);
if (keylen < 20) if (keylen < 20)
fatal("keylen too small: %d", keylen); fatal("packet_set_encryption_key: keylen too small: %d", keylen);
cipher_init(&receive_context, cipher, key, keylen, NULL, 0);
/* All other ciphers use the same key in both directions for now. */ cipher_init(&send_context, cipher, key, keylen, NULL, 0);
cipher_set_key(&receive_context, cipher, key, keylen);
cipher_set_key(&send_context, cipher, key, keylen);
} }
/* Starts constructing a packet to send. */ /* Starts constructing a packet to send. */
@ -553,7 +547,7 @@ packet_send2()
mac = &kex->mac[MODE_OUT]; mac = &kex->mac[MODE_OUT];
comp = &kex->comp[MODE_OUT]; comp = &kex->comp[MODE_OUT];
} }
block_size = enc ? enc->block_size : 8; block_size = enc ? enc->cipher->block_size : 8;
cp = buffer_ptr(&outgoing_packet); cp = buffer_ptr(&outgoing_packet);
type = cp[5] & 0xff; type = cp[5] & 0xff;
@ -588,7 +582,7 @@ packet_send2()
if (padlen < 4) if (padlen < 4)
padlen += block_size; padlen += block_size;
buffer_append_space(&outgoing_packet, &cp, padlen); buffer_append_space(&outgoing_packet, &cp, padlen);
if (enc && enc->type != SSH_CIPHER_NONE) { if (enc && enc->cipher->number != SSH_CIPHER_NONE) {
/* random padding */ /* random padding */
for (i = 0; i < padlen; i++) { for (i = 0; i < padlen; i++) {
if (i % 4 == 0) if (i % 4 == 0)
@ -614,7 +608,7 @@ packet_send2()
buffer_len(&outgoing_packet), buffer_len(&outgoing_packet),
mac->key, mac->key_len mac->key, mac->key_len
); );
DBG(debug("done calc HMAC out #%d", seqnr)); DBG(debug("done calc MAC out #%d", seqnr));
} }
/* encrypt packet and append to output buffer. */ /* encrypt packet and append to output buffer. */
buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
@ -637,10 +631,10 @@ packet_send2()
fatal("packet_send2: no KEX"); fatal("packet_send2: no KEX");
if (mac->md != NULL) if (mac->md != NULL)
mac->enabled = 1; mac->enabled = 1;
DBG(debug("cipher_set_key_iv send_context")); DBG(debug("cipher_init send_context"));
cipher_set_key_iv(&send_context, enc->type, cipher_init(&send_context, enc->cipher,
enc->key, enc->key_len, enc->key, enc->cipher->key_len,
enc->iv, enc->iv_len); enc->iv, enc->cipher->block_size);
clear_enc_keys(enc, kex->we_need); clear_enc_keys(enc, kex->we_need);
if (comp->type != 0 && comp->enabled == 0) { if (comp->type != 0 && comp->enabled == 0) {
comp->enabled = 1; comp->enabled = 1;
@ -841,7 +835,7 @@ packet_read_poll2(int *payload_len_ptr)
comp = &kex->comp[MODE_IN]; comp = &kex->comp[MODE_IN];
} }
maclen = mac && mac->enabled ? mac->mac_len : 0; maclen = mac && mac->enabled ? mac->mac_len : 0;
block_size = enc ? enc->block_size : 8; block_size = enc ? enc->cipher->block_size : 8;
if (packet_length == 0) { if (packet_length == 0) {
/* /*
@ -894,8 +888,8 @@ packet_read_poll2(int *payload_len_ptr)
mac->key, mac->key_len mac->key, mac->key_len
); );
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
packet_disconnect("Corrupted HMAC on input."); packet_disconnect("Corrupted MAC on input.");
DBG(debug("HMAC #%d ok", seqnr)); DBG(debug("MAC #%d ok", seqnr));
buffer_consume(&input, mac->mac_len); buffer_consume(&input, mac->mac_len);
} }
if (++seqnr == 0) if (++seqnr == 0)
@ -939,10 +933,10 @@ packet_read_poll2(int *payload_len_ptr)
fatal("packet_read_poll2: no KEX"); fatal("packet_read_poll2: no KEX");
if (mac->md != NULL) if (mac->md != NULL)
mac->enabled = 1; mac->enabled = 1;
DBG(debug("cipher_set_key_iv receive_context")); DBG(debug("cipher_init receive_context"));
cipher_set_key_iv(&receive_context, enc->type, cipher_init(&receive_context, enc->cipher,
enc->key, enc->key_len, enc->key, enc->cipher->key_len,
enc->iv, enc->iv_len); enc->iv, enc->cipher->block_size);
clear_enc_keys(enc, kex->we_need); clear_enc_keys(enc, kex->we_need);
if (comp->type != 0 && comp->enabled == 0) { if (comp->type != 0 && comp->enabled == 0) {
comp->enabled = 1; comp->enabled = 1;

View File

@ -32,88 +32,24 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: readpass.c,v 1.11 2000/06/20 01:39:44 markus Exp $"); RCSID("$OpenBSD: readpass.c,v 1.12 2000/10/11 20:14:39 markus Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "ssh.h" #include "ssh.h"
#include "cli.h"
volatile int intr;
void
intcatch()
{
intr = 1;
}
/* /*
* Reads a passphrase from /dev/tty with echo turned off. Returns the * Reads a passphrase from /dev/tty with echo turned off. Returns the
* passphrase (allocated with xmalloc), being very careful to ensure that * passphrase (allocated with xmalloc), being very careful to ensure that
* no other userland buffer is storing the password. * 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 * char *
read_passphrase(const char *prompt, int from_stdin) read_passphrase(char *prompt, int from_stdin)
{ {
char buf[1024], *p, ch; return cli_read_passphrase(prompt, from_stdin, 0);
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("/dev/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);
} }

493
crypto/openssh/rijndael.c Normal file
View File

@ -0,0 +1,493 @@
/* $OpenBSD: rijndael.c,v 1.2 2000/10/15 14:14:01 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 BLOCK_SWAP
#endif
/* For inverting byte order in input/output 32 bit words if needed */
#ifdef BLOCK_SWAP
#define BYTE_SWAP
#define WORD_SWAP
#endif
#ifdef BYTE_SWAP
#define io_swap(x) bswap(x)
#else
#define io_swap(x) (x)
#endif
/* For inverting the byte order of input/output blocks if needed */
#ifdef WORD_SWAP
#define get_block(x) \
((u4byte*)(x))[0] = io_swap(in_blk[3]); \
((u4byte*)(x))[1] = io_swap(in_blk[2]); \
((u4byte*)(x))[2] = io_swap(in_blk[1]); \
((u4byte*)(x))[3] = io_swap(in_blk[0])
#define put_block(x) \
out_blk[3] = io_swap(((u4byte*)(x))[0]); \
out_blk[2] = io_swap(((u4byte*)(x))[1]); \
out_blk[1] = io_swap(((u4byte*)(x))[2]); \
out_blk[0] = io_swap(((u4byte*)(x))[3])
#define get_key(x,len) \
((u4byte*)(x))[4] = ((u4byte*)(x))[5] = \
((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0; \
switch((((len) + 63) / 64)) { \
case 2: \
((u4byte*)(x))[0] = io_swap(in_key[3]); \
((u4byte*)(x))[1] = io_swap(in_key[2]); \
((u4byte*)(x))[2] = io_swap(in_key[1]); \
((u4byte*)(x))[3] = io_swap(in_key[0]); \
break; \
case 3: \
((u4byte*)(x))[0] = io_swap(in_key[5]); \
((u4byte*)(x))[1] = io_swap(in_key[4]); \
((u4byte*)(x))[2] = io_swap(in_key[3]); \
((u4byte*)(x))[3] = io_swap(in_key[2]); \
((u4byte*)(x))[4] = io_swap(in_key[1]); \
((u4byte*)(x))[5] = io_swap(in_key[0]); \
break; \
case 4: \
((u4byte*)(x))[0] = io_swap(in_key[7]); \
((u4byte*)(x))[1] = io_swap(in_key[6]); \
((u4byte*)(x))[2] = io_swap(in_key[5]); \
((u4byte*)(x))[3] = io_swap(in_key[4]); \
((u4byte*)(x))[4] = io_swap(in_key[3]); \
((u4byte*)(x))[5] = io_swap(in_key[2]); \
((u4byte*)(x))[6] = io_swap(in_key[1]); \
((u4byte*)(x))[7] = io_swap(in_key[0]); \
}
#else
#define get_block(x) \
((u4byte*)(x))[0] = io_swap(in_blk[0]); \
((u4byte*)(x))[1] = io_swap(in_blk[1]); \
((u4byte*)(x))[2] = io_swap(in_blk[2]); \
((u4byte*)(x))[3] = io_swap(in_blk[3])
#define put_block(x) \
out_blk[0] = io_swap(((u4byte*)(x))[0]); \
out_blk[1] = io_swap(((u4byte*)(x))[1]); \
out_blk[2] = io_swap(((u4byte*)(x))[2]); \
out_blk[3] = io_swap(((u4byte*)(x))[3])
#define get_key(x,len) \
((u4byte*)(x))[4] = ((u4byte*)(x))[5] = \
((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0; \
switch((((len) + 63) / 64)) { \
case 4: \
((u4byte*)(x))[6] = io_swap(in_key[6]); \
((u4byte*)(x))[7] = io_swap(in_key[7]); \
case 3: \
((u4byte*)(x))[4] = io_swap(in_key[4]); \
((u4byte*)(x))[5] = io_swap(in_key[5]); \
case 2: \
((u4byte*)(x))[0] = io_swap(in_key[0]); \
((u4byte*)(x))[1] = io_swap(in_key[1]); \
((u4byte*)(x))[2] = io_swap(in_key[2]); \
((u4byte*)(x))[3] = io_swap(in_key[3]); \
}
#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] = in_key[0]; e_key[1] = in_key[1];
e_key[2] = in_key[2]; e_key[3] = 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] = in_key[4]; t = e_key[5] = in_key[5];
for(i = 0; i < 8; ++i)
loop6(i);
break;
case 8: e_key[4] = in_key[4]; e_key[5] = in_key[5];
e_key[6] = in_key[6]; t = e_key[7] = 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] = in_blk[0] ^ e_key[0]; b0[1] = in_blk[1] ^ e_key[1];
b0[2] = in_blk[2] ^ e_key[2]; b0[3] = 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] = b0[0]; out_blk[1] = b0[1];
out_blk[2] = b0[2]; out_blk[3] = 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] = in_blk[0] ^ e_key[4 * k_len + 24]; b0[1] = in_blk[1] ^ e_key[4 * k_len + 25];
b0[2] = in_blk[2] ^ e_key[4 * k_len + 26]; b0[3] = 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] = b0[0]; out_blk[1] = b0[1];
out_blk[2] = b0[2]; out_blk[3] = b0[3];
}

31
crypto/openssh/rijndael.h 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_ */

View File

@ -9,7 +9,7 @@
.\" .\"
.\" Created: Sun May 7 00:14:37 1995 ylo .\" Created: Sun May 7 00:14:37 1995 ylo
.\" .\"
.\" $Id: scp.1,v 1.10 2000/09/01 15:25:13 deraadt Exp $ .\" $OpenBSD: scp.1,v 1.13 2000/10/16 09:38:44 djm Exp $
.\" .\"
.Dd September 25, 1999 .Dd September 25, 1999
.Dt SCP 1 .Dt SCP 1
@ -24,6 +24,7 @@
.Op Fl P Ar port .Op Fl P Ar port
.Op Fl c Ar cipher .Op Fl c Ar cipher
.Op Fl i Ar identity_file .Op Fl i Ar identity_file
.Op Fl o Ar option
.Sm off .Sm off
.Oo .Oo
.Op Ar user@ .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 .It Fl S Ar program
Name of Name of
.Ar program .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 .Xr ssh 1
options. options.
.It Fl o Ar option
The given option is directly passed to
.Xr ssh 1 .
.It Fl 4 .It Fl 4
Forces Forces
.Nm .Nm

View File

@ -75,11 +75,10 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: scp.c,v 1.39 2000/09/07 20:53:00 markus Exp $"); RCSID("$OpenBSD: scp.c,v 1.43 2000/10/18 18:23:02 markus Exp $");
#include "ssh.h" #include "ssh.h"
#include "xmalloc.h" #include "xmalloc.h"
#include <utime.h>
#define _PATH_CP "cp" #define _PATH_CP "cp"
@ -93,6 +92,9 @@ void progressmeter(int);
int getttywidth(void); int getttywidth(void);
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);
/* setup arguments for the call to ssh */
void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2)));
/* Time a transfer started. */ /* Time a transfer started. */
static struct timeval start; static struct timeval start;
@ -105,12 +107,6 @@ off_t totalbytes = 0;
/* Name of current file being transferred. */ /* Name of current file being transferred. */
char *curfile; char *curfile;
/* This is set to non-zero if IPv4 is desired. */
int IPv4 = 0;
/* This is set to non-zero if IPv6 is desired. */
int IPv6 = 0;
/* This is set to non-zero to enable verbose mode. */ /* This is set to non-zero to enable verbose mode. */
int verbose_mode = 0; int verbose_mode = 0;
@ -120,23 +116,16 @@ int compress = 0;
/* This is set to zero if the progressmeter is not desired. */ /* This is set to zero if the progressmeter is not desired. */
int showprogress = 1; int showprogress = 1;
/* This is set to non-zero if running in batch mode (that is, password
and passphrase queries are not allowed). */
int batchmode = 0;
/* This is set to the cipher type string if given on the command line. */
char *cipher = NULL;
/* This is set to the RSA authentication identity file name if given on
the command line. */
char *identity = NULL;
/* This is the port to use in contacting the remote site (is non-NULL). */
char *port = NULL;
/* This is the program to execute for the secured connection. ("ssh" or -S) */ /* This is the program to execute for the secured connection. ("ssh" or -S) */
char *ssh_program = SSH_PROGRAM; char *ssh_program = SSH_PROGRAM;
/* This is the list of arguments that scp passes to ssh */
struct {
char **list;
int num;
int nalloc;
} args;
/* /*
* This function executes the given command as the specified user on the * This function executes the given command as the specified user on the
* given host. This returns < 0 if execution fails, and >= 0 otherwise. This * given host. This returns < 0 if execution fails, and >= 0 otherwise. This
@ -149,8 +138,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
int pin[2], pout[2], reserved[2]; int pin[2], pout[2], reserved[2];
if (verbose_mode) if (verbose_mode)
fprintf(stderr, "Executing: host %s, user %s, command %s\n", fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n",
host, remuser ? remuser : "(unspecified)", cmd); ssh_program, host, remuser ? remuser : "(unspecified)", cmd);
/* /*
* Reserve two descriptors so that the real pipes won't get * Reserve two descriptors so that the real pipes won't get
@ -169,10 +158,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
close(reserved[1]); close(reserved[1]);
/* For a child to execute the command on the remote host using ssh. */ /* For a child to execute the command on the remote host using ssh. */
if (fork() == 0) { if (fork() == 0) {
char *args[100]; /* XXX careful */
unsigned int i;
/* Child. */ /* Child. */
close(pin[1]); close(pin[1]);
close(pout[0]); close(pout[0]);
@ -181,41 +167,13 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
close(pin[0]); close(pin[0]);
close(pout[1]); close(pout[1]);
i = 0; args.list[0] = ssh_program;
args[i++] = ssh_program; if (remuser != NULL)
args[i++] = "-x"; addargs("-l%s", remuser);
args[i++] = "-oFallBackToRsh no"; addargs("%s", host);
if (IPv4) addargs("%s", cmd);
args[i++] = "-4";
if (IPv6)
args[i++] = "-6";
if (verbose_mode)
args[i++] = "-v";
if (compress)
args[i++] = "-C";
if (batchmode)
args[i++] = "-oBatchMode yes";
if (cipher != NULL) {
args[i++] = "-c";
args[i++] = cipher;
}
if (identity != NULL) {
args[i++] = "-i";
args[i++] = identity;
}
if (port != NULL) {
args[i++] = "-p";
args[i++] = port;
}
if (remuser != NULL) {
args[i++] = "-l";
args[i++] = remuser;
}
args[i++] = host;
args[i++] = cmd;
args[i++] = NULL;
execvp(ssh_program, args); execvp(ssh_program, args.list);
perror(ssh_program); perror(ssh_program);
exit(1); exit(1);
} }
@ -281,27 +239,45 @@ main(argc, argv)
extern char *optarg; extern char *optarg;
extern int optind; extern int optind;
args.list = NULL;
addargs("ssh"); /* overwritten with ssh_program */
addargs("-x");
addargs("-oFallBackToRsh no");
fflag = tflag = 0; fflag = tflag = 0;
while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:")) != EOF) while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != EOF)
switch (ch) { switch (ch) {
/* User-visible flags. */ /* User-visible flags. */
case '4': case '4':
IPv4 = 1;
break;
case '6': case '6':
IPv6 = 1; case 'C':
addargs("-%c", ch);
break;
case 'o':
case 'c':
case 'i':
addargs("-%c%s", ch, optarg);
break;
case 'P':
addargs("-p%s", optarg);
break;
case 'B':
addargs("-oBatchmode yes");
break; break;
case 'p': case 'p':
pflag = 1; pflag = 1;
break; break;
case 'P':
port = optarg;
break;
case 'r': case 'r':
iamrecursive = 1; iamrecursive = 1;
break; break;
case 'S': case 'S':
ssh_program = optarg; ssh_program = xstrdup(optarg);
break;
case 'v':
verbose_mode = 1;
break;
case 'q':
showprogress = 0;
break; break;
/* Server options. */ /* Server options. */
@ -316,24 +292,6 @@ main(argc, argv)
iamremote = 1; iamremote = 1;
tflag = 1; tflag = 1;
break; break;
case 'c':
cipher = optarg;
break;
case 'i':
identity = optarg;
break;
case 'v':
verbose_mode = 1;
break;
case 'B':
batchmode = 1;
break;
case 'C':
compress = 1;
break;
case 'q':
showprogress = 0;
break;
case '?': case '?':
default: default:
usage(); usage();
@ -703,8 +661,8 @@ sink(argc, argv)
off_t size; off_t size;
int setimes, targisdir, wrerrno = 0; int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
struct utimbuf ut;
int dummy_usec; int dummy_usec;
struct timeval tv[2];
#define SCREWUP(str) { why = str; goto screwup; } #define SCREWUP(str) { why = str; goto screwup; }
@ -758,16 +716,18 @@ sink(argc, argv)
if (*cp == 'T') { if (*cp == 'T') {
setimes++; setimes++;
cp++; cp++;
getnum(ut.modtime); getnum(tv[1].tv_sec);
if (*cp++ != ' ') if (*cp++ != ' ')
SCREWUP("mtime.sec not delimited"); SCREWUP("mtime.sec not delimited");
getnum(dummy_usec); getnum(dummy_usec);
tv[1].tv_usec = 0;
if (*cp++ != ' ') if (*cp++ != ' ')
SCREWUP("mtime.usec not delimited"); SCREWUP("mtime.usec not delimited");
getnum(ut.actime); getnum(tv[0].tv_sec);
if (*cp++ != ' ') if (*cp++ != ' ')
SCREWUP("atime.sec not delimited"); SCREWUP("atime.sec not delimited");
getnum(dummy_usec); getnum(dummy_usec);
tv[0].tv_usec = 0;
if (*cp++ != '\0') if (*cp++ != '\0')
SCREWUP("atime.usec not delimited"); SCREWUP("atime.usec not delimited");
(void) atomicio(write, remout, "", 1); (void) atomicio(write, remout, "", 1);
@ -835,7 +795,7 @@ sink(argc, argv)
sink(1, vect); sink(1, vect);
if (setimes) { if (setimes) {
setimes = 0; setimes = 0;
if (utime(np, &ut) < 0) if (utimes(np, tv) < 0)
run_err("%s: set times: %s", run_err("%s: set times: %s",
np, strerror(errno)); np, strerror(errno));
} }
@ -868,8 +828,10 @@ bad: run_err("%s: %s", np, strerror(errno));
amt = size - i; amt = size - i;
count += amt; count += amt;
do { do {
j = atomicio(read, remin, cp, amt); j = read(remin, cp, amt);
if (j <= 0) { if (j == -1 && (errno == EINTR || errno == EAGAIN)) {
continue;
} else if (j <= 0) {
run_err("%s", j ? strerror(errno) : run_err("%s", j ? strerror(errno) :
"dropped connection"); "dropped connection");
exit(1); exit(1);
@ -922,7 +884,7 @@ bad: run_err("%s: %s", np, strerror(errno));
(void) response(); (void) response();
if (setimes && wrerr == NO) { if (setimes && wrerr == NO) {
setimes = 0; setimes = 0;
if (utime(np, &ut) < 0) { if (utimes(np, tv) < 0) {
run_err("%s: set times: %s", run_err("%s: set times: %s",
np, strerror(errno)); np, strerror(errno));
wrerr = DISPLAYED; wrerr = DISPLAYED;
@ -1249,3 +1211,25 @@ getttywidth(void)
else else
return (80); return (80);
} }
void
addargs(char *fmt, ...)
{
va_list ap;
char buf[1024];
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (args.list == NULL) {
args.nalloc = 32;
args.num = 0;
args.list = xmalloc(args.nalloc * sizeof(char *));
} else if (args.num+2 >= args.nalloc) {
args.nalloc *= 2;
args.list = xrealloc(args.list, args.nalloc * sizeof(char *));
}
args.list[args.num++] = xstrdup(buf);
args.list[args.num] = NULL;
}

View File

@ -35,6 +35,8 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: serverloop.c,v 1.34 2000/10/27 07:32:18 markus Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "ssh.h" #include "ssh.h"
#include "packet.h" #include "packet.h"
@ -49,6 +51,8 @@
#include "dispatch.h" #include "dispatch.h"
#include "auth-options.h" #include "auth-options.h"
extern ServerOptions options;
static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */
static Buffer stderr_buffer; /* Buffer for stderr data. */ static Buffer stderr_buffer; /* Buffer for stderr data. */
@ -380,7 +384,7 @@ drain_output()
void void
process_buffered_input_packets() process_buffered_input_packets()
{ {
dispatch_run(DISPATCH_NONBLOCK, NULL); dispatch_run(DISPATCH_NONBLOCK, NULL, NULL);
} }
/* /*
@ -673,7 +677,7 @@ server_loop2(void)
} }
void void
server_input_stdin_data(int type, int plen) server_input_stdin_data(int type, int plen, void *ctxt)
{ {
char *data; char *data;
unsigned int data_len; unsigned int data_len;
@ -690,7 +694,7 @@ server_input_stdin_data(int type, int plen)
} }
void void
server_input_eof(int type, int plen) server_input_eof(int type, int plen, void *ctxt)
{ {
/* /*
* Eof from the client. The stdin descriptor to the * Eof from the client. The stdin descriptor to the
@ -703,7 +707,7 @@ server_input_eof(int type, int plen)
} }
void void
server_input_window_size(int type, int plen) server_input_window_size(int type, int plen, void *ctxt)
{ {
int row = packet_get_int(); int row = packet_get_int();
int col = packet_get_int(); int col = packet_get_int();
@ -733,7 +737,7 @@ input_direct_tcpip(void)
originator, originator_port, target, target_port); originator, originator_port, target, target_port);
/* XXX check permission */ /* XXX check permission */
if (no_port_forwarding_flag) { if (no_port_forwarding_flag || !options.allow_tcp_forwarding) {
xfree(target); xfree(target);
xfree(originator); xfree(originator);
return -1; return -1;
@ -745,11 +749,11 @@ input_direct_tcpip(void)
return -1; return -1;
return channel_new("direct-tcpip", SSH_CHANNEL_OPEN, return channel_new("direct-tcpip", SSH_CHANNEL_OPEN,
sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip")); CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
} }
void void
server_input_channel_open(int type, int plen) server_input_channel_open(int type, int plen, void *ctxt)
{ {
Channel *c = NULL; Channel *c = NULL;
char *ctype; char *ctype;
@ -764,7 +768,7 @@ server_input_channel_open(int type, int plen)
rwindow = packet_get_int(); rwindow = packet_get_int();
rmaxpack = packet_get_int(); rmaxpack = packet_get_int();
debug("channel_input_open: ctype %s rchan %d win %d max %d", debug("server_input_channel_open: ctype %s rchan %d win %d max %d",
ctype, rchan, rwindow, rmaxpack); ctype, rchan, rwindow, rmaxpack);
if (strcmp(ctype, "session") == 0) { if (strcmp(ctype, "session") == 0) {
@ -779,7 +783,7 @@ server_input_channel_open(int type, int plen)
*/ */
id = channel_new(ctype, SSH_CHANNEL_LARVAL, id = channel_new(ctype, SSH_CHANNEL_LARVAL,
-1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT, -1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT,
0, xstrdup("server-session")); 0, xstrdup("server-session"), 1);
if (session_open(id) == 1) { if (session_open(id) == 1) {
channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST,
session_input_channel_req, (void *)0); session_input_channel_req, (void *)0);

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: sftp-server.8,v 1.2 2000/09/07 20:27:53 deraadt Exp $ .\" $OpenBSD: sftp-server.8,v 1.3 2000/10/13 17:20:44 aaron Exp $
.\" .\"
.\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" Copyright (c) 2000 Markus Friedl. All rights reserved.
.\" .\"
@ -36,21 +36,21 @@ is a program that speaks the server side of SFTP protocol
to stdout and expects client requests from stdin. to stdout and expects client requests from stdin.
.Nm .Nm
is not intended to be called directly, but from is not intended to be called directly, but from
.Xr sshd 8 .Xr sshd 8
using the using the
.Cm Subsystem .Cm Subsystem
option. option.
See See
.Xr sshd 8 .Xr sshd 8
for more information. for more information.
.Sh HISTORY
.Nm
first appeared in
.Ox 2.8 .
.Sh AUTHOR
Markus Friedl <markus@openbsd.org>
.Sh SEE ALSO .Sh SEE ALSO
.Xr ssh 1 , .Xr ssh 1 ,
.Xr ssh-add 1 , .Xr ssh-add 1 ,
.Xr ssh-keygen 1 , .Xr ssh-keygen 1 ,
.Xr sshd 8 , .Xr sshd 8
.Sh AUTHOR
Markus Friedl <markus@openbsd.org>
.Sh HISTORY
.Nm
first appeared in
.Ox 2.8 .

View File

@ -168,8 +168,9 @@ removed once the RSA patent expires.
This option will read a private This option will read a private
OpenSSH DSA format file and print a SSH2-compatible public key to stdout. OpenSSH DSA format file and print a SSH2-compatible public key to stdout.
.It Fl X .It Fl X
This option will read a This option will read a unencrypted
SSH2-compatible public key file and print an OpenSSH DSA compatible public key to stdout. SSH2-compatible private (or public) key file and
print an OpenSSH compatible private (or public) key to stdout.
.It Fl y .It Fl y
This option will read a private This option will read a private
OpenSSH DSA format file and print an OpenSSH DSA public key to stdout. OpenSSH DSA format file and print an OpenSSH DSA public key to stdout.

View File

@ -12,7 +12,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: ssh-keygen.c,v 1.31 2000/09/07 20:27:54 deraadt Exp $"); RCSID("$OpenBSD: ssh-keygen.c,v 1.32 2000/10/09 21:30:44 markus Exp $");
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/pem.h> #include <openssl/pem.h>
@ -27,6 +27,9 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.31 2000/09/07 20:27:54 deraadt Exp $");
#include "authfile.h" #include "authfile.h"
#include "uuencode.h" #include "uuencode.h"
#include "buffer.h"
#include "bufaux.h"
/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ /* Number of bits in the RSA/DSA key. This value can be changed on the command line. */
int bits = 1024; int bits = 1024;
@ -104,8 +107,10 @@ try_load_key(char *filename, Key *k)
return success; return success;
} }
#define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
#define SSH_COM_MAGIC_END "---- END SSH2 PUBLIC KEY ----" #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
void void
do_convert_to_ssh2(struct passwd *pw) do_convert_to_ssh2(struct passwd *pw)
@ -127,18 +132,83 @@ do_convert_to_ssh2(struct passwd *pw)
exit(1); exit(1);
} }
dsa_make_key_blob(k, &blob, &len); dsa_make_key_blob(k, &blob, &len);
fprintf(stdout, "%s\n", SSH_COM_MAGIC_BEGIN); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
fprintf(stdout, fprintf(stdout,
"Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n",
BN_num_bits(k->dsa->p), key_size(k), key_type(k),
pw->pw_name, hostname); pw->pw_name, hostname);
dump_base64(stdout, blob, len); dump_base64(stdout, blob, len);
fprintf(stdout, "%s\n", SSH_COM_MAGIC_END); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
key_free(k); key_free(k);
xfree(blob); xfree(blob);
exit(0); exit(0);
} }
void
buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
{
int bits = buffer_get_int(b);
int bytes = (bits + 7) / 8;
if (buffer_len(b) < bytes)
fatal("buffer_get_bignum_bits: input buffer too small");
BN_bin2bn((unsigned char *)buffer_ptr(b), bytes, value);
buffer_consume(b, bytes);
}
Key *
do_convert_private_ssh2_from_blob(char *blob, int blen)
{
Buffer b;
DSA *dsa;
Key *key = NULL;
int ignore, magic, rlen;
char *type, *cipher;
buffer_init(&b);
buffer_append(&b, blob, blen);
magic = buffer_get_int(&b);
if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
buffer_free(&b);
return NULL;
}
ignore = buffer_get_int(&b);
type = buffer_get_string(&b, NULL);
cipher = buffer_get_string(&b, NULL);
ignore = buffer_get_int(&b);
ignore = buffer_get_int(&b);
ignore = buffer_get_int(&b);
xfree(type);
if (strcmp(cipher, "none") != 0) {
error("unsupported cipher %s", cipher);
xfree(cipher);
buffer_free(&b);
return NULL;
}
xfree(cipher);
key = key_new(KEY_DSA);
dsa = key->dsa;
dsa->priv_key = BN_new();
if (dsa->priv_key == NULL) {
error("alloc priv_key failed");
key_free(key);
return NULL;
}
buffer_get_bignum_bits(&b, dsa->p);
buffer_get_bignum_bits(&b, dsa->g);
buffer_get_bignum_bits(&b, dsa->q);
buffer_get_bignum_bits(&b, dsa->pub_key);
buffer_get_bignum_bits(&b, dsa->priv_key);
rlen = buffer_len(&b);
if(rlen != 0)
error("do_convert_private_ssh2_from_blob: remaining bytes in key blob %d", rlen);
buffer_free(&b);
return key;
}
void void
do_convert_from_ssh2(struct passwd *pw) do_convert_from_ssh2(struct passwd *pw)
{ {
@ -148,7 +218,7 @@ do_convert_from_ssh2(struct passwd *pw)
char blob[8096]; char blob[8096];
char encoded[8096]; char encoded[8096];
struct stat st; struct stat st;
int escaped = 0; int escaped = 0, private = 0, ok;
FILE *fp; FILE *fp;
if (!have_identity) if (!have_identity)
@ -172,6 +242,8 @@ do_convert_from_ssh2(struct passwd *pw)
escaped++; escaped++;
if (strncmp(line, "----", 4) == 0 || if (strncmp(line, "----", 4) == 0 ||
strstr(line, ": ") != NULL) { strstr(line, ": ") != NULL) {
if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
private = 1;
fprintf(stderr, "ignore: %s", line); fprintf(stderr, "ignore: %s", line);
continue; continue;
} }
@ -188,9 +260,20 @@ do_convert_from_ssh2(struct passwd *pw)
fprintf(stderr, "uudecode failed.\n"); fprintf(stderr, "uudecode failed.\n");
exit(1); exit(1);
} }
k = dsa_key_from_blob(blob, blen); k = private ?
if (!key_write(k, stdout)) do_convert_private_ssh2_from_blob(blob, blen) :
fprintf(stderr, "key_write failed"); dsa_key_from_blob(blob, blen);
if (k == NULL) {
fprintf(stderr, "decode blob failed.\n");
exit(1);
}
ok = private ?
PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :
key_write(k, stdout);
if (!ok) {
fprintf(stderr, "key write failed");
exit(1);
}
key_free(k); key_free(k);
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fclose(fp); fclose(fp);

View File

@ -52,7 +52,7 @@
* *
* 192-255 Local extensions * 192-255 Local extensions
*/ */
/* RCSID("$OpenBSD: ssh2.h,v 1.4 2000/09/07 20:27:54 deraadt Exp $"); */ /* RCSID("$OpenBSD: ssh2.h,v 1.5 2000/10/11 04:02:17 provos Exp $"); */
/* transport layer: generic */ /* transport layer: generic */
@ -73,6 +73,12 @@
#define SSH2_MSG_KEXDH_INIT 30 #define SSH2_MSG_KEXDH_INIT 30
#define SSH2_MSG_KEXDH_REPLY 31 #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 */ /* user authentication: generic */
#define SSH2_MSG_USERAUTH_REQUEST 50 #define SSH2_MSG_USERAUTH_REQUEST 50

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ CFLAGS+=-DHAVE_LOGIN_CAP
SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
pty.c log-server.c login.c servconf.c serverloop.c \ pty.c log-server.c login.c servconf.c serverloop.c \
auth.c auth1.c auth2.c auth-options.c session.c auth.c auth1.c auth2.c auth-options.c session.c dh.c
.include <bsd.own.mk> # for KERBEROS and AFS .include <bsd.own.mk> # for KERBEROS and AFS
@ -26,7 +26,7 @@ DPADD+= ${LIBKRB}
.endif # KERBEROS .endif # KERBEROS
.if (${SKEY:L} == "yes") .if (${SKEY:L} == "yes")
SRCS+= auth-skey.c SRCS+= auth-skey.c auth2-skey.c
.endif .endif
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: util.c,v 1.5 2000/09/07 20:27:55 deraadt Exp $ */ /* $OpenBSD: util.c,v 1.6 2000/10/27 07:32:19 markus Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -25,7 +25,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: util.c,v 1.5 2000/09/07 20:27:55 deraadt Exp $"); RCSID("$OpenBSD: util.c,v 1.6 2000/10/27 07:32:19 markus Exp $");
#include "ssh.h" #include "ssh.h"
@ -48,18 +48,15 @@ void
set_nonblock(int fd) set_nonblock(int fd)
{ {
int val; 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); val = fcntl(fd, F_GETFL, 0);
if (val < 0) { if (val < 0) {
error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
return; return;
} }
if (val & O_NONBLOCK) if (val & O_NONBLOCK) {
debug("fd %d IS O_NONBLOCK", fd);
return; return;
}
debug("fd %d setting O_NONBLOCK", fd); debug("fd %d setting O_NONBLOCK", fd);
val |= O_NONBLOCK; val |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, val) == -1) if (fcntl(fd, F_SETFL, val) == -1)

View File

@ -1 +1,3 @@
#define SSH_VERSION "OpenSSH_2.2.0" /* $OpenBSD: version.h,v 1.13 2000/10/16 09:38:45 djm Exp $ */
#define SSH_VERSION "OpenSSH_2.3.0"