summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog26
-rw-r--r--auth2.c16
-rw-r--r--authfd.c11
-rw-r--r--authfd.h5
-rw-r--r--channels.c28
-rw-r--r--channels.h30
-rw-r--r--clientloop.c12
-rw-r--r--dispatch.c8
-rw-r--r--dispatch.h6
-rw-r--r--scp.c15
-rw-r--r--serverloop.c12
-rw-r--r--ssh-agent.c11
-rw-r--r--sshconnect.c6
-rw-r--r--sshconnect2.c450
-rw-r--r--sshd.83
-rw-r--r--sshd.c11
16 files changed, 447 insertions, 203 deletions
diff --git a/ChangeLog b/ChangeLog
index a20e9ad54..b6f22341d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,32 @@
8 - (djm) NeXT patch from Ben Lindstrom <mouring@pconline.com> 8 - (djm) NeXT patch from Ben Lindstrom <mouring@pconline.com>
9 - (djm) Use printf %lld instead of %qd in sftp-server.c. Fix from 9 - (djm) Use printf %lld instead of %qd in sftp-server.c. Fix from
10 Michael Stone <mstone@cs.loyola.edu> 10 Michael Stone <mstone@cs.loyola.edu>
11 - (djm) OpenBSD CVS sync:
12 - markus@cvs.openbsd.org 2000/09/17 09:38:59
13 [sshconnect2.c sshd.c]
14 fix DEBUG_KEXDH
15 - markus@cvs.openbsd.org 2000/09/17 09:52:51
16 [sshconnect.c]
17 yes no; ok niels@
18 - markus@cvs.openbsd.org 2000/09/21 04:55:11
19 [sshd.8]
20 typo
21 - markus@cvs.openbsd.org 2000/09/21 05:03:54
22 [serverloop.c]
23 typo
24 - markus@cvs.openbsd.org 2000/09/21 05:11:42
25 scp.c
26 utime() to utimes(); mouring@pconline.com
27 - markus@cvs.openbsd.org 2000/09/21 05:25:08
28 sshconnect2.c
29 change login logic in ssh2, allows plugin of other auth methods
30 - markus@cvs.openbsd.org 2000/09/21 05:25:35
31 [auth2.c channels.c channels.h clientloop.c dispatch.c dispatch.h]
32 [serverloop.c]
33 add context to dispatch_run
34 - markus@cvs.openbsd.org 2000/09/21 05:07:52
35 authfd.c authfd.h ssh-agent.c
36 bug compat for old ssh.com software
11 37
1220000920 3820000920
13 - (djm) Fix bad path substitution. Report from Andrew Miner 39 - (djm) Fix bad path substitution. Report from Andrew Miner
diff --git a/auth2.c b/auth2.c
index 8b0a4bc6a..6ac5d2527 100644
--- a/auth2.c
+++ b/auth2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: auth2.c,v 1.14 2000/09/07 20:27:49 deraadt Exp $"); 26RCSID("$OpenBSD: auth2.c,v 1.15 2000/09/21 11:25:32 markus Exp $");
27 27
28#include <openssl/dsa.h> 28#include <openssl/dsa.h>
29#include <openssl/rsa.h> 29#include <openssl/rsa.h>
@@ -64,9 +64,9 @@ extern int session_id2_len;
64 64
65/* protocol */ 65/* protocol */
66 66
67void input_service_request(int type, int plen); 67void input_service_request(int type, int plen, void *ctxt);
68void input_userauth_request(int type, int plen); 68void input_userauth_request(int type, int plen, void *ctxt);
69void protocol_error(int type, int plen); 69void protocol_error(int type, int plen, void *ctxt);
70 70
71/* auth */ 71/* auth */
72int ssh2_auth_none(struct passwd *pw); 72int ssh2_auth_none(struct passwd *pw);
@@ -104,12 +104,12 @@ do_authentication2()
104 104
105 dispatch_init(&protocol_error); 105 dispatch_init(&protocol_error);
106 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 106 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
107 dispatch_run(DISPATCH_BLOCK, &userauth_success); 107 dispatch_run(DISPATCH_BLOCK, &userauth_success, NULL);
108 do_authenticated2(); 108 do_authenticated2();
109} 109}
110 110
111void 111void
112protocol_error(int type, int plen) 112protocol_error(int type, int plen, void *ctxt)
113{ 113{
114 log("auth: protocol error: type %d plen %d", type, plen); 114 log("auth: protocol error: type %d plen %d", type, plen);
115 packet_start(SSH2_MSG_UNIMPLEMENTED); 115 packet_start(SSH2_MSG_UNIMPLEMENTED);
@@ -119,7 +119,7 @@ protocol_error(int type, int plen)
119} 119}
120 120
121void 121void
122input_service_request(int type, int plen) 122input_service_request(int type, int plen, void *ctxt)
123{ 123{
124 unsigned int len; 124 unsigned int len;
125 int accept = 0; 125 int accept = 0;
@@ -148,7 +148,7 @@ input_service_request(int type, int plen)
148} 148}
149 149
150void 150void
151input_userauth_request(int type, int plen) 151input_userauth_request(int type, int plen, void *ctxt)
152{ 152{
153 static void (*authlog) (const char *fmt,...) = verbose; 153 static void (*authlog) (const char *fmt,...) = verbose;
154 static int attempt = 0; 154 static int attempt = 0;
diff --git a/authfd.c b/authfd.c
index 89fa2afad..433623ef7 100644
--- a/authfd.c
+++ b/authfd.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: authfd.c,v 1.27 2000/09/07 20:27:49 deraadt Exp $"); 38RCSID("$OpenBSD: authfd.c,v 1.28 2000/09/21 11:07:50 markus Exp $");
39 39
40#include "ssh.h" 40#include "ssh.h"
41#include "rsa.h" 41#include "rsa.h"
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: authfd.c,v 1.27 2000/09/07 20:27:49 deraadt Exp $");
51#include "authfd.h" 51#include "authfd.h"
52#include "kex.h" 52#include "kex.h"
53#include "dsa.h" 53#include "dsa.h"
54#include "compat.h"
54 55
55/* helper */ 56/* helper */
56int decode_reply(int type); 57int decode_reply(int type);
@@ -364,20 +365,24 @@ ssh_agent_sign(AuthenticationConnection *auth,
364 unsigned char **sigp, int *lenp, 365 unsigned char **sigp, int *lenp,
365 unsigned char *data, int datalen) 366 unsigned char *data, int datalen)
366{ 367{
368 extern int datafellows;
367 Buffer msg; 369 Buffer msg;
368 unsigned char *blob; 370 unsigned char *blob;
369 unsigned int blen; 371 unsigned int blen;
370 int type; 372 int type, flags = 0;
371 int ret = -1; 373 int ret = -1;
372 374
373 if (dsa_make_key_blob(key, &blob, &blen) == 0) 375 if (dsa_make_key_blob(key, &blob, &blen) == 0)
374 return -1; 376 return -1;
375 377
378 if (datafellows & SSH_BUG_SIGBLOB)
379 flags = SSH_AGENT_OLD_SIGNATURE;
380
376 buffer_init(&msg); 381 buffer_init(&msg);
377 buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); 382 buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
378 buffer_put_string(&msg, blob, blen); 383 buffer_put_string(&msg, blob, blen);
379 buffer_put_string(&msg, data, datalen); 384 buffer_put_string(&msg, data, datalen);
380 buffer_put_int(&msg, 0); /* flags, unused */ 385 buffer_put_int(&msg, flags);
381 xfree(blob); 386 xfree(blob);
382 387
383 if (ssh_request_reply(auth, &msg, &msg) == 0) { 388 if (ssh_request_reply(auth, &msg, &msg) == 0) {
diff --git a/authfd.h b/authfd.h
index b7a137d99..808575cd8 100644
--- a/authfd.h
+++ b/authfd.h
@@ -11,7 +11,7 @@
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13 13
14/* RCSID("$OpenBSD: authfd.h,v 1.11 2000/09/07 20:27:49 deraadt Exp $"); */ 14/* RCSID("$OpenBSD: authfd.h,v 1.12 2000/09/21 11:07:51 markus Exp $"); */
15 15
16#ifndef AUTHFD_H 16#ifndef AUTHFD_H
17#define AUTHFD_H 17#define AUTHFD_H
@@ -37,6 +37,9 @@
37#define SSH2_AGENTC_REMOVE_IDENTITY 18 37#define SSH2_AGENTC_REMOVE_IDENTITY 18
38#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 38#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
39 39
40#define SSH_AGENT_OLD_SIGNATURE 0x01
41
42
40typedef struct { 43typedef struct {
41 int fd; 44 int fd;
42 Buffer identities; 45 Buffer identities;
diff --git a/channels.c b/channels.c
index 48479c456..287e16d10 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: channels.c,v 1.68 2000/09/07 20:40:29 markus Exp $"); 43RCSID("$OpenBSD: channels.c,v 1.69 2000/09/21 11:25:33 markus Exp $");
44 44
45#include "ssh.h" 45#include "ssh.h"
46#include "packet.h" 46#include "packet.h"
@@ -998,7 +998,7 @@ channel_output_poll()
998 */ 998 */
999 999
1000void 1000void
1001channel_input_data(int type, int plen) 1001channel_input_data(int type, int plen, void *ctxt)
1002{ 1002{
1003 int id; 1003 int id;
1004 char *data; 1004 char *data;
@@ -1043,7 +1043,7 @@ channel_input_data(int type, int plen)
1043 xfree(data); 1043 xfree(data);
1044} 1044}
1045void 1045void
1046channel_input_extended_data(int type, int plen) 1046channel_input_extended_data(int type, int plen, void *ctxt)
1047{ 1047{
1048 int id; 1048 int id;
1049 int tcode; 1049 int tcode;
@@ -1113,7 +1113,7 @@ channel_not_very_much_buffered_data()
1113} 1113}
1114 1114
1115void 1115void
1116channel_input_ieof(int type, int plen) 1116channel_input_ieof(int type, int plen, void *ctxt)
1117{ 1117{
1118 int id; 1118 int id;
1119 Channel *c; 1119 Channel *c;
@@ -1128,7 +1128,7 @@ channel_input_ieof(int type, int plen)
1128} 1128}
1129 1129
1130void 1130void
1131channel_input_close(int type, int plen) 1131channel_input_close(int type, int plen, void *ctxt)
1132{ 1132{
1133 int id; 1133 int id;
1134 Channel *c; 1134 Channel *c;
@@ -1167,7 +1167,7 @@ channel_input_close(int type, int plen)
1167 1167
1168/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ 1168/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
1169void 1169void
1170channel_input_oclose(int type, int plen) 1170channel_input_oclose(int type, int plen, void *ctxt)
1171{ 1171{
1172 int id = packet_get_int(); 1172 int id = packet_get_int();
1173 Channel *c = channel_lookup(id); 1173 Channel *c = channel_lookup(id);
@@ -1178,7 +1178,7 @@ channel_input_oclose(int type, int plen)
1178} 1178}
1179 1179
1180void 1180void
1181channel_input_close_confirmation(int type, int plen) 1181channel_input_close_confirmation(int type, int plen, void *ctxt)
1182{ 1182{
1183 int id = packet_get_int(); 1183 int id = packet_get_int();
1184 Channel *c = channel_lookup(id); 1184 Channel *c = channel_lookup(id);
@@ -1194,7 +1194,7 @@ channel_input_close_confirmation(int type, int plen)
1194} 1194}
1195 1195
1196void 1196void
1197channel_input_open_confirmation(int type, int plen) 1197channel_input_open_confirmation(int type, int plen, void *ctxt)
1198{ 1198{
1199 int id, remote_id; 1199 int id, remote_id;
1200 Channel *c; 1200 Channel *c;
@@ -1228,7 +1228,7 @@ channel_input_open_confirmation(int type, int plen)
1228} 1228}
1229 1229
1230void 1230void
1231channel_input_open_failure(int type, int plen) 1231channel_input_open_failure(int type, int plen, void *ctxt)
1232{ 1232{
1233 int id; 1233 int id;
1234 Channel *c; 1234 Channel *c;
@@ -1256,7 +1256,7 @@ channel_input_open_failure(int type, int plen)
1256} 1256}
1257 1257
1258void 1258void
1259channel_input_channel_request(int type, int plen) 1259channel_input_channel_request(int type, int plen, void *ctxt)
1260{ 1260{
1261 int id; 1261 int id;
1262 Channel *c; 1262 Channel *c;
@@ -1281,7 +1281,7 @@ debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event);
1281} 1281}
1282 1282
1283void 1283void
1284channel_input_window_adjust(int type, int plen) 1284channel_input_window_adjust(int type, int plen, void *ctxt)
1285{ 1285{
1286 Channel *c; 1286 Channel *c;
1287 int id, adjust; 1287 int id, adjust;
@@ -1659,7 +1659,7 @@ channel_connect_to(const char *host, u_short host_port)
1659 */ 1659 */
1660 1660
1661void 1661void
1662channel_input_port_open(int type, int plen) 1662channel_input_port_open(int type, int plen, void *ctxt)
1663{ 1663{
1664 u_short host_port; 1664 u_short host_port;
1665 char *host, *originator_string; 1665 char *host, *originator_string;
@@ -2000,7 +2000,7 @@ x11_connect_display(void)
2000 */ 2000 */
2001 2001
2002void 2002void
2003x11_input_open(int type, int plen) 2003x11_input_open(int type, int plen, void *ctxt)
2004{ 2004{
2005 int remote_channel, sock = 0, newch; 2005 int remote_channel, sock = 0, newch;
2006 char *remote_host; 2006 char *remote_host;
@@ -2215,7 +2215,7 @@ auth_input_request_forwarding(struct passwd * pw)
2215/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ 2215/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
2216 2216
2217void 2217void
2218auth_input_open_request(int type, int plen) 2218auth_input_open_request(int type, int plen, void *ctxt)
2219{ 2219{
2220 int remch, sock, newch; 2220 int remch, sock, newch;
2221 char *dummyname; 2221 char *dummyname;
diff --git a/channels.h b/channels.h
index c0d60199c..a74f59261 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35/* RCSID("$OpenBSD: channels.h,v 1.19 2000/09/07 21:13:37 markus Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.20 2000/09/21 11:25:33 markus Exp $"); */
36 36
37#ifndef CHANNELS_H 37#ifndef CHANNELS_H
38#define CHANNELS_H 38#define CHANNELS_H
@@ -131,18 +131,18 @@ int
131channel_new(char *ctype, int type, int rfd, int wfd, int efd, 131channel_new(char *ctype, int type, int rfd, int wfd, int efd,
132 int window, int maxpack, int extended_usage, char *remote_name); 132 int window, int maxpack, int extended_usage, char *remote_name);
133 133
134void channel_input_channel_request(int type, int plen); 134void channel_input_channel_request(int type, int plen, void *ctxt);
135void channel_input_close(int type, int plen); 135void channel_input_close(int type, int plen, void *ctxt);
136void channel_input_close_confirmation(int type, int plen); 136void channel_input_close_confirmation(int type, int plen, void *ctxt);
137void channel_input_data(int type, int plen); 137void channel_input_data(int type, int plen, void *ctxt);
138void channel_input_extended_data(int type, int plen); 138void channel_input_extended_data(int type, int plen, void *ctxt);
139void channel_input_ieof(int type, int plen); 139void channel_input_ieof(int type, int plen, void *ctxt);
140void channel_input_oclose(int type, int plen); 140void channel_input_oclose(int type, int plen, void *ctxt);
141void channel_input_open_confirmation(int type, int plen); 141void channel_input_open_confirmation(int type, int plen, void *ctxt);
142void channel_input_open_failure(int type, int plen); 142void channel_input_open_failure(int type, int plen, void *ctxt);
143void channel_input_port_open(int type, int plen); 143void channel_input_port_open(int type, int plen, void *ctxt);
144void channel_input_window_adjust(int type, int plen); 144void channel_input_window_adjust(int type, int plen, void *ctxt);
145void channel_input_open(int type, int plen); 145void channel_input_open(int type, int plen, void *ctxt);
146 146
147/* Sets specific protocol options. */ 147/* Sets specific protocol options. */
148void channel_set_options(int hostname_in_open); 148void channel_set_options(int hostname_in_open);
@@ -246,7 +246,7 @@ char *x11_create_display_inet(int screen, int x11_display_offset);
246 * the remote channel number. We should do whatever we want, and respond 246 * the remote channel number. We should do whatever we want, and respond
247 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. 247 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
248 */ 248 */
249void x11_input_open(int type, int plen); 249void x11_input_open(int type, int plen, void *ctxt);
250 250
251/* 251/*
252 * Requests forwarding of X11 connections. This should be called on the 252 * Requests forwarding of X11 connections. This should be called on the
@@ -279,7 +279,7 @@ char *auth_get_socket_name(void);
279int auth_input_request_forwarding(struct passwd * pw); 279int auth_input_request_forwarding(struct passwd * pw);
280 280
281/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ 281/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
282void auth_input_open_request(int type, int plen); 282void auth_input_open_request(int type, int plen, void *ctxt);
283 283
284/* XXX */ 284/* XXX */
285int channel_connect_to(const char *host, u_short host_port); 285int channel_connect_to(const char *host, u_short host_port);
diff --git a/clientloop.c b/clientloop.c
index 7400a17a6..845307eba 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.35 2000/09/14 20:25:14 markus Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.36 2000/09/21 11:25:33 markus Exp $");
63 63
64#include "xmalloc.h" 64#include "xmalloc.h"
65#include "ssh.h" 65#include "ssh.h"
@@ -771,7 +771,7 @@ client_process_output(fd_set * writeset)
771void 771void
772client_process_buffered_input_packets() 772client_process_buffered_input_packets()
773{ 773{
774 dispatch_run(DISPATCH_NONBLOCK, &quit_pending); 774 dispatch_run(DISPATCH_NONBLOCK, &quit_pending, NULL);
775} 775}
776 776
777/* scan buf[] for '~' before sending data to the peer */ 777/* 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)
978/*********/ 978/*********/
979 979
980void 980void
981client_input_stdout_data(int type, int plen) 981client_input_stdout_data(int type, int plen, void *ctxt)
982{ 982{
983 unsigned int data_len; 983 unsigned int data_len;
984 char *data = packet_get_string(&data_len); 984 char *data = packet_get_string(&data_len);
@@ -989,7 +989,7 @@ client_input_stdout_data(int type, int plen)
989 xfree(data); 989 xfree(data);
990} 990}
991void 991void
992client_input_stderr_data(int type, int plen) 992client_input_stderr_data(int type, int plen, void *ctxt)
993{ 993{
994 unsigned int data_len; 994 unsigned int data_len;
995 char *data = packet_get_string(&data_len); 995 char *data = packet_get_string(&data_len);
@@ -1000,7 +1000,7 @@ client_input_stderr_data(int type, int plen)
1000 xfree(data); 1000 xfree(data);
1001} 1001}
1002void 1002void
1003client_input_exit_status(int type, int plen) 1003client_input_exit_status(int type, int plen, void *ctxt)
1004{ 1004{
1005 packet_integrity_check(plen, 4, type); 1005 packet_integrity_check(plen, 4, type);
1006 exit_status = packet_get_int(); 1006 exit_status = packet_get_int();
@@ -1018,7 +1018,7 @@ client_input_exit_status(int type, int plen)
1018 1018
1019/* XXXX move to generic input handler */ 1019/* XXXX move to generic input handler */
1020void 1020void
1021client_input_channel_open(int type, int plen) 1021client_input_channel_open(int type, int plen, void *ctxt)
1022{ 1022{
1023 Channel *c = NULL; 1023 Channel *c = NULL;
1024 char *ctype; 1024 char *ctype;
diff --git a/dispatch.c b/dispatch.c
index 3daac2022..db8951c1b 100644
--- a/dispatch.c
+++ b/dispatch.c
@@ -22,7 +22,7 @@
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24#include "includes.h" 24#include "includes.h"
25RCSID("$OpenBSD: dispatch.c,v 1.4 2000/09/07 20:27:51 deraadt Exp $"); 25RCSID("$OpenBSD: dispatch.c,v 1.5 2000/09/21 11:25:34 markus Exp $");
26#include "ssh.h" 26#include "ssh.h"
27#include "dispatch.h" 27#include "dispatch.h"
28#include "packet.h" 28#include "packet.h"
@@ -33,7 +33,7 @@ RCSID("$OpenBSD: dispatch.c,v 1.4 2000/09/07 20:27:51 deraadt Exp $");
33dispatch_fn *dispatch[DISPATCH_MAX]; 33dispatch_fn *dispatch[DISPATCH_MAX];
34 34
35void 35void
36dispatch_protocol_error(int type, int plen) 36dispatch_protocol_error(int type, int plen, void *ctxt)
37{ 37{
38 error("Hm, dispatch protocol error: type %d plen %d", type, plen); 38 error("Hm, dispatch protocol error: type %d plen %d", type, plen);
39} 39}
@@ -50,7 +50,7 @@ dispatch_set(int type, dispatch_fn *fn)
50 dispatch[type] = fn; 50 dispatch[type] = fn;
51} 51}
52void 52void
53dispatch_run(int mode, int *done) 53dispatch_run(int mode, int *done, void *ctxt)
54{ 54{
55 for (;;) { 55 for (;;) {
56 int plen; 56 int plen;
@@ -64,7 +64,7 @@ dispatch_run(int mode, int *done)
64 return; 64 return;
65 } 65 }
66 if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) 66 if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL)
67 (*dispatch[type])(type, plen); 67 (*dispatch[type])(type, plen, ctxt);
68 else 68 else
69 packet_disconnect("protocol error: rcvd type %d", type); 69 packet_disconnect("protocol error: rcvd type %d", type);
70 if (done != NULL && *done) 70 if (done != NULL && *done)
diff --git a/dispatch.h b/dispatch.h
index dc9d3dd4e..e60174c20 100644
--- a/dispatch.h
+++ b/dispatch.h
@@ -26,9 +26,9 @@ enum {
26 DISPATCH_NONBLOCK 26 DISPATCH_NONBLOCK
27}; 27};
28 28
29typedef void dispatch_fn(int type, int plen); 29typedef void dispatch_fn(int type, int plen, void *ctxt);
30 30
31void dispatch_init(dispatch_fn *dflt); 31void dispatch_init(dispatch_fn *dflt);
32void dispatch_set(int type, dispatch_fn *fn); 32void dispatch_set(int type, dispatch_fn *fn);
33void dispatch_run(int mode, int *done); 33void dispatch_run(int mode, int *done, void *ctxt);
34void dispatch_protocol_error(int type, int plen); 34void dispatch_protocol_error(int type, int plen, void *ctxt);
diff --git a/scp.c b/scp.c
index 79c310c5e..72949d0ec 100644
--- a/scp.c
+++ b/scp.c
@@ -75,11 +75,10 @@
75 */ 75 */
76 76
77#include "includes.h" 77#include "includes.h"
78RCSID("$OpenBSD: scp.c,v 1.39 2000/09/07 20:53:00 markus Exp $"); 78RCSID("$OpenBSD: scp.c,v 1.40 2000/09/21 11:11:42 markus Exp $");
79 79
80#include "ssh.h" 80#include "ssh.h"
81#include "xmalloc.h" 81#include "xmalloc.h"
82#include <utime.h>
83 82
84#define _PATH_CP "cp" 83#define _PATH_CP "cp"
85 84
@@ -711,8 +710,8 @@ sink(argc, argv)
711 off_t size; 710 off_t size;
712 int setimes, targisdir, wrerrno = 0; 711 int setimes, targisdir, wrerrno = 0;
713 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; 712 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
714 struct utimbuf ut;
715 int dummy_usec; 713 int dummy_usec;
714 struct timeval tv[2];
716 715
717#define SCREWUP(str) { why = str; goto screwup; } 716#define SCREWUP(str) { why = str; goto screwup; }
718 717
@@ -766,16 +765,18 @@ sink(argc, argv)
766 if (*cp == 'T') { 765 if (*cp == 'T') {
767 setimes++; 766 setimes++;
768 cp++; 767 cp++;
769 getnum(ut.modtime); 768 getnum(tv[1].tv_sec);
770 if (*cp++ != ' ') 769 if (*cp++ != ' ')
771 SCREWUP("mtime.sec not delimited"); 770 SCREWUP("mtime.sec not delimited");
772 getnum(dummy_usec); 771 getnum(dummy_usec);
772 tv[1].tv_usec = 0;
773 if (*cp++ != ' ') 773 if (*cp++ != ' ')
774 SCREWUP("mtime.usec not delimited"); 774 SCREWUP("mtime.usec not delimited");
775 getnum(ut.actime); 775 getnum(tv[0].tv_sec);
776 if (*cp++ != ' ') 776 if (*cp++ != ' ')
777 SCREWUP("atime.sec not delimited"); 777 SCREWUP("atime.sec not delimited");
778 getnum(dummy_usec); 778 getnum(dummy_usec);
779 tv[0].tv_usec = 0;
779 if (*cp++ != '\0') 780 if (*cp++ != '\0')
780 SCREWUP("atime.usec not delimited"); 781 SCREWUP("atime.usec not delimited");
781 (void) atomicio(write, remout, "", 1); 782 (void) atomicio(write, remout, "", 1);
@@ -843,7 +844,7 @@ sink(argc, argv)
843 sink(1, vect); 844 sink(1, vect);
844 if (setimes) { 845 if (setimes) {
845 setimes = 0; 846 setimes = 0;
846 if (utime(np, &ut) < 0) 847 if (utimes(np, tv) < 0)
847 run_err("%s: set times: %s", 848 run_err("%s: set times: %s",
848 np, strerror(errno)); 849 np, strerror(errno));
849 } 850 }
@@ -930,7 +931,7 @@ bad: run_err("%s: %s", np, strerror(errno));
930 (void) response(); 931 (void) response();
931 if (setimes && wrerr == NO) { 932 if (setimes && wrerr == NO) {
932 setimes = 0; 933 setimes = 0;
933 if (utime(np, &ut) < 0) { 934 if (utimes(np, tv) < 0) {
934 run_err("%s: set times: %s", 935 run_err("%s: set times: %s",
935 np, strerror(errno)); 936 np, strerror(errno));
936 wrerr = DISPLAYED; 937 wrerr = DISPLAYED;
diff --git a/serverloop.c b/serverloop.c
index c2b2d0222..be9edfafc 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -389,7 +389,7 @@ drain_output()
389void 389void
390process_buffered_input_packets() 390process_buffered_input_packets()
391{ 391{
392 dispatch_run(DISPATCH_NONBLOCK, NULL); 392 dispatch_run(DISPATCH_NONBLOCK, NULL, NULL);
393} 393}
394 394
395/* 395/*
@@ -689,7 +689,7 @@ server_loop2(void)
689} 689}
690 690
691void 691void
692server_input_stdin_data(int type, int plen) 692server_input_stdin_data(int type, int plen, void *ctxt)
693{ 693{
694 char *data; 694 char *data;
695 unsigned int data_len; 695 unsigned int data_len;
@@ -706,7 +706,7 @@ server_input_stdin_data(int type, int plen)
706} 706}
707 707
708void 708void
709server_input_eof(int type, int plen) 709server_input_eof(int type, int plen, void *ctxt)
710{ 710{
711 /* 711 /*
712 * Eof from the client. The stdin descriptor to the 712 * Eof from the client. The stdin descriptor to the
@@ -719,7 +719,7 @@ server_input_eof(int type, int plen)
719} 719}
720 720
721void 721void
722server_input_window_size(int type, int plen) 722server_input_window_size(int type, int plen, void *ctxt)
723{ 723{
724 int row = packet_get_int(); 724 int row = packet_get_int();
725 int col = packet_get_int(); 725 int col = packet_get_int();
@@ -765,7 +765,7 @@ input_direct_tcpip(void)
765} 765}
766 766
767void 767void
768server_input_channel_open(int type, int plen) 768server_input_channel_open(int type, int plen, void *ctxt)
769{ 769{
770 Channel *c = NULL; 770 Channel *c = NULL;
771 char *ctype; 771 char *ctype;
@@ -780,7 +780,7 @@ server_input_channel_open(int type, int plen)
780 rwindow = packet_get_int(); 780 rwindow = packet_get_int();
781 rmaxpack = packet_get_int(); 781 rmaxpack = packet_get_int();
782 782
783 debug("channel_input_open: ctype %s rchan %d win %d max %d", 783 debug("server_input_channel_open: ctype %s rchan %d win %d max %d",
784 ctype, rchan, rwindow, rmaxpack); 784 ctype, rchan, rwindow, rmaxpack);
785 785
786 if (strcmp(ctype, "session") == 0) { 786 if (strcmp(ctype, "session") == 0) {
diff --git a/ssh-agent.c b/ssh-agent.c
index f7be488f8..e6fb336ed 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.36 2000/09/15 07:13:49 deraadt Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.37 2000/09/21 11:07:51 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,7 +37,7 @@
37 */ 37 */
38 38
39#include "includes.h" 39#include "includes.h"
40RCSID("$OpenBSD: ssh-agent.c,v 1.36 2000/09/15 07:13:49 deraadt Exp $"); 40RCSID("$OpenBSD: ssh-agent.c,v 1.37 2000/09/21 11:07:51 markus Exp $");
41 41
42#include "ssh.h" 42#include "ssh.h"
43#include "rsa.h" 43#include "rsa.h"
@@ -56,6 +56,7 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.36 2000/09/15 07:13:49 deraadt Exp $");
56#include "authfd.h" 56#include "authfd.h"
57#include "dsa.h" 57#include "dsa.h"
58#include "kex.h" 58#include "kex.h"
59#include "compat.h"
59 60
60typedef struct { 61typedef struct {
61 int fd; 62 int fd;
@@ -237,6 +238,7 @@ process_sign_request2(SocketEntry *e)
237 Key *key, *private; 238 Key *key, *private;
238 unsigned char *blob, *data, *signature = NULL; 239 unsigned char *blob, *data, *signature = NULL;
239 unsigned int blen, dlen, slen = 0; 240 unsigned int blen, dlen, slen = 0;
241 int flags;
240 Buffer msg; 242 Buffer msg;
241 int ok = -1; 243 int ok = -1;
242 244
@@ -244,7 +246,10 @@ process_sign_request2(SocketEntry *e)
244 246
245 blob = buffer_get_string(&e->input, &blen); 247 blob = buffer_get_string(&e->input, &blen);
246 data = buffer_get_string(&e->input, &dlen); 248 data = buffer_get_string(&e->input, &dlen);
247 buffer_get_int(&e->input); /* flags, unused */ 249
250 flags = buffer_get_int(&e->input);
251 if (flags & SSH_AGENT_OLD_SIGNATURE)
252 datafellows = SSH_BUG_SIGBLOB;
248 253
249 key = dsa_key_from_blob(blob, blen); 254 key = dsa_key_from_blob(blob, blen);
250 if (key != NULL) { 255 if (key != NULL) {
diff --git a/sshconnect.c b/sshconnect.c
index 7144040ef..d6072b36c 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect.c,v 1.78 2000/09/07 20:27:54 deraadt Exp $"); 16RCSID("$OpenBSD: sshconnect.c,v 1.79 2000/09/17 15:52:51 markus Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19#include <openssl/dsa.h> 19#include <openssl/dsa.h>
@@ -444,8 +444,10 @@ read_yes_or_no(const char *prompt, int defval)
444 retval = defval; 444 retval = defval;
445 if (strcmp(buf, "yes") == 0) 445 if (strcmp(buf, "yes") == 0)
446 retval = 1; 446 retval = 1;
447 if (strcmp(buf, "no") == 0) 447 else if (strcmp(buf, "no") == 0)
448 retval = 0; 448 retval = 0;
449 else
450 fprintf(stderr, "Please type 'yes' or 'no'.\n");
449 451
450 if (retval != -1) { 452 if (retval != -1) {
451 if (f != stdin) 453 if (f != stdin)
diff --git a/sshconnect2.c b/sshconnect2.c
index d225359d0..855833c06 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.18 2000/09/07 20:27:55 deraadt Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.20 2000/09/21 11:25:07 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/rsa.h> 29#include <openssl/rsa.h>
@@ -49,6 +49,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.18 2000/09/07 20:27:55 deraadt Exp $");
49#include "dsa.h" 49#include "dsa.h"
50#include "sshconnect.h" 50#include "sshconnect.h"
51#include "authfile.h" 51#include "authfile.h"
52#include "dispatch.h"
52#include "authfd.h" 53#include "authfd.h"
53 54
54/* import */ 55/* import */
@@ -67,6 +68,9 @@ void
67ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, 68ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
68 Buffer *client_kexinit, Buffer *server_kexinit) 69 Buffer *client_kexinit, Buffer *server_kexinit)
69{ 70{
71#ifdef DEBUG_KEXDH
72 int i;
73#endif
70 int plen, dlen; 74 int plen, dlen;
71 unsigned int klen, kout; 75 unsigned int klen, kout;
72 char *signature = NULL; 76 char *signature = NULL;
@@ -90,11 +94,11 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
90 94
91#ifdef DEBUG_KEXDH 95#ifdef DEBUG_KEXDH
92 fprintf(stderr, "\np= "); 96 fprintf(stderr, "\np= ");
93 bignum_print(dh->p); 97 BN_print_fp(stderr, dh->p);
94 fprintf(stderr, "\ng= "); 98 fprintf(stderr, "\ng= ");
95 bignum_print(dh->g); 99 BN_print_fp(stderr, dh->g);
96 fprintf(stderr, "\npub= "); 100 fprintf(stderr, "\npub= ");
97 bignum_print(dh->pub_key); 101 BN_print_fp(stderr, dh->pub_key);
98 fprintf(stderr, "\n"); 102 fprintf(stderr, "\n");
99 DHparams_print_fp(stderr, dh); 103 DHparams_print_fp(stderr, dh);
100#endif 104#endif
@@ -122,7 +126,7 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
122 126
123#ifdef DEBUG_KEXDH 127#ifdef DEBUG_KEXDH
124 fprintf(stderr, "\ndh_server_pub= "); 128 fprintf(stderr, "\ndh_server_pub= ");
125 bignum_print(dh_server_pub); 129 BN_print_fp(stderr, dh_server_pub);
126 fprintf(stderr, "\n"); 130 fprintf(stderr, "\n");
127 debug("bits %d", BN_num_bits(dh_server_pub)); 131 debug("bits %d", BN_num_bits(dh_server_pub));
128#endif 132#endif
@@ -253,8 +257,156 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
253/* 257/*
254 * Authenticate user 258 * Authenticate user
255 */ 259 */
260
261typedef struct Authctxt Authctxt;
262typedef struct Authmethod Authmethod;
263
264typedef int sign_cb_fn(
265 Authctxt *authctxt, Key *key,
266 unsigned char **sigp, int *lenp, unsigned char *data, int datalen);
267
268struct Authctxt {
269 const char *server_user;
270 const char *host;
271 const char *service;
272 AuthenticationConnection *agent;
273 int success;
274 Authmethod *method;
275};
276struct Authmethod {
277 char *name; /* string to compare against server's list */
278 int (*userauth)(Authctxt *authctxt);
279 int *enabled; /* flag in option struct that enables method */
280 int *batch_flag; /* flag in option struct that disables method */
281};
282
283void input_userauth_success(int type, int plen, void *ctxt);
284void input_userauth_failure(int type, int plen, void *ctxt);
285void input_userauth_error(int type, int plen, void *ctxt);
286int userauth_pubkey(Authctxt *authctxt);
287int userauth_passwd(Authctxt *authctxt);
288
289void authmethod_clear();
290Authmethod *authmethod_get(char *auth_list);
291
292Authmethod authmethods[] = {
293 {"publickey",
294 userauth_pubkey,
295 &options.dsa_authentication,
296 NULL},
297 {"password",
298 userauth_passwd,
299 &options.password_authentication,
300 &options.batch_mode},
301 {NULL, NULL, NULL, NULL}
302};
303
304void
305ssh_userauth2(const char *server_user, char *host)
306{
307 Authctxt authctxt;
308 int type;
309 int plen;
310
311 debug("send SSH2_MSG_SERVICE_REQUEST");
312 packet_start(SSH2_MSG_SERVICE_REQUEST);
313 packet_put_cstring("ssh-userauth");
314 packet_send();
315 packet_write_wait();
316 type = packet_read(&plen);
317 if (type != SSH2_MSG_SERVICE_ACCEPT) {
318 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
319 }
320 if (packet_remaining() > 0) {
321 char *reply = packet_get_string(&plen);
322 debug("service_accept: %s", reply);
323 xfree(reply);
324 packet_done();
325 } else {
326 debug("buggy server: service_accept w/o service");
327 }
328 packet_done();
329 debug("got SSH2_MSG_SERVICE_ACCEPT");
330
331 /* setup authentication context */
332 authctxt.agent = ssh_get_authentication_connection();
333 authctxt.server_user = server_user;
334 authctxt.host = host;
335 authctxt.service = "ssh-connection"; /* service name */
336 authctxt.success = 0;
337 authctxt.method = NULL;
338
339 /* initial userauth request */
340 packet_start(SSH2_MSG_USERAUTH_REQUEST);
341 packet_put_cstring(authctxt.server_user);
342 packet_put_cstring(authctxt.service);
343 packet_put_cstring("none");
344 packet_send();
345 packet_write_wait();
346
347 authmethod_clear();
348
349 dispatch_init(&input_userauth_error);
350 dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
351 dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
352 dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
353
354 if (authctxt.agent != NULL)
355 ssh_close_authentication_connection(authctxt.agent);
356
357 debug("ssh-userauth2 successfull");
358}
359void
360input_userauth_error(int type, int plen, void *ctxt)
361{
362 fatal("input_userauth_error: bad message during authentication");
363}
364void
365input_userauth_success(int type, int plen, void *ctxt)
366{
367 Authctxt *authctxt = ctxt;
368 if (authctxt == NULL)
369 fatal("input_userauth_success: no authentication context");
370 authctxt->success = 1; /* break out */
371}
372void
373input_userauth_failure(int type, int plen, void *ctxt)
374{
375 Authmethod *method = NULL;
376 Authctxt *authctxt = ctxt;
377 char *authlist = NULL;
378 int partial;
379 int dlen;
380
381 if (authctxt == NULL)
382 fatal("input_userauth_failure: no authentication context");
383
384 authlist = packet_get_string(&dlen);
385 partial = packet_get_char();
386 packet_done();
387
388 if (partial != 0)
389 debug("partial success");
390 debug("authentications that can continue: %s", authlist);
391
392 for (;;) {
393 /* try old method or get next method */
394 method = authmethod_get(authlist);
395 if (method == NULL)
396 fatal("Unable to find an authentication method");
397 if (method->userauth(authctxt) != 0) {
398 debug2("we sent a packet, wait for reply");
399 break;
400 } else {
401 debug2("we did not send a packet, disable method");
402 method->enabled = NULL;
403 }
404 }
405 xfree(authlist);
406}
407
256int 408int
257ssh2_try_passwd(const char *server_user, const char *host, const char *service) 409userauth_passwd(Authctxt *authctxt)
258{ 410{
259 static int attempt = 0; 411 static int attempt = 0;
260 char prompt[80]; 412 char prompt[80];
@@ -267,11 +419,11 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service)
267 error("Permission denied, please try again."); 419 error("Permission denied, please try again.");
268 420
269 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", 421 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
270 server_user, host); 422 authctxt->server_user, authctxt->host);
271 password = read_passphrase(prompt, 0); 423 password = read_passphrase(prompt, 0);
272 packet_start(SSH2_MSG_USERAUTH_REQUEST); 424 packet_start(SSH2_MSG_USERAUTH_REQUEST);
273 packet_put_cstring(server_user); 425 packet_put_cstring(authctxt->server_user);
274 packet_put_cstring(service); 426 packet_put_cstring(authctxt->service);
275 packet_put_cstring("password"); 427 packet_put_cstring("password");
276 packet_put_char(0); 428 packet_put_char(0);
277 packet_put_cstring(password); 429 packet_put_cstring(password);
@@ -282,14 +434,8 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service)
282 return 1; 434 return 1;
283} 435}
284 436
285typedef int sign_fn(
286 Key *key,
287 unsigned char **sigp, int *lenp,
288 unsigned char *data, int datalen);
289
290int 437int
291ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign, 438sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
292 const char *server_user, const char *host, const char *service)
293{ 439{
294 Buffer b; 440 Buffer b;
295 unsigned char *blob, *signature; 441 unsigned char *blob, *signature;
@@ -309,18 +455,18 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
309 skip = session_id2_len; 455 skip = session_id2_len;
310 } 456 }
311 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 457 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
312 buffer_put_cstring(&b, server_user); 458 buffer_put_cstring(&b, authctxt->server_user);
313 buffer_put_cstring(&b, 459 buffer_put_cstring(&b,
314 datafellows & SSH_BUG_PUBKEYAUTH ? 460 datafellows & SSH_BUG_PUBKEYAUTH ?
315 "ssh-userauth" : 461 "ssh-userauth" :
316 service); 462 authctxt->service);
317 buffer_put_cstring(&b, "publickey"); 463 buffer_put_cstring(&b, "publickey");
318 buffer_put_char(&b, 1); 464 buffer_put_char(&b, 1);
319 buffer_put_cstring(&b, KEX_DSS); 465 buffer_put_cstring(&b, KEX_DSS);
320 buffer_put_string(&b, blob, bloblen); 466 buffer_put_string(&b, blob, bloblen);
321 467
322 /* generate signature */ 468 /* generate signature */
323 ret = do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); 469 ret = (*sign_callback)(authctxt, k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
324 if (ret == -1) { 470 if (ret == -1) {
325 xfree(blob); 471 xfree(blob);
326 buffer_free(&b); 472 buffer_free(&b);
@@ -333,8 +479,8 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
333 buffer_clear(&b); 479 buffer_clear(&b);
334 buffer_append(&b, session_id2, session_id2_len); 480 buffer_append(&b, session_id2, session_id2_len);
335 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 481 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
336 buffer_put_cstring(&b, server_user); 482 buffer_put_cstring(&b, authctxt->server_user);
337 buffer_put_cstring(&b, service); 483 buffer_put_cstring(&b, authctxt->service);
338 buffer_put_cstring(&b, "publickey"); 484 buffer_put_cstring(&b, "publickey");
339 buffer_put_char(&b, 1); 485 buffer_put_char(&b, 1);
340 buffer_put_cstring(&b, KEX_DSS); 486 buffer_put_cstring(&b, KEX_DSS);
@@ -347,7 +493,7 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
347 493
348 /* skip session id and packet type */ 494 /* skip session id and packet type */
349 if (buffer_len(&b) < skip + 1) 495 if (buffer_len(&b) < skip + 1)
350 fatal("ssh2_try_pubkey: internal error"); 496 fatal("userauth_pubkey: internal error");
351 buffer_consume(&b, skip + 1); 497 buffer_consume(&b, skip + 1);
352 498
353 /* put remaining data from buffer into packet */ 499 /* put remaining data from buffer into packet */
@@ -362,12 +508,18 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
362 return 1; 508 return 1;
363} 509}
364 510
511/* sign callback */
512int dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
513 unsigned char *data, int datalen)
514{
515 return dsa_sign(key, sigp, lenp, data, datalen);
516}
517
365int 518int
366ssh2_try_pubkey(char *filename, 519userauth_pubkey_identity(Authctxt *authctxt, char *filename)
367 const char *server_user, const char *host, const char *service)
368{ 520{
369 Key *k; 521 Key *k;
370 int ret = 0; 522 int i, ret, try_next;
371 struct stat st; 523 struct stat st;
372 524
373 if (stat(filename, &st) != 0) { 525 if (stat(filename, &st) != 0) {
@@ -384,37 +536,40 @@ ssh2_try_pubkey(char *filename,
384 snprintf(prompt, sizeof prompt, 536 snprintf(prompt, sizeof prompt,
385 "Enter passphrase for DSA key '%.100s': ", 537 "Enter passphrase for DSA key '%.100s': ",
386 filename); 538 filename);
387 passphrase = read_passphrase(prompt, 0); 539 for (i = 0; i < options.number_of_password_prompts; i++) {
388 success = load_private_key(filename, passphrase, k, NULL); 540 passphrase = read_passphrase(prompt, 0);
389 memset(passphrase, 0, strlen(passphrase)); 541 if (strcmp(passphrase, "") != 0) {
390 xfree(passphrase); 542 success = load_private_key(filename, passphrase, k, NULL);
543 try_next = 0;
544 } else {
545 debug2("no passphrase given, try next key");
546 try_next = 1;
547 }
548 memset(passphrase, 0, strlen(passphrase));
549 xfree(passphrase);
550 if (success || try_next)
551 break;
552 debug2("bad passphrase given, try again...");
553 }
391 if (!success) { 554 if (!success) {
392 key_free(k); 555 key_free(k);
393 return 0; 556 return 0;
394 } 557 }
395 } 558 }
396 ret = ssh2_sign_and_send_pubkey(k, dsa_sign, server_user, host, service); 559 ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb);
397 key_free(k); 560 key_free(k);
398 return ret; 561 return ret;
399} 562}
400 563
401int agent_sign( 564/* sign callback */
402 Key *key, 565int agent_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
403 unsigned char **sigp, int *lenp,
404 unsigned char *data, int datalen) 566 unsigned char *data, int datalen)
405{ 567{
406 int ret = -1; 568 return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
407 AuthenticationConnection *ac = ssh_get_authentication_connection();
408 if (ac != NULL) {
409 ret = ssh_agent_sign(ac, key, sigp, lenp, data, datalen);
410 ssh_close_authentication_connection(ac);
411 }
412 return ret;
413} 569}
414 570
415int 571int
416ssh2_try_agent(AuthenticationConnection *ac, 572userauth_pubkey_agent(Authctxt *authctxt)
417 const char *server_user, const char *host, const char *service)
418{ 573{
419 static int called = 0; 574 static int called = 0;
420 char *comment; 575 char *comment;
@@ -422,104 +577,151 @@ ssh2_try_agent(AuthenticationConnection *ac,
422 int ret; 577 int ret;
423 578
424 if (called == 0) { 579 if (called == 0) {
425 k = ssh_get_first_identity(ac, &comment, 2); 580 k = ssh_get_first_identity(authctxt->agent, &comment, 2);
426 called ++; 581 called = 1;
427 } else { 582 } else {
428 k = ssh_get_next_identity(ac, &comment, 2); 583 k = ssh_get_next_identity(authctxt->agent, &comment, 2);
429 } 584 }
430 if (k == NULL) 585 if (k == NULL) {
586 debug2("no more DSA keys from agent");
431 return 0; 587 return 0;
588 }
432 debug("trying DSA agent key %s", comment); 589 debug("trying DSA agent key %s", comment);
433 xfree(comment); 590 xfree(comment);
434 ret = ssh2_sign_and_send_pubkey(k, agent_sign, server_user, host, service); 591 ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
435 key_free(k); 592 key_free(k);
436 return ret; 593 return ret;
437} 594}
438 595
439void 596int
440ssh_userauth2(const char *server_user, char *host) 597userauth_pubkey(Authctxt *authctxt)
441{ 598{
442 AuthenticationConnection *ac = ssh_get_authentication_connection(); 599 static int idx = 0;
443 int type; 600 int sent = 0;
444 int plen; 601
445 int sent; 602 if (authctxt->agent != NULL)
446 unsigned int dlen; 603 sent = userauth_pubkey_agent(authctxt);
447 int partial; 604 while (sent == 0 && idx < options.num_identity_files2)
448 int i = 0; 605 sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]);
449 char *auths; 606 return sent;
450 char *service = "ssh-connection"; /* service name */ 607}
451 608
452 debug("send SSH2_MSG_SERVICE_REQUEST");
453 packet_start(SSH2_MSG_SERVICE_REQUEST);
454 packet_put_cstring("ssh-userauth");
455 packet_send();
456 packet_write_wait();
457 609
458 type = packet_read(&plen); 610/* find auth method */
459 if (type != SSH2_MSG_SERVICE_ACCEPT) { 611
460 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); 612#define DELIM ","
613
614static char *def_authlist = "publickey,password";
615static char *authlist_current = NULL; /* clean copy used for comparison */
616static char *authname_current = NULL; /* last used auth method */
617static char *authlist_working = NULL; /* copy that gets modified by strtok_r() */
618static char *authlist_state = NULL; /* state variable for strtok_r() */
619
620/*
621 * Before starting to use a new authentication method list sent by the
622 * server, reset internal variables. This should also be called when
623 * finished processing server list to free resources.
624 */
625void
626authmethod_clear()
627{
628 if (authlist_current != NULL) {
629 xfree(authlist_current);
630 authlist_current = NULL;
461 } 631 }
462 if (packet_remaining() > 0) { 632 if (authlist_working != NULL) {
463 char *reply = packet_get_string(&plen); 633 xfree(authlist_working);
464 debug("service_accept: %s", reply); 634 authlist_working = NULL;
465 xfree(reply);
466 } else {
467 /* payload empty for ssh-2.0.13 ?? */
468 debug("buggy server: service_accept w/o service");
469 } 635 }
470 packet_done(); 636 if (authname_current != NULL) {
471 debug("got SSH2_MSG_SERVICE_ACCEPT"); 637 xfree(authname_current);
638 authlist_state = NULL;
639 }
640 if (authlist_state != NULL)
641 authlist_state = NULL;
642 return;
643}
472 644
473 /* INITIAL request for auth */ 645/*
474 packet_start(SSH2_MSG_USERAUTH_REQUEST); 646 * given auth method name, if configurable options permit this method fill
475 packet_put_cstring(server_user); 647 * in auth_ident field and return true, otherwise return false.
476 packet_put_cstring(service); 648 */
477 packet_put_cstring("none"); 649int
478 packet_send(); 650authmethod_is_enabled(Authmethod *method)
479 packet_write_wait(); 651{
652 if (method == NULL)
653 return 0;
654 /* return false if options indicate this method is disabled */
655 if (method->enabled == NULL || *method->enabled == 0)
656 return 0;
657 /* return false if batch mode is enabled but method needs interactive mode */
658 if (method->batch_flag != NULL && *method->batch_flag != 0)
659 return 0;
660 return 1;
661}
480 662
481 for (;;) { 663Authmethod *
482 sent = 0; 664authmethod_lookup(const char *name)
483 type = packet_read(&plen); 665{
484 if (type == SSH2_MSG_USERAUTH_SUCCESS) 666 Authmethod *method = NULL;
667 if (name != NULL)
668 for (method = authmethods; method->name != NULL; method++)
669 if (strcmp(name, method->name) == 0)
670 return method;
671 debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
672 return NULL;
673}
674
675/*
676 * Given the authentication method list sent by the server, return the
677 * next method we should try. If the server initially sends a nil list,
678 * use a built-in default list. If the server sends a nil list after
679 * previously sending a valid list, continue using the list originally
680 * sent.
681 */
682
683Authmethod *
684authmethod_get(char *authlist)
685{
686 char *name = NULL;
687 Authmethod *method = NULL;
688
689 /* Use a suitable default if we're passed a nil list. */
690 if (authlist == NULL || strlen(authlist) == 0)
691 authlist = def_authlist;
692
693 if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
694 /* start over if passed a different list */
695 authmethod_clear();
696 authlist_current = xstrdup(authlist);
697 authlist_working = xstrdup(authlist);
698 name = strtok_r(authlist_working, DELIM, &authlist_state);
699 } else {
700 /*
701 * try to use previously used authentication method
702 * or continue to use previously passed list
703 */
704 name = (authname_current != NULL) ?
705 authname_current : strtok_r(NULL, DELIM, &authlist_state);
706 }
707
708 while (name != NULL) {
709 method = authmethod_lookup(name);
710 if (method != NULL && authmethod_is_enabled(method))
485 break; 711 break;
486 if (type != SSH2_MSG_USERAUTH_FAILURE) 712 name = strtok_r(NULL, DELIM, &authlist_state);
487 fatal("access denied: %d", type); 713 }
488 /* SSH2_MSG_USERAUTH_FAILURE means: try again */ 714
489 auths = packet_get_string(&dlen); 715 if (authname_current != NULL)
490 debug("authentications that can continue: %s", auths); 716 xfree(authname_current);
491 partial = packet_get_char(); 717
492 packet_done(); 718 if (name != NULL) {
493 if (partial) 719 debug("next auth method to try is %s", name);
494 debug("partial success"); 720 authname_current = xstrdup(name);
495 if (options.dsa_authentication && 721 return method;
496 strstr(auths, "publickey") != NULL) { 722 } else {
497 if (ac != NULL) 723 debug("no more auth methods to try");
498 sent = ssh2_try_agent(ac, 724 authname_current = NULL;
499 server_user, host, service); 725 return NULL;
500 if (!sent) {
501 while (i < options.num_identity_files2) {
502 sent = ssh2_try_pubkey(
503 options.identity_files2[i++],
504 server_user, host, service);
505 if (sent)
506 break;
507 }
508 }
509 }
510 if (!sent) {
511 if (options.password_authentication &&
512 !options.batch_mode &&
513 strstr(auths, "password") != NULL) {
514 sent = ssh2_try_passwd(server_user, host, service);
515 }
516 }
517 if (!sent)
518 fatal("Permission denied (%s).", auths);
519 xfree(auths);
520 } 726 }
521 if (ac != NULL)
522 ssh_close_authentication_connection(ac);
523 packet_done();
524 debug("ssh-userauth2 successfull");
525} 727}
diff --git a/sshd.8 b/sshd.8
index 6c08a377e..cd2a8e962 100644
--- a/sshd.8
+++ b/sshd.8
@@ -432,8 +432,7 @@ Default is
432If set then if password authentication through Kerberos fails then 432If set then if password authentication through Kerberos fails then
433the password will be validated via any additional local mechanism 433the password will be validated via any additional local mechanism
434such as 434such as
435.Pa /etc/passwd 435.Pa /etc/passwd .
436or SecurID.
437Default is 436Default is
438.Dq yes . 437.Dq yes .
439.It Cm KerberosTgtPassing 438.It Cm KerberosTgtPassing
diff --git a/sshd.c b/sshd.c
index e94b5d11d..c11a89609 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.127 2000/09/12 20:53:10 markus Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.128 2000/09/17 15:38:59 markus Exp $");
44 44
45#include "xmalloc.h" 45#include "xmalloc.h"
46#include "rsa.h" 46#include "rsa.h"
@@ -1336,7 +1336,7 @@ do_ssh2_kex()
1336 1336
1337#ifdef DEBUG_KEXDH 1337#ifdef DEBUG_KEXDH
1338 fprintf(stderr, "\ndh_client_pub= "); 1338 fprintf(stderr, "\ndh_client_pub= ");
1339 bignum_print(dh_client_pub); 1339 BN_print_fp(stderr, dh_client_pub);
1340 fprintf(stderr, "\n"); 1340 fprintf(stderr, "\n");
1341 debug("bits %d", BN_num_bits(dh_client_pub)); 1341 debug("bits %d", BN_num_bits(dh_client_pub));
1342#endif 1342#endif
@@ -1346,12 +1346,13 @@ do_ssh2_kex()
1346 1346
1347#ifdef DEBUG_KEXDH 1347#ifdef DEBUG_KEXDH
1348 fprintf(stderr, "\np= "); 1348 fprintf(stderr, "\np= ");
1349 bignum_print(dh->p); 1349 BN_print_fp(stderr, dh->p);
1350 fprintf(stderr, "\ng= "); 1350 fprintf(stderr, "\ng= ");
1351 bignum_print(dh->g); 1351 bn_print(dh->g);
1352 fprintf(stderr, "\npub= "); 1352 fprintf(stderr, "\npub= ");
1353 bignum_print(dh->pub_key); 1353 BN_print_fp(stderr, dh->pub_key);
1354 fprintf(stderr, "\n"); 1354 fprintf(stderr, "\n");
1355 DHparams_print_fp(stderr, dh);
1355#endif 1356#endif
1356 if (!dh_pub_is_valid(dh, dh_client_pub)) 1357 if (!dh_pub_is_valid(dh, dh_client_pub))
1357 packet_disconnect("bad client public DH value"); 1358 packet_disconnect("bad client public DH value");