aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/dropbear/patches/002-match_keepalive_to_OpenSSH.patch
blob: b8cb2d0698401ac21557aee45e9f418a06bec30e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# HG changeset patch
# User Matt Johnston <matt@ucc.asn.au>
# Date 1408460936 -28800
# Node ID 0bb16232e7c4162daa43e8618521cf453847ac16
# Parent  939944f0fca9b2dcdf8470bb24efcc37a3843e8b
Make keepalive handling more robust, this should now match what OpenSSH does

diff -r 939944f0fca9 -r 0bb16232e7c4 LICENSE
--- a/LICENSE	Wed Aug 13 22:07:43 2014 +0800
+++ b/LICENSE	Tue Aug 19 23:08:56 2014 +0800
@@ -8,7 +8,7 @@
 Portions of the client-mode work are (c) 2004 Mihnea Stoenescu, under the
 same license:
 
-Copyright (c) 2002-2013 Matt Johnston
+Copyright (c) 2002-2014 Matt Johnston
 Portions copyright (c) 2004 Mihnea Stoenescu
 All rights reserved.
 
diff -r 939944f0fca9 -r 0bb16232e7c4 auth.h
--- a/auth.h	Wed Aug 13 22:07:43 2014 +0800
+++ b/auth.h	Tue Aug 19 23:08:56 2014 +0800
@@ -106,7 +106,7 @@
 								valid */
 	unsigned int failcount; /* Number of (failed) authentication attempts.*/
 	unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have. Applies for
-							  client and server (though has differing [obvious]
+							  client and server (though has differing 
 							  meanings). */
 	unsigned perm_warn : 1; /* Server only, set if bad permissions on 
 							   ~/.ssh/authorized_keys have already been
diff -r 939944f0fca9 -r 0bb16232e7c4 channel.h
--- a/channel.h	Wed Aug 13 22:07:43 2014 +0800
+++ b/channel.h	Tue Aug 19 23:08:56 2014 +0800
@@ -105,6 +105,9 @@
 void setchannelfds(fd_set *readfd, fd_set *writefd);
 void channelio(fd_set *readfd, fd_set *writefd);
 struct Channel* getchannel();
+/* Returns an arbitrary channel that is in a ready state - not
+being initialised and no EOF in either direction. NULL if none. */
+struct Channel* get_any_ready_channel();
 
 void recv_msg_channel_open();
 void recv_msg_channel_request();
@@ -128,8 +131,10 @@
 void recv_msg_channel_open_confirmation();
 void recv_msg_channel_open_failure();
 #endif
+void start_send_channel_request(struct Channel *channel, unsigned char *type);
 
 void send_msg_request_success();
 void send_msg_request_failure();
 
+
 #endif /* _CHANNEL_H_ */
diff -r 939944f0fca9 -r 0bb16232e7c4 chansession.h
--- a/chansession.h	Wed Aug 13 22:07:43 2014 +0800
+++ b/chansession.h	Tue Aug 19 23:08:56 2014 +0800
@@ -89,7 +89,6 @@
 #ifdef ENABLE_CLI_NETCAT
 void cli_send_netcat_request();
 #endif
-void cli_start_send_channel_request(struct Channel *channel, unsigned char *type);
 
 void svr_chansessinitialise();
 extern const struct ChanType svrchansess;
diff -r 939944f0fca9 -r 0bb16232e7c4 cli-agentfwd.c
--- a/cli-agentfwd.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/cli-agentfwd.c	Tue Aug 19 23:08:56 2014 +0800
@@ -234,7 +234,7 @@
 		return;
 	}
 	
-	cli_start_send_channel_request(channel, "auth-agent-req@openssh.com");
+	start_send_channel_request(channel, "auth-agent-req@openssh.com");
 	/* Don't want replies */
 	buf_putbyte(ses.writepayload, 0);
 	encrypt_packet();
diff -r 939944f0fca9 -r 0bb16232e7c4 cli-chansession.c
--- a/cli-chansession.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/cli-chansession.c	Tue Aug 19 23:08:56 2014 +0800
@@ -92,17 +92,6 @@
 	}
 }
 
-void cli_start_send_channel_request(struct Channel *channel, 
-		unsigned char *type) {
-
-	CHECKCLEARTOWRITE();
-	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
-	buf_putint(ses.writepayload, channel->remotechan);
-
-	buf_putstring(ses.writepayload, type, strlen(type));
-
-}
-
 /* Taken from OpenSSH's sshtty.c:
  * RCSID("OpenBSD: sshtty.c,v 1.5 2003/09/19 17:43:35 markus Exp "); */
 static void cli_tty_setup() {
@@ -287,7 +276,7 @@
 
 	TRACE(("enter send_chansess_pty_req"))
 
-	cli_start_send_channel_request(channel, "pty-req");
+	start_send_channel_request(channel, "pty-req");
 
 	/* Don't want replies */
 	buf_putbyte(ses.writepayload, 0);
@@ -330,7 +319,7 @@
 		reqtype = "shell";
 	}
 
-	cli_start_send_channel_request(channel, reqtype);
+	start_send_channel_request(channel, reqtype);
 
 	/* XXX TODO */
 	buf_putbyte(ses.writepayload, 0); /* Don't want replies */
diff -r 939944f0fca9 -r 0bb16232e7c4 cli-session.c
--- a/cli-session.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/cli-session.c	Tue Aug 19 23:08:56 2014 +0800
@@ -70,11 +70,15 @@
 	{SSH_MSG_USERAUTH_BANNER, recv_msg_userauth_banner}, /* client */
 	{SSH_MSG_USERAUTH_SPECIFIC_60, recv_msg_userauth_specific_60}, /* client */
 	{SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_cli},
+	{SSH_MSG_CHANNEL_SUCCESS, ignore_recv_response},
+	{SSH_MSG_CHANNEL_FAILURE, ignore_recv_response},
 #ifdef  ENABLE_CLI_REMOTETCPFWD
 	{SSH_MSG_REQUEST_SUCCESS, cli_recv_msg_request_success}, /* client */
 	{SSH_MSG_REQUEST_FAILURE, cli_recv_msg_request_failure}, /* client */
 #else
-	{SSH_MSG_REQUEST_FAILURE, ignore_recv_msg_request_failure}, /* for keepalive */
+	/* For keepalive */
+	{SSH_MSG_REQUEST_SUCCESS, ignore_recv_response},
+	{SSH_MSG_REQUEST_FAILURE, ignore_recv_response},
 #endif
 	{0, 0} /* End */
 };
diff -r 939944f0fca9 -r 0bb16232e7c4 common-channel.c
--- a/common-channel.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/common-channel.c	Tue Aug 19 23:08:56 2014 +0800
@@ -627,7 +627,12 @@
 			&& !channel->close_handler_done) {
 		channel->type->reqhandler(channel);
 	} else {
-		send_msg_channel_failure(channel);
+		int wantreply;
+		buf_eatstring(ses.payload);
+		wantreply = buf_getbool(ses.payload);
+		if (wantreply) {
+			send_msg_channel_failure(channel);
+		}
 	}
 
 	TRACE(("leave recv_msg_channel_request"))
@@ -1134,3 +1139,30 @@
 	buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_FAILURE);
 	encrypt_packet();
 }
+
+struct Channel* get_any_ready_channel() {
+	if (ses.chancount == 0) {
+		return NULL;
+	}
+	size_t i;
+	for (i = 0; i < ses.chansize; i++) {
+		struct Channel *chan = ses.channels[i];
+		if (chan
+				&& !(chan->sent_eof || chan->recv_eof)
+				&& !(chan->await_open || chan->initconn)) {
+			return chan;
+		}
+	}
+	return NULL;
+}
+
+void start_send_channel_request(struct Channel *channel, 
+		unsigned char *type) {
+
+	CHECKCLEARTOWRITE();
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	buf_putstring(ses.writepayload, type, strlen(type));
+
+}
diff -r 939944f0fca9 -r 0bb16232e7c4 common-session.c
--- a/common-session.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/common-session.c	Tue Aug 19 23:08:56 2014 +0800
@@ -394,19 +394,30 @@
 	return pos+1;
 }
 
-void ignore_recv_msg_request_failure() {
+void ignore_recv_response() {
 	// Do nothing
-	TRACE(("Ignored msg_request_failure"))
+	TRACE(("Ignored msg_request_response"))
 }
 
 static void send_msg_keepalive() {
 	CHECKCLEARTOWRITE();
 	time_t old_time_idle = ses.last_packet_time_idle;
-	/* Try to force a response from the other end. Some peers will
-	reply with SSH_MSG_REQUEST_FAILURE, some will reply with SSH_MSG_UNIMPLEMENTED */
-	buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
-	/* A short string */
-	buf_putstring(ses.writepayload, "k@dropbear.nl", 0);
+
+	struct Channel *chan = get_any_ready_channel();
+
+	if (chan) {
+		/* Channel requests are preferable, more implementations
+		handle them than SSH_MSG_GLOBAL_REQUEST */
+		TRACE(("keepalive channel request %d", chan->index))
+		start_send_channel_request(chan, DROPBEAR_KEEPALIVE_STRING);
+	} else {
+		TRACE(("keepalive global request"))
+		/* Some peers will reply with SSH_MSG_REQUEST_FAILURE, 
+		some will reply with SSH_MSG_UNIMPLEMENTED, some will exit. */
+		buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); 
+		buf_putstring(ses.writepayload, DROPBEAR_KEEPALIVE_STRING,
+			strlen(DROPBEAR_KEEPALIVE_STRING));
+	}
 	buf_putbyte(ses.writepayload, 1); /* want_reply */
 	encrypt_packet();
 
@@ -435,7 +446,10 @@
 		send_msg_kexinit();
 	}
 	
-	if (opts.keepalive_secs > 0) {
+	if (opts.keepalive_secs > 0 && ses.authstate.authdone) {
+		/* Avoid sending keepalives prior to auth - those are
+		not valid pre-auth packet types */
+
 		/* Send keepalives if we've been idle */
 		if (now - ses.last_packet_time_any_sent >= opts.keepalive_secs) {
 			send_msg_keepalive();
diff -r 939944f0fca9 -r 0bb16232e7c4 session.h
--- a/session.h	Wed Aug 13 22:07:43 2014 +0800
+++ b/session.h	Tue Aug 19 23:08:56 2014 +0800
@@ -47,7 +47,7 @@
 void session_cleanup();
 void send_session_identification();
 void send_msg_ignore();
-void ignore_recv_msg_request_failure();
+void ignore_recv_response();
 
 void update_channel_prio();
 
diff -r 939944f0fca9 -r 0bb16232e7c4 svr-chansession.c
--- a/svr-chansession.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/svr-chansession.c	Tue Aug 19 23:08:56 2014 +0800
@@ -53,6 +53,7 @@
 static void closechansess(struct Channel *channel);
 static int newchansess(struct Channel *channel);
 static void chansessionrequest(struct Channel *channel);
+static int sesscheckclose(struct Channel *channel);
 
 static void send_exitsignalstatus(struct Channel *channel);
 static void send_msg_chansess_exitstatus(struct Channel * channel,
@@ -61,6 +62,14 @@
 		struct ChanSess * chansess);
 static void get_termmodes(struct ChanSess *chansess);
 
+const struct ChanType svrchansess = {
+	0, /* sepfds */
+	"session", /* name */
+	newchansess, /* inithandler */
+	sesscheckclose, /* checkclosehandler */
+	chansessionrequest, /* reqhandler */
+	closechansess, /* closehandler */
+};
 
 /* required to clear environment */
 extern char** environ;
@@ -968,16 +977,6 @@
 	dropbear_exit("Child failed");
 }
 
-const struct ChanType svrchansess = {
-	0, /* sepfds */
-	"session", /* name */
-	newchansess, /* inithandler */
-	sesscheckclose, /* checkclosehandler */
-	chansessionrequest, /* reqhandler */
-	closechansess, /* closehandler */
-};
-
-
 /* Set up the general chansession environment, in particular child-exit
  * handling */
 void svr_chansessinitialise() {
diff -r 939944f0fca9 -r 0bb16232e7c4 svr-main.c
--- a/svr-main.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/svr-main.c	Tue Aug 19 23:08:56 2014 +0800
@@ -409,7 +409,7 @@
 	size_t sockpos = 0;
 	int nsock;
 
-	TRACE(("listensockets: %d to try\n", svr_opts.portcount))
+	TRACE(("listensockets: %d to try", svr_opts.portcount))
 
 	for (i = 0; i < svr_opts.portcount; i++) {
 
diff -r 939944f0fca9 -r 0bb16232e7c4 svr-session.c
--- a/svr-session.c	Wed Aug 13 22:07:43 2014 +0800
+++ b/svr-session.c	Tue Aug 19 23:08:56 2014 +0800
@@ -58,7 +58,10 @@
 	{SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open},
 	{SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof},
 	{SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close},
-	{SSH_MSG_REQUEST_FAILURE, ignore_recv_msg_request_failure}, /* for keepalive */
+	{SSH_MSG_CHANNEL_SUCCESS, ignore_recv_response},
+	{SSH_MSG_CHANNEL_FAILURE, ignore_recv_response},
+	{SSH_MSG_REQUEST_FAILURE, ignore_recv_response}, /* for keepalive */
+	{SSH_MSG_REQUEST_SUCCESS, ignore_recv_response}, /* client */
 #ifdef USING_LISTENERS
 	{SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation},
 	{SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
diff -r 939944f0fca9 -r 0bb16232e7c4 sysoptions.h
--- a/sysoptions.h	Wed Aug 13 22:07:43 2014 +0800
+++ b/sysoptions.h	Tue Aug 19 23:08:56 2014 +0800
@@ -257,4 +257,7 @@
 #define DROPBEAR_LISTEN_BACKLOG MAX_CHANNELS
 #endif
 
+/* Use this string since some implementations might special-case it */
+#define DROPBEAR_KEEPALIVE_STRING "keepalive@openssh.com"
+
 /* no include guard for this file */