annotate cli-channel.c @ 1788:1fc0012b9c38

Fix handling of replies to global requests (#112) The current code assumes that all global requests want / need a reply. This isn't always true and the request itself indicates if it wants a reply or not. It causes a specific problem with [email protected] messages. These are sent by OpenSSH after authentication to inform the client of potential other host keys for the host. This can be used to add a new type of host key or to rotate host keys. The initial information message from the server is sent as a global request, but with want_reply set to false. This means that the server doesn't expect an answer to this message. Instead the client needs to send a prove request as a reply if it wants to receive proof of ownership for the host keys. The bug doesn't cause any current problems with due to how OpenSSH treats receiving the failure message. It instead treats it as a keepalive message and further ignores it. Arguably this is a protocol violation though of Dropbear and it is only accidental that it doesn't cause a problem with OpenSSH. The bug was found when adding host keys support to libssh, which is more strict protocol wise and treats the unexpected failure message an error, also see https://gitlab.com/libssh/libssh-mirror/-/merge_requests/145 for more information. The fix here is to honor the want_reply flag in the global request and to only send a reply if the other side expects a reply.
author Dirkjan Bussink <d.bussink@gmail.com>
date Thu, 10 Dec 2020 16:13:13 +0100
parents 1c7bf9cec6c8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
107
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 /*
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 * Dropbear SSH
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 *
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 * Copyright (c) 2002-2004 Matt Johnston
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 * All rights reserved.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 *
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 * of this software and associated documentation files (the "Software"), to deal
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 * in the Software without restriction, including without limitation the rights
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11 * copies of the Software, and to permit persons to whom the Software is
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 * furnished to do so, subject to the following conditions:
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 *
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 * The above copyright notice and this permission notice shall be included in
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 * all copies or substantial portions of the Software.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 *
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 * SOFTWARE. */
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25 #include "includes.h"
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 #include "channel.h"
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27 #include "buffer.h"
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 #include "circbuffer.h"
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 #include "dbutil.h"
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 #include "session.h"
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 #include "ssh.h"
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 /* We receive channel data - only used by the client chansession code*/
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 void recv_msg_channel_extended_data() {
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 struct Channel *channel;
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37 unsigned int datatype;
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 107
diff changeset
39 TRACE(("enter recv_msg_channel_extended_data"))
107
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40
179
161557a9dde8 * fix longstanding bug with connections being closed on failure to
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
41 channel = getchannel();
107
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43 if (channel->type != &clichansess) {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 107
diff changeset
44 TRACE(("leave recv_msg_channel_extended_data: chantype is wrong"))
107
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 return; /* we just ignore it */
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46 }
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
48 datatype = buf_getint(ses.payload);
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
50 if (datatype != SSH_EXTENDED_DATA_STDERR) {
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
51 TRACE(("leave recv_msg_channel_extended_data: wrong datatype: %d",
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 107
diff changeset
52 datatype))
107
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
53 return;
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54 }
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
55
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
56 common_recv_msg_channel_data(channel, channel->errfd, channel->extrabuf);
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
57
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 107
diff changeset
58 TRACE(("leave recv_msg_channel_extended_data"))
107
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
59 }