diff options
author | Damien Miller <djm@mindrot.org> | 2000-09-23 17:15:56 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-09-23 17:15:56 +1100 |
commit | 62cee00753ef8ce31b322ce6a14318cb974e883d (patch) | |
tree | 9a4dedd152d4570a99744eb9f32fe7e70461edfc | |
parent | f056e23dd6f7fad96afb9e0f5a64dce4f6045cc7 (diff) |
- (djm) OpenBSD CVS sync:
- markus@cvs.openbsd.org 2000/09/17 09:38:59
[sshconnect2.c sshd.c]
fix DEBUG_KEXDH
- markus@cvs.openbsd.org 2000/09/17 09:52:51
[sshconnect.c]
yes no; ok niels@
- markus@cvs.openbsd.org 2000/09/21 04:55:11
[sshd.8]
typo
- markus@cvs.openbsd.org 2000/09/21 05:03:54
[serverloop.c]
typo
- markus@cvs.openbsd.org 2000/09/21 05:11:42
scp.c
utime() to utimes(); mouring@pconline.com
- markus@cvs.openbsd.org 2000/09/21 05:25:08
sshconnect2.c
change login logic in ssh2, allows plugin of other auth methods
- markus@cvs.openbsd.org 2000/09/21 05:25:35
[auth2.c channels.c channels.h clientloop.c dispatch.c dispatch.h]
[serverloop.c]
add context to dispatch_run
- markus@cvs.openbsd.org 2000/09/21 05:07:52
authfd.c authfd.h ssh-agent.c
bug compat for old ssh.com software
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | auth2.c | 16 | ||||
-rw-r--r-- | authfd.c | 11 | ||||
-rw-r--r-- | authfd.h | 5 | ||||
-rw-r--r-- | channels.c | 28 | ||||
-rw-r--r-- | channels.h | 30 | ||||
-rw-r--r-- | clientloop.c | 12 | ||||
-rw-r--r-- | dispatch.c | 8 | ||||
-rw-r--r-- | dispatch.h | 6 | ||||
-rw-r--r-- | scp.c | 15 | ||||
-rw-r--r-- | serverloop.c | 12 | ||||
-rw-r--r-- | ssh-agent.c | 11 | ||||
-rw-r--r-- | sshconnect.c | 6 | ||||
-rw-r--r-- | sshconnect2.c | 450 | ||||
-rw-r--r-- | sshd.8 | 3 | ||||
-rw-r--r-- | sshd.c | 11 |
16 files changed, 447 insertions, 203 deletions
@@ -8,6 +8,32 @@ - (djm) NeXT patch from Ben Lindstrom <mouring@pconline.com> - (djm) Use printf %lld instead of %qd in sftp-server.c. Fix from Michael Stone <mstone@cs.loyola.edu> + - (djm) OpenBSD CVS sync: + - markus@cvs.openbsd.org 2000/09/17 09:38:59 + [sshconnect2.c sshd.c] + fix DEBUG_KEXDH + - markus@cvs.openbsd.org 2000/09/17 09:52:51 + [sshconnect.c] + yes no; ok niels@ + - markus@cvs.openbsd.org 2000/09/21 04:55:11 + [sshd.8] + typo + - markus@cvs.openbsd.org 2000/09/21 05:03:54 + [serverloop.c] + typo + - markus@cvs.openbsd.org 2000/09/21 05:11:42 + scp.c + utime() to utimes(); mouring@pconline.com + - markus@cvs.openbsd.org 2000/09/21 05:25:08 + sshconnect2.c + change login logic in ssh2, allows plugin of other auth methods + - markus@cvs.openbsd.org 2000/09/21 05:25:35 + [auth2.c channels.c channels.h clientloop.c dispatch.c dispatch.h] + [serverloop.c] + add context to dispatch_run + - markus@cvs.openbsd.org 2000/09/21 05:07:52 + authfd.c authfd.h ssh-agent.c + bug compat for old ssh.com software 20000920 - (djm) Fix bad path substitution. Report from Andrew Miner @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.14 2000/09/07 20:27:49 deraadt Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.15 2000/09/21 11:25:32 markus Exp $"); #include <openssl/dsa.h> #include <openssl/rsa.h> @@ -64,9 +64,9 @@ extern int session_id2_len; /* protocol */ -void input_service_request(int type, int plen); -void input_userauth_request(int type, int plen); -void protocol_error(int type, int plen); +void input_service_request(int type, int plen, void *ctxt); +void input_userauth_request(int type, int plen, void *ctxt); +void protocol_error(int type, int plen, void *ctxt); /* auth */ int ssh2_auth_none(struct passwd *pw); @@ -104,12 +104,12 @@ do_authentication2() dispatch_init(&protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); - dispatch_run(DISPATCH_BLOCK, &userauth_success); + dispatch_run(DISPATCH_BLOCK, &userauth_success, NULL); do_authenticated2(); } void -protocol_error(int type, int plen) +protocol_error(int type, int plen, void *ctxt) { log("auth: protocol error: type %d plen %d", type, plen); packet_start(SSH2_MSG_UNIMPLEMENTED); @@ -119,7 +119,7 @@ protocol_error(int type, int plen) } void -input_service_request(int type, int plen) +input_service_request(int type, int plen, void *ctxt) { unsigned int len; int accept = 0; @@ -148,7 +148,7 @@ input_service_request(int type, int plen) } void -input_userauth_request(int type, int plen) +input_userauth_request(int type, int plen, void *ctxt) { static void (*authlog) (const char *fmt,...) = verbose; static int attempt = 0; @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.27 2000/09/07 20:27:49 deraadt Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.28 2000/09/21 11:07:50 markus Exp $"); #include "ssh.h" #include "rsa.h" @@ -51,6 +51,7 @@ RCSID("$OpenBSD: authfd.c,v 1.27 2000/09/07 20:27:49 deraadt Exp $"); #include "authfd.h" #include "kex.h" #include "dsa.h" +#include "compat.h" /* helper */ int decode_reply(int type); @@ -364,20 +365,24 @@ ssh_agent_sign(AuthenticationConnection *auth, unsigned char **sigp, int *lenp, unsigned char *data, int datalen) { + extern int datafellows; Buffer msg; unsigned char *blob; unsigned int blen; - int type; + int type, flags = 0; int ret = -1; if (dsa_make_key_blob(key, &blob, &blen) == 0) return -1; + if (datafellows & SSH_BUG_SIGBLOB) + flags = SSH_AGENT_OLD_SIGNATURE; + buffer_init(&msg); buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); buffer_put_string(&msg, blob, blen); buffer_put_string(&msg, data, datalen); - buffer_put_int(&msg, 0); /* flags, unused */ + buffer_put_int(&msg, flags); xfree(blob); if (ssh_request_reply(auth, &msg, &msg) == 0) { @@ -11,7 +11,7 @@ * 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.12 2000/09/21 11:07:51 markus Exp $"); */ #ifndef AUTHFD_H #define AUTHFD_H @@ -37,6 +37,9 @@ #define SSH2_AGENTC_REMOVE_IDENTITY 18 #define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 +#define SSH_AGENT_OLD_SIGNATURE 0x01 + + typedef struct { int fd; Buffer identities; @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.68 2000/09/07 20:40:29 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.69 2000/09/21 11:25:33 markus Exp $"); #include "ssh.h" #include "packet.h" @@ -998,7 +998,7 @@ channel_output_poll() */ void -channel_input_data(int type, int plen) +channel_input_data(int type, int plen, void *ctxt) { int id; char *data; @@ -1043,7 +1043,7 @@ channel_input_data(int type, int plen) xfree(data); } void -channel_input_extended_data(int type, int plen) +channel_input_extended_data(int type, int plen, void *ctxt) { int id; int tcode; @@ -1113,7 +1113,7 @@ channel_not_very_much_buffered_data() } void -channel_input_ieof(int type, int plen) +channel_input_ieof(int type, int plen, void *ctxt) { int id; Channel *c; @@ -1128,7 +1128,7 @@ channel_input_ieof(int type, int plen) } void -channel_input_close(int type, int plen) +channel_input_close(int type, int plen, void *ctxt) { int id; Channel *c; @@ -1167,7 +1167,7 @@ channel_input_close(int type, int plen) /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ void -channel_input_oclose(int type, int plen) +channel_input_oclose(int type, int plen, void *ctxt) { int id = packet_get_int(); Channel *c = channel_lookup(id); @@ -1178,7 +1178,7 @@ channel_input_oclose(int type, int plen) } void -channel_input_close_confirmation(int type, int plen) +channel_input_close_confirmation(int type, int plen, void *ctxt) { int id = packet_get_int(); Channel *c = channel_lookup(id); @@ -1194,7 +1194,7 @@ channel_input_close_confirmation(int type, int plen) } void -channel_input_open_confirmation(int type, int plen) +channel_input_open_confirmation(int type, int plen, void *ctxt) { int id, remote_id; Channel *c; @@ -1228,7 +1228,7 @@ channel_input_open_confirmation(int type, int plen) } void -channel_input_open_failure(int type, int plen) +channel_input_open_failure(int type, int plen, void *ctxt) { int id; Channel *c; @@ -1256,7 +1256,7 @@ channel_input_open_failure(int type, int plen) } void -channel_input_channel_request(int type, int plen) +channel_input_channel_request(int type, int plen, void *ctxt) { int id; Channel *c; @@ -1281,7 +1281,7 @@ debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event); } void -channel_input_window_adjust(int type, int plen) +channel_input_window_adjust(int type, int plen, void *ctxt) { Channel *c; int id, adjust; @@ -1659,7 +1659,7 @@ channel_connect_to(const char *host, u_short host_port) */ void -channel_input_port_open(int type, int plen) +channel_input_port_open(int type, int plen, void *ctxt) { u_short host_port; char *host, *originator_string; @@ -2000,7 +2000,7 @@ x11_connect_display(void) */ void -x11_input_open(int type, int plen) +x11_input_open(int type, int plen, void *ctxt) { int remote_channel, sock = 0, newch; char *remote_host; @@ -2215,7 +2215,7 @@ auth_input_request_forwarding(struct passwd * pw) /* This is called to process an SSH_SMSG_AGENT_OPEN message. */ void -auth_input_open_request(int type, int plen) +auth_input_open_request(int type, int plen, void *ctxt) { int remch, sock, newch; char *dummyname; @@ -32,7 +32,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* RCSID("$OpenBSD: channels.h,v 1.19 2000/09/07 21:13:37 markus Exp $"); */ +/* RCSID("$OpenBSD: channels.h,v 1.20 2000/09/21 11:25:33 markus Exp $"); */ #ifndef CHANNELS_H #define CHANNELS_H @@ -131,18 +131,18 @@ int channel_new(char *ctype, int type, int rfd, int wfd, int efd, int window, int maxpack, int extended_usage, char *remote_name); -void channel_input_channel_request(int type, int plen); -void channel_input_close(int type, int plen); -void channel_input_close_confirmation(int type, int plen); -void channel_input_data(int type, int plen); -void channel_input_extended_data(int type, int plen); -void channel_input_ieof(int type, int plen); -void channel_input_oclose(int type, int plen); -void channel_input_open_confirmation(int type, int plen); -void channel_input_open_failure(int type, int plen); -void channel_input_port_open(int type, int plen); -void channel_input_window_adjust(int type, int plen); -void channel_input_open(int type, int plen); +void channel_input_channel_request(int type, int plen, void *ctxt); +void channel_input_close(int type, int plen, void *ctxt); +void channel_input_close_confirmation(int type, int plen, void *ctxt); +void channel_input_data(int type, int plen, void *ctxt); +void channel_input_extended_data(int type, int plen, void *ctxt); +void channel_input_ieof(int type, int plen, void *ctxt); +void channel_input_oclose(int type, int plen, void *ctxt); +void channel_input_open_confirmation(int type, int plen, void *ctxt); +void channel_input_open_failure(int type, int plen, void *ctxt); +void channel_input_port_open(int type, int plen, void *ctxt); +void channel_input_window_adjust(int type, int plen, void *ctxt); +void channel_input_open(int type, int plen, void *ctxt); /* Sets specific protocol options. */ void channel_set_options(int hostname_in_open); @@ -246,7 +246,7 @@ char *x11_create_display_inet(int screen, int x11_display_offset); * the remote channel number. We should do whatever we want, and respond * 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 @@ -279,7 +279,7 @@ char *auth_get_socket_name(void); int auth_input_request_forwarding(struct passwd * pw); /* 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 */ int channel_connect_to(const char *host, u_short host_port); diff --git a/clientloop.c b/clientloop.c index 7400a17a..845307eb 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.35 2000/09/14 20:25:14 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.36 2000/09/21 11:25:33 markus Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -771,7 +771,7 @@ client_process_output(fd_set * writeset) void 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 */ @@ -978,7 +978,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /*********/ void -client_input_stdout_data(int type, int plen) +client_input_stdout_data(int type, int plen, void *ctxt) { unsigned int data_len; char *data = packet_get_string(&data_len); @@ -989,7 +989,7 @@ client_input_stdout_data(int type, int plen) xfree(data); } void -client_input_stderr_data(int type, int plen) +client_input_stderr_data(int type, int plen, void *ctxt) { unsigned int data_len; char *data = packet_get_string(&data_len); @@ -1000,7 +1000,7 @@ client_input_stderr_data(int type, int plen) xfree(data); } 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); exit_status = packet_get_int(); @@ -1018,7 +1018,7 @@ client_input_exit_status(int type, int plen) /* XXXX move to generic input handler */ void -client_input_channel_open(int type, int plen) +client_input_channel_open(int type, int plen, void *ctxt) { Channel *c = NULL; char *ctype; @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #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 "dispatch.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]; 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); } @@ -50,7 +50,7 @@ dispatch_set(int type, dispatch_fn *fn) dispatch[type] = fn; } void -dispatch_run(int mode, int *done) +dispatch_run(int mode, int *done, void *ctxt) { for (;;) { int plen; @@ -64,7 +64,7 @@ dispatch_run(int mode, int *done) return; } if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) - (*dispatch[type])(type, plen); + (*dispatch[type])(type, plen, ctxt); else packet_disconnect("protocol error: rcvd type %d", type); if (done != NULL && *done) @@ -26,9 +26,9 @@ enum { 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_set(int type, dispatch_fn *fn); -void dispatch_run(int mode, int *done); -void dispatch_protocol_error(int type, int plen); +void dispatch_run(int mode, int *done, void *ctxt); +void dispatch_protocol_error(int type, int plen, void *ctxt); @@ -75,11 +75,10 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.39 2000/09/07 20:53:00 markus Exp $"); +RCSID("$OpenBSD: scp.c,v 1.40 2000/09/21 11:11:42 markus Exp $"); #include "ssh.h" #include "xmalloc.h" -#include <utime.h> #define _PATH_CP "cp" @@ -711,8 +710,8 @@ sink(argc, argv) off_t size; int setimes, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; - struct utimbuf ut; int dummy_usec; + struct timeval tv[2]; #define SCREWUP(str) { why = str; goto screwup; } @@ -766,16 +765,18 @@ sink(argc, argv) if (*cp == 'T') { setimes++; cp++; - getnum(ut.modtime); + getnum(tv[1].tv_sec); if (*cp++ != ' ') SCREWUP("mtime.sec not delimited"); getnum(dummy_usec); + tv[1].tv_usec = 0; if (*cp++ != ' ') SCREWUP("mtime.usec not delimited"); - getnum(ut.actime); + getnum(tv[0].tv_sec); if (*cp++ != ' ') SCREWUP("atime.sec not delimited"); getnum(dummy_usec); + tv[0].tv_usec = 0; if (*cp++ != '\0') SCREWUP("atime.usec not delimited"); (void) atomicio(write, remout, "", 1); @@ -843,7 +844,7 @@ sink(argc, argv) sink(1, vect); if (setimes) { setimes = 0; - if (utime(np, &ut) < 0) + if (utimes(np, tv) < 0) run_err("%s: set times: %s", np, strerror(errno)); } @@ -930,7 +931,7 @@ bad: run_err("%s: %s", np, strerror(errno)); (void) response(); if (setimes && wrerr == NO) { setimes = 0; - if (utime(np, &ut) < 0) { + if (utimes(np, tv) < 0) { run_err("%s: set times: %s", np, strerror(errno)); wrerr = DISPLAYED; diff --git a/serverloop.c b/serverloop.c index c2b2d022..be9edfaf 100644 --- a/serverloop.c +++ b/serverloop.c @@ -389,7 +389,7 @@ drain_output() void process_buffered_input_packets() { - dispatch_run(DISPATCH_NONBLOCK, NULL); + dispatch_run(DISPATCH_NONBLOCK, NULL, NULL); } /* @@ -689,7 +689,7 @@ server_loop2(void) } void -server_input_stdin_data(int type, int plen) +server_input_stdin_data(int type, int plen, void *ctxt) { char *data; unsigned int data_len; @@ -706,7 +706,7 @@ server_input_stdin_data(int type, int plen) } 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 @@ -719,7 +719,7 @@ server_input_eof(int type, int plen) } 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 col = packet_get_int(); @@ -765,7 +765,7 @@ input_direct_tcpip(void) } void -server_input_channel_open(int type, int plen) +server_input_channel_open(int type, int plen, void *ctxt) { Channel *c = NULL; char *ctype; @@ -780,7 +780,7 @@ server_input_channel_open(int type, int plen) rwindow = 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); if (strcmp(ctype, "session") == 0) { diff --git a/ssh-agent.c b/ssh-agent.c index f7be488f..e6fb336e 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.36 2000/09/15 07:13:49 deraadt Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.37 2000/09/21 11:07:51 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.36 2000/09/15 07:13:49 deraadt Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.37 2000/09/21 11:07:51 markus Exp $"); #include "ssh.h" #include "rsa.h" @@ -56,6 +56,7 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.36 2000/09/15 07:13:49 deraadt Exp $"); #include "authfd.h" #include "dsa.h" #include "kex.h" +#include "compat.h" typedef struct { int fd; @@ -237,6 +238,7 @@ process_sign_request2(SocketEntry *e) Key *key, *private; unsigned char *blob, *data, *signature = NULL; unsigned int blen, dlen, slen = 0; + int flags; Buffer msg; int ok = -1; @@ -244,7 +246,10 @@ process_sign_request2(SocketEntry *e) blob = buffer_get_string(&e->input, &blen); data = buffer_get_string(&e->input, &dlen); - buffer_get_int(&e->input); /* flags, unused */ + + flags = buffer_get_int(&e->input); + if (flags & SSH_AGENT_OLD_SIGNATURE) + datafellows = SSH_BUG_SIGBLOB; key = dsa_key_from_blob(blob, blen); if (key != NULL) { diff --git a/sshconnect.c b/sshconnect.c index 7144040e..d6072b36 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.78 2000/09/07 20:27:54 deraadt Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.79 2000/09/17 15:52:51 markus Exp $"); #include <openssl/bn.h> #include <openssl/dsa.h> @@ -444,8 +444,10 @@ read_yes_or_no(const char *prompt, int defval) retval = defval; if (strcmp(buf, "yes") == 0) retval = 1; - if (strcmp(buf, "no") == 0) + else if (strcmp(buf, "no") == 0) retval = 0; + else + fprintf(stderr, "Please type 'yes' or 'no'.\n"); if (retval != -1) { if (f != stdin) diff --git a/sshconnect2.c b/sshconnect2.c index d225359d..855833c0 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.18 2000/09/07 20:27:55 deraadt Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.20 2000/09/21 11:25:07 markus Exp $"); #include <openssl/bn.h> #include <openssl/rsa.h> @@ -49,6 +49,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.18 2000/09/07 20:27:55 deraadt Exp $"); #include "dsa.h" #include "sshconnect.h" #include "authfile.h" +#include "dispatch.h" #include "authfd.h" /* import */ @@ -67,6 +68,9 @@ void ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, Buffer *client_kexinit, Buffer *server_kexinit) { +#ifdef DEBUG_KEXDH + int i; +#endif int plen, dlen; unsigned int klen, kout; char *signature = NULL; @@ -90,11 +94,11 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, #ifdef DEBUG_KEXDH fprintf(stderr, "\np= "); - bignum_print(dh->p); + BN_print_fp(stderr, dh->p); fprintf(stderr, "\ng= "); - bignum_print(dh->g); + BN_print_fp(stderr, dh->g); fprintf(stderr, "\npub= "); - bignum_print(dh->pub_key); + BN_print_fp(stderr, dh->pub_key); fprintf(stderr, "\n"); DHparams_print_fp(stderr, dh); #endif @@ -122,7 +126,7 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, #ifdef DEBUG_KEXDH fprintf(stderr, "\ndh_server_pub= "); - bignum_print(dh_server_pub); + BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif @@ -253,8 +257,156 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) /* * Authenticate user */ + +typedef struct Authctxt Authctxt; +typedef struct Authmethod Authmethod; + +typedef int sign_cb_fn( + Authctxt *authctxt, Key *key, + unsigned char **sigp, int *lenp, unsigned char *data, int datalen); + +struct Authctxt { + const char *server_user; + const char *host; + const char *service; + AuthenticationConnection *agent; + int success; + Authmethod *method; +}; +struct Authmethod { + char *name; /* string to compare against server's list */ + int (*userauth)(Authctxt *authctxt); + int *enabled; /* flag in option struct that enables method */ + int *batch_flag; /* flag in option struct that disables method */ +}; + +void input_userauth_success(int type, int plen, void *ctxt); +void input_userauth_failure(int type, int plen, void *ctxt); +void input_userauth_error(int type, int plen, void *ctxt); +int userauth_pubkey(Authctxt *authctxt); +int userauth_passwd(Authctxt *authctxt); + +void authmethod_clear(); +Authmethod *authmethod_get(char *auth_list); + +Authmethod authmethods[] = { + {"publickey", + userauth_pubkey, + &options.dsa_authentication, + NULL}, + {"password", + userauth_passwd, + &options.password_authentication, + &options.batch_mode}, + {NULL, NULL, NULL, NULL} +}; + +void +ssh_userauth2(const char *server_user, char *host) +{ + Authctxt authctxt; + int type; + int plen; + + debug("send SSH2_MSG_SERVICE_REQUEST"); + packet_start(SSH2_MSG_SERVICE_REQUEST); + packet_put_cstring("ssh-userauth"); + packet_send(); + packet_write_wait(); + type = packet_read(&plen); + if (type != SSH2_MSG_SERVICE_ACCEPT) { + fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); + } + if (packet_remaining() > 0) { + char *reply = packet_get_string(&plen); + debug("service_accept: %s", reply); + xfree(reply); + packet_done(); + } else { + debug("buggy server: service_accept w/o service"); + } + packet_done(); + debug("got SSH2_MSG_SERVICE_ACCEPT"); + + /* setup authentication context */ + authctxt.agent = ssh_get_authentication_connection(); + authctxt.server_user = server_user; + authctxt.host = host; + authctxt.service = "ssh-connection"; /* service name */ + authctxt.success = 0; + authctxt.method = NULL; + + /* initial userauth request */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt.server_user); + packet_put_cstring(authctxt.service); + packet_put_cstring("none"); + packet_send(); + packet_write_wait(); + + authmethod_clear(); + + dispatch_init(&input_userauth_error); + dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); + dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); + dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ + + if (authctxt.agent != NULL) + ssh_close_authentication_connection(authctxt.agent); + + debug("ssh-userauth2 successfull"); +} +void +input_userauth_error(int type, int plen, void *ctxt) +{ + fatal("input_userauth_error: bad message during authentication"); +} +void +input_userauth_success(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + if (authctxt == NULL) + fatal("input_userauth_success: no authentication context"); + authctxt->success = 1; /* break out */ +} +void +input_userauth_failure(int type, int plen, void *ctxt) +{ + Authmethod *method = NULL; + Authctxt *authctxt = ctxt; + char *authlist = NULL; + int partial; + int dlen; + + if (authctxt == NULL) + fatal("input_userauth_failure: no authentication context"); + + authlist = packet_get_string(&dlen); + partial = packet_get_char(); + packet_done(); + + if (partial != 0) + debug("partial success"); + debug("authentications that can continue: %s", authlist); + + for (;;) { + /* try old method or get next method */ + method = authmethod_get(authlist); + if (method == NULL) + fatal("Unable to find an authentication method"); + if (method->userauth(authctxt) != 0) { + debug2("we sent a packet, wait for reply"); + break; + } else { + debug2("we did not send a packet, disable method"); + method->enabled = NULL; + } + } + xfree(authlist); +} + int -ssh2_try_passwd(const char *server_user, const char *host, const char *service) +userauth_passwd(Authctxt *authctxt) { static int attempt = 0; char prompt[80]; @@ -267,11 +419,11 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service) error("Permission denied, please try again."); snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", - server_user, host); + authctxt->server_user, authctxt->host); password = read_passphrase(prompt, 0); packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(server_user); - packet_put_cstring(service); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); packet_put_cstring("password"); packet_put_char(0); packet_put_cstring(password); @@ -282,14 +434,8 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service) return 1; } -typedef int sign_fn( - Key *key, - unsigned char **sigp, int *lenp, - unsigned char *data, int datalen); - int -ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign, - const char *server_user, const char *host, const char *service) +sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) { Buffer b; unsigned char *blob, *signature; @@ -309,18 +455,18 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign, skip = session_id2_len; } buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, server_user); + buffer_put_cstring(&b, authctxt->server_user); buffer_put_cstring(&b, datafellows & SSH_BUG_PUBKEYAUTH ? "ssh-userauth" : - service); + authctxt->service); buffer_put_cstring(&b, "publickey"); buffer_put_char(&b, 1); buffer_put_cstring(&b, KEX_DSS); buffer_put_string(&b, blob, bloblen); /* generate signature */ - ret = do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); < |