Incorrect protocol implementation by OpenSSH? - SSH
This is a discussion on Incorrect protocol implementation by OpenSSH? - SSH ; I am testing against an embedded SSH server that does not allow
clients to execute commands other than through an interactive shell. That
is, when the server receives an SSH_MSG_CHANNEL_REQUEST message to
execute commands, the server replies with SSH_MSG_CHANNEL_FAILURE. The
...
-
Incorrect protocol implementation by OpenSSH?
I am testing against an embedded SSH server that does not allow
clients to execute commands other than through an interactive shell. That
is, when the server receives an SSH_MSG_CHANNEL_REQUEST message to
execute commands, the server replies with SSH_MSG_CHANNEL_FAILURE. The
issue that I am encountering is that OpenSSH (at least version 4.1 does)
sends an SSH_MSG_UNIMPLEMENTED message in reply.
Why? I can't believe that OpenSSH does not implement
SSH_MSG_CHANNEL_FAILURE message processing - this message is most
certainly contemplated in the standard. It is true that the
SSH_MSG_CHANNEL_REQUEST message sent by the OpenSSH client contains a 0
byte in the want-reply field. However, my interpretation of the relevant
portion of the standard (RFC 4254, section 5.4) is that the server should
send an SSH_MSG_CHANNEL_FAILURE message in this case regardless of the
contents of the want-reply field.
Is this not the correct interpretation? The PuTTY client (at
least version 0.60) does seem to agree, for it just terminates the
connection at that point without sending any SSH_MSG_UNIMPLEMENTED
messages.
-
Re: Incorrect protocol implementation by OpenSSH?
"H.K. Kingston-Smith" writes:
> I am testing against an embedded SSH server that does not allow
>clients to execute commands other than through an interactive shell. That
>is, when the server receives an SSH_MSG_CHANNEL_REQUEST message to
>execute commands, the server replies with SSH_MSG_CHANNEL_FAILURE. The
>issue that I am encountering is that OpenSSH (at least version 4.1 does)
>sends an SSH_MSG_UNIMPLEMENTED message in reply.
> Why? I can't believe that OpenSSH does not implement
>SSH_MSG_CHANNEL_FAILURE message processing - this message is most
>certainly contemplated in the standard. It is true that the
>SSH_MSG_CHANNEL_REQUEST message sent by the OpenSSH client contains a 0
>byte in the want-reply field. However, my interpretation of the relevant
>portion of the standard (RFC 4254, section 5.4) is that the server should
>send an SSH_MSG_CHANNEL_FAILURE message in this case regardless of the
>contents of the want-reply field.
Well, I think "not implimented " and "failure" are different concept. The
second says "Yes, what you tried to send me is fine, but somewhere I
screwed up and the command failed" The first says" You are not supposed to
be trying what you just tried." Your situation seems closer to this than to
the "I screwed up" situation.
> Is this not the correct interpretation? The PuTTY client (at
>least version 0.60) does seem to agree, for it just terminates the
>connection at that point without sending any SSH_MSG_UNIMPLEMENTED
>messages.
?? I do not understand. Putty is the client. It is the one requesting the
service, not delivering it.
-
Re: Incorrect protocol implementation by OpenSSH?
On Thu, 27 Sep 2007 22:04:07 +0000, Unruh wrote:
> "H.K. Kingston-Smith" writes:
>
>> I am testing against an embedded SSH server that does not allow
>>clients to execute commands other than through an interactive shell.
>>That is, when the server receives an SSH_MSG_CHANNEL_REQUEST message to
>>execute commands, the server replies with SSH_MSG_CHANNEL_FAILURE. The
>>issue that I am encountering is that OpenSSH (at least version 4.1 does)
>>sends an SSH_MSG_UNIMPLEMENTED message in reply.
>
>> Why? I can't believe that OpenSSH does not implement
>>SSH_MSG_CHANNEL_FAILURE message processing - this message is most
>>certainly contemplated in the standard. It is true that the
>>SSH_MSG_CHANNEL_REQUEST message sent by the OpenSSH client contains a 0
>>byte in the want-reply field. However, my interpretation of the relevant
>>portion of the standard (RFC 4254, section 5.4) is that the server
>>should send an SSH_MSG_CHANNEL_FAILURE message in this case regardless
>>of the contents of the want-reply field.
>
> Well, I think "not implimented " and "failure" are different concept.
> The second says "Yes, what you tried to send me is fine, but somewhere I
> screwed up and the command failed" The first says" You are not supposed
> to be trying what you just tried." Your situation seems closer to this
> than to the "I screwed up" situation.
My contention is that the server is acting correctly, whereas the
OpenSSH client is not.
>
>> Is this not the correct interpretation? The PuTTY client (at
>>least version 0.60) does seem to agree, for it just terminates the
>>connection at that point without sending any SSH_MSG_UNIMPLEMENTED
>>messages.
>
> ?? I do not understand. Putty is the client. It is the one requesting
> the service, not delivering it.
I think that you have misunderstood what I wrote. The server
sends SSH_MSG_CHANNEL_FAILURE because, like I said, it can't execute
single command lines. When receiving this from the server, an OpenSSH
client replies with SSH_MSG_UNIMPLEMENTED. My question is, Why is it
replying with that?
According to the standard (RFC 4253, section 11.4) I believe that
this message should be sent when a message has been received that has not
been recognized. Does this mean that OpenSSH can't recognize an
SSH_MSG_CHANNEL_FAILURE message? Unlikely. It's more like it wasn't
expecting it. If the former is true, OpenSSH is surprisingly incomplete;
if the latter is true, I believe that it is not acting in agreement with
the standard. This is the clarification I am asking for.
As far as PuTTY is concerned, on receiving
SSH_MSG_CHANNEL_FAILURE, the PuTTY client immediately closes the
connection, printing out a diagnostic for the user to the effect that the
server refuses to execute the command sent. That is, it recognizes the
SSH_MSG_CHANNEL_FAILURE message and proceeds somewhat drastically but, in
my opinion, and unlike OpenSSH, in agreement with the standard.
Clarifications are welcome.
-
Re: Incorrect protocol implementation by OpenSSH?
In article ,
H.K. Kingston-Smith wrote:
> Why? I can't believe that OpenSSH does not implement
>SSH_MSG_CHANNEL_FAILURE message processing - this message is most
>certainly contemplated in the standard. It is true that the
>SSH_MSG_CHANNEL_REQUEST message sent by the OpenSSH client contains a 0
>byte in the want-reply field. However, my interpretation of the relevant
>portion of the standard (RFC 4254, section 5.4) is that the server should
>send an SSH_MSG_CHANNEL_FAILURE message in this case regardless of the
>contents of the want-reply field.
That interpretation is incorrect. The RFC says:
If 'want reply' is FALSE, no response will be sent to the request.
Otherwise, the recipient responds with either
SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, or request-specific
continuation messages. If the request is not recognized or is not
supported for the channel, SSH_MSG_CHANNEL_FAILURE is returned.
The "Otherwise" obviously qualifies its own sentence, but it implicitly
qualifies the last sentence as well.
This is clear if you think about how responses to
SSH_MSG_CHANNEL_REQUESTs are matched up with the requests. They don't
have sequence numbers, so the only way to match them up is to count the
number of requests (with 'want reply' true) and responses. If requests
with 'want reply' false could generate SSH_MSG_CHANNEL_FAILURE, it would
be impossible to reliably pair up requests and responses.
What OpenSSH should really do is disconnect with
SSH_DISCONNECT_PROTOCOL_ERROR, but emitting SSH_MSG_UNIMPLEMENTED isn't
surprising. PuTTY would probably do such a thing in equivalent
circumstances, though now that I've noticed it I might try to correct
that.
> Is this not the correct interpretation? The PuTTY client (at
>least version 0.60) does seem to agree, for it just terminates the
>connection at that point without sending any SSH_MSG_UNIMPLEMENTED
>messages.
PuTTY sets 'want reply' to true, since it unsurprisingly cares whether
the request for a command succeeded. Thus it's expecting an
SSH_MSG_CHANNEL_SUCCESS or an SSH_MSG_CHANNEL_FAILURE.
--
Ben Harris
-
Re: Incorrect protocol implementation by OpenSSH?
On Fri, 28 Sep 2007 12:18:33 +0100, Ben Harris wrote:
> In article , H.K. Kingston-Smith
> wrote:
>> Why? I can't believe that OpenSSH does not implement
>>SSH_MSG_CHANNEL_FAILURE message processing - this message is most
>>certainly contemplated in the standard. It is true that the
>>SSH_MSG_CHANNEL_REQUEST message sent by the OpenSSH client contains a 0
>>byte in the want-reply field. However, my interpretation of the relevant
>>portion of the standard (RFC 4254, section 5.4) is that the server
>>should send an SSH_MSG_CHANNEL_FAILURE message in this case regardless
>>of the contents of the want-reply field.
>
> That interpretation is incorrect. The RFC says:
>
> If 'want reply' is FALSE, no response will be sent to the request.
> Otherwise, the recipient responds with either
> SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, or request-specific
> continuation messages. If the request is not recognized or is not
> supported for the channel, SSH_MSG_CHANNEL_FAILURE is returned.
>
> The "Otherwise" obviously qualifies its own sentence, but it implicitly
> qualifies the last sentence as well.
That is a valid interpretation. I still think that the standard
ought to have been less ambiguous though. Now if this interpretation is
the one that the standard intended, what is the subsequent message
exchange supposed to be like?
If the server S does not support a certain type of request (exec,
in this case) and the client C sends an SSH_MSG_CHANNEL_REQUEST message
of that type, with want-reply set to 0, what is S supposed to do? S must
send something back; otherwise, the exchange will be deadlocked. Is it
supposed to disconnect?
> This is clear if you think about how responses to
> SSH_MSG_CHANNEL_REQUESTs are matched up with the requests. They don't
> have sequence numbers,
Hmm... I thought that every single packet exchanged has a
sequence number associated with it - see RFC 4253, section 6.4. The
standard seems to be using "packet" and "SSH message" interchangeably,
but I may be missing something. Still, I think that these requests, like
any other SSH message, have a unique sequence number associated - after
all, how is the MAC computed for each message (when it is computed)?
> so the only way to match them up is to count the
> number of requests (with 'want reply' true) and responses. If requests
> with 'want reply' false could generate SSH_MSG_CHANNEL_FAILURE, it would
> be impossible to reliably pair up requests and responses.
>
> What OpenSSH should really do is disconnect with
> SSH_DISCONNECT_PROTOCOL_ERROR, but emitting SSH_MSG_UNIMPLEMENTED isn't
> surprising. PuTTY would probably do such a thing in equivalent
> circumstances, though now that I've noticed it I might try to correct
> that.
>
>> Is this not the correct interpretation? The PuTTY client (at
>>least version 0.60) does seem to agree, for it just terminates the
>>connection at that point without sending any SSH_MSG_UNIMPLEMENTED
>>messages.
>
> PuTTY sets 'want reply' to true, since it unsurprisingly cares whether
> the request for a command succeeded. Thus it's expecting an
> SSH_MSG_CHANNEL_SUCCESS or an SSH_MSG_CHANNEL_FAILURE.
So what's the OpenSSL client doing here? It does not want to have
a reply of any sort. What is it then expecting for the server to do if
the server can't honor the request?
-
Re: Incorrect protocol implementation by OpenSSH?
> On Fri, 28 Sep 2007 12:18:33 +0100, Ben Harris wrote:
>> This is clear if you think about how responses to
>> SSH_MSG_CHANNEL_REQUESTs are matched up with the requests. They don't
>> have sequence numbers,
H.K. Kingston-Smith wrote:
> Hmm... I thought that every single packet exchanged has a
> sequence number associated with it - see RFC 4253, section 6.4.
You miss Ben's point. Yes, every message (or packet - you're correct
in thinking the two terms are interchangeable in this context) has a
sequence number _associated_ with it. But what Ben is saying here is
that SSH_MSG_CHANNEL_SUCCESS and SSH_MSG_CHANNEL_FAILURE messages do
not _quote_ the sequence number of the SSH_MSG_CHANNEL_REQUEST they
are responding to.
Therefore, a server sending CHANNEL_FAILURE for a message without
want_reply set risks completely confusing the client. Suppose a
client submits two CHANNEL_REQUESTs, of which the first does not
have want_reply set and the second does. It then receives a
CHANNEL_FAILURE. It assumes (because it has no way to tell
otherwise) that this was for the second request. If the server
actually sent it in response to the first, there is no reliable way
for the client to unconfuse itself.
--
Simon Tatham "You may call that a cheap shot.
I prefer to think of it as good value."
-
Re: Incorrect protocol implementation by OpenSSH?
On Fri, 28 Sep 2007 17:18:17 +0100, Simon Tatham wrote:
>> On Fri, 28 Sep 2007 12:18:33 +0100, Ben Harris wrote:
>>> This is clear if you think about how responses to
>>> SSH_MSG_CHANNEL_REQUESTs are matched up with the requests. They don't
>>> have sequence numbers,
>
> H.K. Kingston-Smith wrote:
>> Hmm... I thought that every single packet exchanged has a
>> sequence number associated with it - see RFC 4253, section 6.4.
>
> You miss Ben's point. Yes, every message (or packet - you're correct in
> thinking the two terms are interchangeable in this context) has a
> sequence number _associated_ with it. But what Ben is saying here is
> that SSH_MSG_CHANNEL_SUCCESS and SSH_MSG_CHANNEL_FAILURE messages do not
> _quote_ the sequence number of the SSH_MSG_CHANNEL_REQUEST they are
> responding to.
Point taken.
> Therefore, a server sending CHANNEL_FAILURE for a message without
> want_reply set risks completely confusing the client. Suppose a client
> submits two CHANNEL_REQUESTs, of which the first does not have
> want_reply set and the second does. It then receives a CHANNEL_FAILURE.
> It assumes (because it has no way to tell otherwise) that this was for
> the second request. If the server actually sent it in response to the
> first, there is no reliable way for the client to unconfuse itself.
Fair enough. The question still remains: What is a server
supposed to do when receiving an SSH_MSG_CHANNEL_REQUEST containing a
request that it can't honor, when the request has the want-reply field
set to 0? Is it not the case that if the server does not send some SSH
packet back the conversation will be deadlocked? And if therefore it has
to send some SSH packet(s) back, what is it it has to send?
-
Re: Incorrect protocol implementation by OpenSSH?
In article ,
H.K. Kingston-Smith wrote:
>On Fri, 28 Sep 2007 12:18:33 +0100, Ben Harris wrote:
> If the server S does not support a certain type of request (exec,
>in this case) and the client C sends an SSH_MSG_CHANNEL_REQUEST message
>of that type, with want-reply set to 0, what is S supposed to do?
Ignore it. If the client wanted a reply, it would have set 'want reply'
to true. If 'want reply' is false, the client isn't expecting a reply
and is likely to be terribly confused if one arrives.
> So what's the OpenSSL client doing here? It does not want to have
>a reply of any sort. What is it then expecting for the server to do if
>the server can't honor the request?
I suspect the OpenSSH maintainers simply haven't considered the
possibility, or hadn't in 2000 when the code was written. RFC 4254
(section 6.5) certainly counsels against such optimism:
It is RECOMMENDED that the reply to these messages be requested and
checked.
There are usually some of OpenSSH's authors lurking around here, so they
might be able to explain this decision, or you may have to ask them
directly.
--
Ben Harris
-
Re: Incorrect protocol implementation by OpenSSH?
On Fri, 28 Sep 2007 19:14:35 +0100, Ben Harris wrote:
> In article , H.K. Kingston-Smith
> wrote:
>>On Fri, 28 Sep 2007 12:18:33 +0100, Ben Harris wrote:
>> If the server S does not support a certain type of request (exec,
>>in this case) and the client C sends an SSH_MSG_CHANNEL_REQUEST message
>>of that type, with want-reply set to 0, what is S supposed to do?
>
> Ignore it. If the client wanted a reply, it would have set 'want reply'
> to true. If 'want reply' is false, the client isn't expecting a reply
> and is likely to be terribly confused if one arrives.
>
>> So what's the OpenSSL client doing here? It does not want to have
>>a reply of any sort. What is it then expecting for the server to do if
>>the server can't honor the request?
>
> I suspect the OpenSSH maintainers simply haven't considered the
> possibility, or hadn't in 2000 when the code was written. RFC 4254
> (section 6.5) certainly counsels against such optimism:
>
> It is RECOMMENDED that the reply to these messages be requested and
> checked.
>
> There are usually some of OpenSSH's authors lurking around here, so they
> might be able to explain this decision, or you may have to ask them
> directly.
I have just checked out that an SSH conversation between an
OpenSSH (I just noticed that I wrote OpenSSL in several places instead;
my apologies for that) server and an OpenSSH client does indeed end up
deadlocked in the situation I describe (I used version 4.7p1, changing
the channel request for a shell so that the client sends a request for a
"thell" :-)
Based on this, ignoring the request is not an option: The server
should send something back. What should it send back? The standard does
not seem to have anything to say about this.
Can anybody throw some further light into this?
-
Re: Incorrect protocol implementation by OpenSSH?
H.K. Kingston-Smith wrote:
> Fair enough. The question still remains: What is a server
> supposed to do when receiving an SSH_MSG_CHANNEL_REQUEST containing a
> request that it can't honor, when the request has the want-reply field
> set to 0?
Nothing. If it can honour the request, it should do so and send no
packet back; otherwise, it should do nothing and send no packet
back.
> Is it not the case that if the server does not send some SSH
> packet back the conversation will be deadlocked?
Not in general. Consider non-essential CHANNEL_REQUESTs such as
"pty-req" or "x11-req". The session can still proceed in the absence
of those, and if they're refused then there's not much the client
can do about it anyway, so a client might perfectly well decide not
to bother finding out whether they worked or not; it just requests
them, and the user either ends up with them enabled or not. In this
situation there's no reason why the session should be deadlocked if
one of those requests isn't granted.
The "exec" request is a less obviously useful one to set
want_reply=0 on, admittedly. But if the client chooses to discard
enough error data that it can't work out that it's in a deadlock
situation, that's its own fault, and it's not the server's job to
second-guess it.
--
Simon Tatham These are my opinions. There are many
like them but these ones are mine.
-
Re: Incorrect protocol implementation by OpenSSH?
On Sat, 29 Sep 2007 00:33:08 +0100, Simon Tatham wrote:
> H.K. Kingston-Smith wrote:
>> Fair enough. The question still remains: What is a server supposed to
>> do when receiving an SSH_MSG_CHANNEL_REQUEST containing a request that
>> it can't honor, when the request has the want-reply field set to 0?
>
> Nothing. If it can honour the request, it should do so and send no
> packet back; otherwise, it should do nothing and send no packet back.
>
>> Is it not the case that if the server does not send some SSH packet
>> back the conversation will be deadlocked?
>
> Not in general. Consider non-essential CHANNEL_REQUESTs such as
> "pty-req" or "x11-req". The session can still proceed in the absence of
> those, and if they're refused then there's not much the client can do
> about it anyway, so a client might perfectly well decide not to bother
> finding out whether they worked or not; it just requests them, and the
> user either ends up with them enabled or not. In this situation there's
> no reason why the session should be deadlocked if one of those requests
> isn't granted.
That makes sense.
> The "exec" request is a less obviously useful one to set want_reply=0
> on, admittedly. But if the client chooses to discard enough error data
> that it can't work out that it's in a deadlock situation, that's its own
> fault, and it's not the server's job to second-guess it.
I am not sure I entirely agree with that. If the client specifies
want-reply = 0 and the server does not support "exec", how can the client
know the reason behind the deadlock?
It would seem that an "exec" (or "shell") request with want-reply
set to 0 sent to a server that does not support such a capability will
necessarily lead to a deadlock. Is this right in general? It most
certainly is when dealing with OpenSSH clients.
-
Re: Incorrect protocol implementation by OpenSSH?
H.K. Kingston-Smith wrote:
> I am not sure I entirely agree with that. If the client specifies
> want-reply = 0 and the server does not support "exec", how can the client
> know the reason behind the deadlock?
It can't.
> It would seem that an "exec" (or "shell") request with want-reply
> set to 0 sent to a server that does not support such a capability will
> necessarily lead to a deadlock. Is this right in general?
I think so, yes. But you cannot deduce from that that the _server_
should do something different in that situation: it's the _client's_
fault for setting want_reply=0, and so the client should have done
something different. It isn't the server's job to exceed the
protocol specification in order to compensate for a broken client;
it's the client's job not to be broken in the first place.
--
Simon Tatham "infinite loop _see_ loop, infinite"
- Index, Borland Pascal Language Guide
-
Re: Incorrect protocol implementation by OpenSSH?
In article ,
H.K. Kingston-Smith wrote:
> I have just checked out that an SSH conversation between an
>OpenSSH (I just noticed that I wrote OpenSSL in several places instead;
>my apologies for that) server and an OpenSSH client does indeed end up
>deadlocked in the situation I describe (I used version 4.7p1, changing
>the channel request for a shell so that the client sends a request for a
>"thell" :-)
>
> Based on this, ignoring the request is not an option: The server
>should send something back. What should it send back?
If you really want to work around what seems to be an OpenSSH bug, I'd
suggest forcibly closing the channel over which the request arrived.
This will avoid killing any other channels that might be running over
the same connection, but should make it clear to the client that no good
will come of the channel. If you do this, it should only be in
response to a "shell" or "exec" request with 'want reply' false, and
preferably only if the client has identified itself as OpenSSH. That
way, you'll minimise the chances of causing new problems with sensible
clients.
--
Ben Harris
-
Re: Incorrect protocol implementation by OpenSSH?
On Sat, 29 Sep 2007 08:49:36 +0100, Simon Tatham wrote:
> H.K. Kingston-Smith wrote:
>> I am not sure I entirely agree with that. If the client specifies
>> want-reply = 0 and the server does not support "exec", how can the
>> client know the reason behind the deadlock?
>
> It can't.
>
>> It would seem that an "exec" (or "shell") request with want-reply
>> set to 0 sent to a server that does not support such a capability will
>> necessarily lead to a deadlock. Is this right in general?
>
> I think so, yes. But you cannot deduce from that that the _server_
> should do something different in that situation: it's the _client's_
> fault for setting want_reply=0, and so the client should have done
> something different. It isn't the server's job to exceed the protocol
> specification in order to compensate for a broken client; it's the
> client's job not to be broken in the first place.
That's right; OpenSSH is broken here.
-
Re: Incorrect protocol implementation by OpenSSH?
On Sat, 29 Sep 2007 13:23:34 +0100, Ben Harris wrote:
> In article , H.K. Kingston-Smith
> wrote:
>> I have just checked out that an SSH conversation between an
>>OpenSSH (I just noticed that I wrote OpenSSL in several places instead;
>>my apologies for that) server and an OpenSSH client does indeed end up
>>deadlocked in the situation I describe (I used version 4.7p1, changing
>>the channel request for a shell so that the client sends a request for a
>>"thell" :-)
>>
>> Based on this, ignoring the request is not an option: The server
>>should send something back. What should it send back?
>
> If you really want to work around what seems to be an OpenSSH bug, I'd
> suggest forcibly closing the channel over which the request arrived.
That's a good suggestion. Thanks.
> This will avoid killing any other channels that might be running over
> the same connection, but should make it clear to the client that no good
> will come of the channel. If you do this, it should only be in response
> to a "shell" or "exec" request with 'want reply' false, and preferably
> only if the client has identified itself as OpenSSH. That way, you'll
> minimise the chances of causing new problems with sensible clients.
-
Re: Incorrect protocol implementation by OpenSSH?
On 2007-09-28, Ben Harris wrote:
[...]
> There are usually some of OpenSSH's authors lurking around here, so they
> might be able to explain this decision, or you may have to ask them
> directly.
I think that's just me these days, however the code in question predates
me so I'm afraid I can't shed any light on this.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.