hostapd: Fix wps button hotplug script to handle multiple radios
[openwrt.git] / package / network / services / dropbear / patches / 002-match_keepalive_to_OpenSSH.patch
1
2 # HG changeset patch
3 # User Matt Johnston <matt@ucc.asn.au>
4 # Date 1408460936 -28800
5 # Node ID 0bb16232e7c4162daa43e8618521cf453847ac16
6 # Parent  939944f0fca9b2dcdf8470bb24efcc37a3843e8b
7 Make keepalive handling more robust, this should now match what OpenSSH does
8
9 diff -r 939944f0fca9 -r 0bb16232e7c4 LICENSE
10 --- a/LICENSE   Wed Aug 13 22:07:43 2014 +0800
11 +++ b/LICENSE   Tue Aug 19 23:08:56 2014 +0800
12 @@ -8,7 +8,7 @@
13  Portions of the client-mode work are (c) 2004 Mihnea Stoenescu, under the
14  same license:
15  
16 -Copyright (c) 2002-2013 Matt Johnston
17 +Copyright (c) 2002-2014 Matt Johnston
18  Portions copyright (c) 2004 Mihnea Stoenescu
19  All rights reserved.
20  
21 diff -r 939944f0fca9 -r 0bb16232e7c4 auth.h
22 --- a/auth.h    Wed Aug 13 22:07:43 2014 +0800
23 +++ b/auth.h    Tue Aug 19 23:08:56 2014 +0800
24 @@ -106,7 +106,7 @@
25                                                                 valid */
26         unsigned int failcount; /* Number of (failed) authentication attempts.*/
27         unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have. Applies for
28 -                                                         client and server (though has differing [obvious]
29 +                                                         client and server (though has differing 
30                                                           meanings). */
31         unsigned perm_warn : 1; /* Server only, set if bad permissions on 
32                                                            ~/.ssh/authorized_keys have already been
33 diff -r 939944f0fca9 -r 0bb16232e7c4 channel.h
34 --- a/channel.h Wed Aug 13 22:07:43 2014 +0800
35 +++ b/channel.h Tue Aug 19 23:08:56 2014 +0800
36 @@ -105,6 +105,9 @@
37  void setchannelfds(fd_set *readfd, fd_set *writefd);
38  void channelio(fd_set *readfd, fd_set *writefd);
39  struct Channel* getchannel();
40 +/* Returns an arbitrary channel that is in a ready state - not
41 +being initialised and no EOF in either direction. NULL if none. */
42 +struct Channel* get_any_ready_channel();
43  
44  void recv_msg_channel_open();
45  void recv_msg_channel_request();
46 @@ -128,8 +131,10 @@
47  void recv_msg_channel_open_confirmation();
48  void recv_msg_channel_open_failure();
49  #endif
50 +void start_send_channel_request(struct Channel *channel, unsigned char *type);
51  
52  void send_msg_request_success();
53  void send_msg_request_failure();
54  
55 +
56  #endif /* _CHANNEL_H_ */
57 diff -r 939944f0fca9 -r 0bb16232e7c4 chansession.h
58 --- a/chansession.h     Wed Aug 13 22:07:43 2014 +0800
59 +++ b/chansession.h     Tue Aug 19 23:08:56 2014 +0800
60 @@ -89,7 +89,6 @@
61  #ifdef ENABLE_CLI_NETCAT
62  void cli_send_netcat_request();
63  #endif
64 -void cli_start_send_channel_request(struct Channel *channel, unsigned char *type);
65  
66  void svr_chansessinitialise();
67  extern const struct ChanType svrchansess;
68 diff -r 939944f0fca9 -r 0bb16232e7c4 cli-agentfwd.c
69 --- a/cli-agentfwd.c    Wed Aug 13 22:07:43 2014 +0800
70 +++ b/cli-agentfwd.c    Tue Aug 19 23:08:56 2014 +0800
71 @@ -234,7 +234,7 @@
72                 return;
73         }
74         
75 -       cli_start_send_channel_request(channel, "auth-agent-req@openssh.com");
76 +       start_send_channel_request(channel, "auth-agent-req@openssh.com");
77         /* Don't want replies */
78         buf_putbyte(ses.writepayload, 0);
79         encrypt_packet();
80 diff -r 939944f0fca9 -r 0bb16232e7c4 cli-chansession.c
81 --- a/cli-chansession.c Wed Aug 13 22:07:43 2014 +0800
82 +++ b/cli-chansession.c Tue Aug 19 23:08:56 2014 +0800
83 @@ -92,17 +92,6 @@
84         }
85  }
86  
87 -void cli_start_send_channel_request(struct Channel *channel, 
88 -               unsigned char *type) {
89 -
90 -       CHECKCLEARTOWRITE();
91 -       buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
92 -       buf_putint(ses.writepayload, channel->remotechan);
93 -
94 -       buf_putstring(ses.writepayload, type, strlen(type));
95 -
96 -}
97 -
98  /* Taken from OpenSSH's sshtty.c:
99   * RCSID("OpenBSD: sshtty.c,v 1.5 2003/09/19 17:43:35 markus Exp "); */
100  static void cli_tty_setup() {
101 @@ -287,7 +276,7 @@
102  
103         TRACE(("enter send_chansess_pty_req"))
104  
105 -       cli_start_send_channel_request(channel, "pty-req");
106 +       start_send_channel_request(channel, "pty-req");
107  
108         /* Don't want replies */
109         buf_putbyte(ses.writepayload, 0);
110 @@ -330,7 +319,7 @@
111                 reqtype = "shell";
112         }
113  
114 -       cli_start_send_channel_request(channel, reqtype);
115 +       start_send_channel_request(channel, reqtype);
116  
117         /* XXX TODO */
118         buf_putbyte(ses.writepayload, 0); /* Don't want replies */
119 diff -r 939944f0fca9 -r 0bb16232e7c4 cli-session.c
120 --- a/cli-session.c     Wed Aug 13 22:07:43 2014 +0800
121 +++ b/cli-session.c     Tue Aug 19 23:08:56 2014 +0800
122 @@ -70,11 +70,15 @@
123         {SSH_MSG_USERAUTH_BANNER, recv_msg_userauth_banner}, /* client */
124         {SSH_MSG_USERAUTH_SPECIFIC_60, recv_msg_userauth_specific_60}, /* client */
125         {SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_cli},
126 +       {SSH_MSG_CHANNEL_SUCCESS, ignore_recv_response},
127 +       {SSH_MSG_CHANNEL_FAILURE, ignore_recv_response},
128  #ifdef  ENABLE_CLI_REMOTETCPFWD
129         {SSH_MSG_REQUEST_SUCCESS, cli_recv_msg_request_success}, /* client */
130         {SSH_MSG_REQUEST_FAILURE, cli_recv_msg_request_failure}, /* client */
131  #else
132 -       {SSH_MSG_REQUEST_FAILURE, ignore_recv_msg_request_failure}, /* for keepalive */
133 +       /* For keepalive */
134 +       {SSH_MSG_REQUEST_SUCCESS, ignore_recv_response},
135 +       {SSH_MSG_REQUEST_FAILURE, ignore_recv_response},
136  #endif
137         {0, 0} /* End */
138  };
139 diff -r 939944f0fca9 -r 0bb16232e7c4 common-channel.c
140 --- a/common-channel.c  Wed Aug 13 22:07:43 2014 +0800
141 +++ b/common-channel.c  Tue Aug 19 23:08:56 2014 +0800
142 @@ -627,7 +627,12 @@
143                         && !channel->close_handler_done) {
144                 channel->type->reqhandler(channel);
145         } else {
146 -               send_msg_channel_failure(channel);
147 +               int wantreply;
148 +               buf_eatstring(ses.payload);
149 +               wantreply = buf_getbool(ses.payload);
150 +               if (wantreply) {
151 +                       send_msg_channel_failure(channel);
152 +               }
153         }
154  
155         TRACE(("leave recv_msg_channel_request"))
156 @@ -1134,3 +1139,30 @@
157         buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_FAILURE);
158         encrypt_packet();
159  }
160 +
161 +struct Channel* get_any_ready_channel() {
162 +       if (ses.chancount == 0) {
163 +               return NULL;
164 +       }
165 +       size_t i;
166 +       for (i = 0; i < ses.chansize; i++) {
167 +               struct Channel *chan = ses.channels[i];
168 +               if (chan
169 +                               && !(chan->sent_eof || chan->recv_eof)
170 +                               && !(chan->await_open || chan->initconn)) {
171 +                       return chan;
172 +               }
173 +       }
174 +       return NULL;
175 +}
176 +
177 +void start_send_channel_request(struct Channel *channel, 
178 +               unsigned char *type) {
179 +
180 +       CHECKCLEARTOWRITE();
181 +       buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
182 +       buf_putint(ses.writepayload, channel->remotechan);
183 +
184 +       buf_putstring(ses.writepayload, type, strlen(type));
185 +
186 +}
187 diff -r 939944f0fca9 -r 0bb16232e7c4 common-session.c
188 --- a/common-session.c  Wed Aug 13 22:07:43 2014 +0800
189 +++ b/common-session.c  Tue Aug 19 23:08:56 2014 +0800
190 @@ -394,19 +394,30 @@
191         return pos+1;
192  }
193  
194 -void ignore_recv_msg_request_failure() {
195 +void ignore_recv_response() {
196         // Do nothing
197 -       TRACE(("Ignored msg_request_failure"))
198 +       TRACE(("Ignored msg_request_response"))
199  }
200  
201  static void send_msg_keepalive() {
202         CHECKCLEARTOWRITE();
203         time_t old_time_idle = ses.last_packet_time_idle;
204 -       /* Try to force a response from the other end. Some peers will
205 -       reply with SSH_MSG_REQUEST_FAILURE, some will reply with SSH_MSG_UNIMPLEMENTED */
206 -       buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
207 -       /* A short string */
208 -       buf_putstring(ses.writepayload, "k@dropbear.nl", 0);
209 +
210 +       struct Channel *chan = get_any_ready_channel();
211 +
212 +       if (chan) {
213 +               /* Channel requests are preferable, more implementations
214 +               handle them than SSH_MSG_GLOBAL_REQUEST */
215 +               TRACE(("keepalive channel request %d", chan->index))
216 +               start_send_channel_request(chan, DROPBEAR_KEEPALIVE_STRING);
217 +       } else {
218 +               TRACE(("keepalive global request"))
219 +               /* Some peers will reply with SSH_MSG_REQUEST_FAILURE, 
220 +               some will reply with SSH_MSG_UNIMPLEMENTED, some will exit. */
221 +               buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); 
222 +               buf_putstring(ses.writepayload, DROPBEAR_KEEPALIVE_STRING,
223 +                       strlen(DROPBEAR_KEEPALIVE_STRING));
224 +       }
225         buf_putbyte(ses.writepayload, 1); /* want_reply */
226         encrypt_packet();
227  
228 @@ -435,7 +446,10 @@
229                 send_msg_kexinit();
230         }
231         
232 -       if (opts.keepalive_secs > 0) {
233 +       if (opts.keepalive_secs > 0 && ses.authstate.authdone) {
234 +               /* Avoid sending keepalives prior to auth - those are
235 +               not valid pre-auth packet types */
236 +
237                 /* Send keepalives if we've been idle */
238                 if (now - ses.last_packet_time_any_sent >= opts.keepalive_secs) {
239                         send_msg_keepalive();
240 diff -r 939944f0fca9 -r 0bb16232e7c4 session.h
241 --- a/session.h Wed Aug 13 22:07:43 2014 +0800
242 +++ b/session.h Tue Aug 19 23:08:56 2014 +0800
243 @@ -47,7 +47,7 @@
244  void session_cleanup();
245  void send_session_identification();
246  void send_msg_ignore();
247 -void ignore_recv_msg_request_failure();
248 +void ignore_recv_response();
249  
250  void update_channel_prio();
251  
252 diff -r 939944f0fca9 -r 0bb16232e7c4 svr-chansession.c
253 --- a/svr-chansession.c Wed Aug 13 22:07:43 2014 +0800
254 +++ b/svr-chansession.c Tue Aug 19 23:08:56 2014 +0800
255 @@ -53,6 +53,7 @@
256  static void closechansess(struct Channel *channel);
257  static int newchansess(struct Channel *channel);
258  static void chansessionrequest(struct Channel *channel);
259 +static int sesscheckclose(struct Channel *channel);
260  
261  static void send_exitsignalstatus(struct Channel *channel);
262  static void send_msg_chansess_exitstatus(struct Channel * channel,
263 @@ -61,6 +62,14 @@
264                 struct ChanSess * chansess);
265  static void get_termmodes(struct ChanSess *chansess);
266  
267 +const struct ChanType svrchansess = {
268 +       0, /* sepfds */
269 +       "session", /* name */
270 +       newchansess, /* inithandler */
271 +       sesscheckclose, /* checkclosehandler */
272 +       chansessionrequest, /* reqhandler */
273 +       closechansess, /* closehandler */
274 +};
275  
276  /* required to clear environment */
277  extern char** environ;
278 @@ -968,16 +977,6 @@
279         dropbear_exit("Child failed");
280  }
281  
282 -const struct ChanType svrchansess = {
283 -       0, /* sepfds */
284 -       "session", /* name */
285 -       newchansess, /* inithandler */
286 -       sesscheckclose, /* checkclosehandler */
287 -       chansessionrequest, /* reqhandler */
288 -       closechansess, /* closehandler */
289 -};
290 -
291 -
292  /* Set up the general chansession environment, in particular child-exit
293   * handling */
294  void svr_chansessinitialise() {
295 diff -r 939944f0fca9 -r 0bb16232e7c4 svr-main.c
296 --- a/svr-main.c        Wed Aug 13 22:07:43 2014 +0800
297 +++ b/svr-main.c        Tue Aug 19 23:08:56 2014 +0800
298 @@ -409,7 +409,7 @@
299         size_t sockpos = 0;
300         int nsock;
301  
302 -       TRACE(("listensockets: %d to try\n", svr_opts.portcount))
303 +       TRACE(("listensockets: %d to try", svr_opts.portcount))
304  
305         for (i = 0; i < svr_opts.portcount; i++) {
306  
307 diff -r 939944f0fca9 -r 0bb16232e7c4 svr-session.c
308 --- a/svr-session.c     Wed Aug 13 22:07:43 2014 +0800
309 +++ b/svr-session.c     Tue Aug 19 23:08:56 2014 +0800
310 @@ -58,7 +58,10 @@
311         {SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open},
312         {SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof},
313         {SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close},
314 -       {SSH_MSG_REQUEST_FAILURE, ignore_recv_msg_request_failure}, /* for keepalive */
315 +       {SSH_MSG_CHANNEL_SUCCESS, ignore_recv_response},
316 +       {SSH_MSG_CHANNEL_FAILURE, ignore_recv_response},
317 +       {SSH_MSG_REQUEST_FAILURE, ignore_recv_response}, /* for keepalive */
318 +       {SSH_MSG_REQUEST_SUCCESS, ignore_recv_response}, /* client */
319  #ifdef USING_LISTENERS
320         {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation},
321         {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
322 diff -r 939944f0fca9 -r 0bb16232e7c4 sysoptions.h
323 --- a/sysoptions.h      Wed Aug 13 22:07:43 2014 +0800
324 +++ b/sysoptions.h      Tue Aug 19 23:08:56 2014 +0800
325 @@ -257,4 +257,7 @@
326  #define DROPBEAR_LISTEN_BACKLOG MAX_CHANNELS
327  #endif
328  
329 +/* Use this string since some implementations might special-case it */
330 +#define DROPBEAR_KEEPALIVE_STRING "keepalive@openssh.com"
331 +
332  /* no include guard for this file */
333