Subject: Re: drafts appear to have been published; please review.

From: Markus Friedl <[email-masked]>
Date: Thu, 2 Aug 2001 00:15:31 +0200

On Tue, Jul 31, 2001 at 06:06:37PM -0600, Joseph Galbraith wrote:
> Hmm... the drafts appear to have changed in a way
> that totally confuses my diff tool... is anyone
> else having a bad time with this or is my diff
> tool just complete drain bamaged?

try to get wdiff from some gnu site. wdiff -p works fine for me.

-m

---

From: "Joseph Galbraith" <[email-masked]>
Date: Fri, 3 Aug 2001 14:37:46 -0600

Regarding global and channel requests... I believe more
information on failure and more flexibility on success
is needed.

- In the connection draft, section 2, we should change

     byte      SSH_MSG_REQUEST_SUCCESS

  to

     byte      SSH_MSG_REQUEST_SUCCESS
     string    request-name
     ... request-specific data follows

  All current requests (unless otherwise specified) have no
  request specific data.

  If existing implementations won't safely ignore the extra
  packet data, we should change the packet number and
  deprecate the existing one.

- In the connection draft, section 2, we should change

    byte      SSH_MSG_REQUEST_FAILURE

  to

    byte      SSH_MSG_REQUEST_FAILURE
    string    request-name
    uint32    reason
    string    additional text (UTF-8)
    string    language

    where reason is one of

    ADMIN_PROHIBITED = 0
    UNKNOWN_UNSUPPORTED = 1
    RESOURCE_SHORTAGE = 2
    GENERAL_FAILURE = 3

  I think existing implementations should simply ignore the
  extra data.  If not, we should give this code a new value,
  i.e., SSH_MSG_REQUEST_FAILURE2, and deprecate the old
  message.

- If global requests are issued asynchronously (is this allowed?)
  are there any guarantees for order of completion?  Do we need
  to be able to tag requests?

- In the connection draft, section 3.4, we should change

     byte      SSH_MSG_CHANNEL_SUCCESS
     uint32    recipient_channel

  to

     byte      SSH_MSG_CHANNEL_SUCCESS
     uint32    recipient_channel
     string    request-name
     ...request specific data

  If existing implementations won't safely ignore the extra
  packet data, we should change the packet number and
  deprecate the existing one.

- In the connection draft, section 3.4, we should change

     byte      SSH_MSG_CHANNEL_FAILURE
     uint32    recipient_channel

  to

     byte      SSH_MSG_CHANNEL_FAILURE
     uint32    recipient_channel
     string    request-name
     uint32    reason
     string    addition descriptive text (UTF8)
     string    language

  Again, I believe current implementations should discard
  the extra data at the end of the packet -- if not, we
  should change the message number and deprecate this
  existing message.

- In the connection draft, section 3.4, we explicitly
  allow requests to be sent without waiting for completion.

  Are there any ordering guarantees?

  Do we need to tag the requests so responses can be
  associated with specific requests?

Joseph Galbraith
[email-masked]

---

From: "Joseph Galbraith" <[email-masked]>
Date: Fri, 3 Aug 2001 14:39:07 -0600

In the connection draft, section 2, we should declare
that global request names follow the DNS extensibility naming
convention.

In the connection draft, section 3.4, we should declare
that channel request names follow the DNS extensibility
naming convention.

In the connection draft, section 4.5 we should note that
subsystem names follow DNS extension convention.

Joseph Galbraith
[email-masked]

---

From: "Joseph Galbraith" <[email-masked]>
Date: Fri, 3 Aug 2001 14:39:20 -0600

In the transport draft, Section 4.2, do we need a comment 
about the zlib bug? (If I remember the discussion correctly,
zlib as implemented in existing SSH servers isn't really
zlib as defined in RFC1950 and RFC1951)

Joseph Galbraith
[email-masked]

---

From: "Joseph Galbraith" <[email-masked]>
Date: Fri, 3 Aug 2001 14:40:04 -0600

In the transport draft, Section 4.6, we specify that
public keys are, in general encoded as:

     string   certificate or public key format identifier
     byte[n]  key/certificate data

However, the sections on x.509 are less clear.  And in fact,
SSH Communications current x.509 implementation omits the
string, including only the certificate data -- although
the string is included when sending signatures.

I would suggest we include the following text in section
documenting "x509v3-sign-rsa":

The "x509v3-sign-rsa" key format has the following specific encoding:

     string    "x509v3-sign-rsa"
     byte[n]   x.509v3 compatible der encoded certificate data

The resulting signature is encoded as follows:

     string    "x509v3-sign-rsa"
     string    rsa_signature_blob

Variants to this go in the other x.509 sections as appropriate.

In addition, I would suggest that we note that signatures
made with x509v3-sign-rsa keys MUST use the SHA-1 hash, and
be done using PKCS1.

Joseph Galbraith
[email-masked]

---

From: "Joseph Galbraith" <[email-masked]>
Date: Fri, 3 Aug 2001 14:42:55 -0600

There are a number of places in the draft where
formatting is a problem.

  o Indentation is often a little screwy making it
    seem like some things are associated or subsections
    when the are not.

  o In arch, pg. 8, section 4, the headings "boolean",
    "uint32", "string", etc. all look like they are
    associated with the section above them.

  o In the transport, pg 6, section 4, the documentation
    for packet format is messed up, both indentation and
    vertical white space.

  o In the transport draft, Section 5.1, the section
    labeled server_host_key_algorithms, a blank line
    between paragraphs would help readability.

    (The same applies anyplace where paragraphs are not
    currently separated by blank lines.)

  o In the connection draft table of contents, there appear
    to be extra characters for 4.3.1 and 4.3.2 -- unless these
    have meaning I'm not aware of?

  o In the transport draft, Section 4.2, 4.3, 4.4, and 4.5 there
    is a missing reference with regards to defining additional
    methods.

Joseph Galbraith
[email-masked]

---

From: "Joseph Galbraith" <[email-masked]>
Date: Fri, 3 Aug 2001 14:48:31 -0600

Here are a number of comments on a fresh read of the
drafts, something I haven't done for a while.

- In the userauth draft, Section 6, we refer to the
  "client username on the remote host"  Since the
  "user name" field is the username on the remote
  host (from the clients point for view) I think
  this must really mean the "username on the client"

  In any case, "remote host" is vague, since we don't
  really know what point of view we are using, client
  or server.  I would suggest this just become "username
  on the client" or perhaps "client user name"

- In the connection draft, section 4.3.1, we should note
  that the x11 authentication cookie MUST be hexadecimal
  encoded.

- In the connection draft, near section 4.7 should we add
  a "terminal-mode-change" message which could be used to
  notify the other side about mode changes (for example
  from input cooked to raw mode)

  This might allow optimizations for long lag time links
  (satellite) if the client wanted to cook lines on it's own.

  I would suggest

     byte      SSH_MSG_CHANNEL_REQUEST
     uint32    recipient_channel
     string    "terminal-mode-change"
     boolean   FALSE
     string    encoded terminal modes
     string    TERM environment variable value

  We may not want to do this -- we are trying to finish
  the drafts -- and it doesn't have a proven usefulness
  (though I've had occasion to wish I could do this as we
  tried to work around NT's lack of real PTYs.)

- In the connection draft, section 5.1, we should specify
  text like this:

  The response to the "tcpip-forward" request will look like:

     byte SSH_MSG_GLOBAL_REQUEST_SUCCESS
     string "tcpip-forward"
     uint32 port that was bound on server

  We should also explicitly allow binding to port
  0 to indicate any port.

Joseph Galbraith
[email-masked]

---

From: [email-masked] (Niels M�ller)
Date: 08 Aug 2001 14:31:33 +0200

> information on failure and more flexibility on success

Why? I believe global requests should always be answered in order, and
channel_requests on the same channel should also be answered in order.
This is analogous to the requirements for userauth-requests, which I
think are spelled out more clearly in the documents.

If you really want to be able to permute responses, you should add a
an id to each request, but I don't think that is really needed. Adding
just the request-name to the responses seems useless.

>      ... request-specific data follows

I don't think adding the request name here is terribly useful. As for
request specific data, that might be useful, but we don't need to do
anything about that now.

The day I invent a request where it makes sense to have additional
data, I'll add it. Implementations that don't know about the new
request will never see the extended response packet, because they
never send the new request.

>   deprecate the existing one.

Datapoint: LSH generally do *not* allow extra data on random packets,
and will generally treat that as a fatal protocol error.

>     string    additional text (UTF-8)

That makes more sense (although the request-name is still redundant,
under the assumption that requests are still answered in order).

>   i.e., SSH_MSG_REQUEST_FAILURE2, and deprecate the old

You can't do that, what you can do is add new _request_ messages.

>   to be able to tag requests?

I think the only reasonable thing is to require that responses are
sent in the right order (requests on different channels can be
answered in any order, though).

Summary: I disagree with you're proposed changes, except for adding
some more information to failure messages.

Resonses should be sent in the right where "right order" is defined in
my first paragraph.

It's too late to replace "reply-in-order" with
"add-id-to-all-requests", and I think reply-in-order is adequate.

Regards,
/Niels

---

From: [email-masked] (Niels M�ller)
Date: 08 Aug 2001 14:40:28 +0200

>   that the x11 authentication cookie MUST be hexadecimal

Why? Is that what people are doing (I haven't implemented x11
forwarding yet). It seems very strange to me to use a redundant but
ascii-friendly encoding for things in the binary very eight-bit clean
ssh protocols.

>   We should also explicitly allow binding to port

I agree this is a good idea. Although I think that for backwards
compatibility we should either

 (i) say that the port field is included *only* when binding port 0,
     or
 (ii) use a new request type

/Niels

---

From: "Joseph Galbraith" <[email-masked]>
Date: Wed, 8 Aug 2001 16:56:12 +0100

Yes, I think I've been mostly talked around --
see my email

    "New requests to support binding port 0"

for a new proposal that is completely backwards
compatible -- there is no change in the response
protocols for currently defined requests.

But, it does make it legal for new requests to
define responses that carry additional, request-
specific information.

(And defines a couple of new requests that
use both new response and new failure protocols.)

Thanks for your comments.  Please read the new
proposal and let me know what you think of it.

- Joseph

----- Original Message -----
From: "Niels Möller" <[email-masked]>
To: "Joseph Galbraith" <[email-masked]>
Cc: <[email-masked]>
Sent: Wednesday, August 08, 2001 1:31 PM
Subject: Re: global and channel requests -- more information on failure,
more flexibility on success

---

From: [email-masked] (Niels M�ller)
Date: 08 Aug 2001 18:32:38 +0200

> protocols for currently defined requests.

I was replying to mail in order... Now I have read your more recent
proposals.

* Ordering for channel requests:

    3.4.1 Multiple requests and ordering

       The client is allowed to send further messages without waiting for
       the response to the request.  The recipient must respond to messages
       in the order received so that responses can be matched to requests.

Requests on separate channels should be independent, with no ordering
constraints. Is that obvious, or should the spec say that explicitly?

* The two forms of failure messages:

and

        byte      SSH_MSG_CHANNEL_FAILURE
        uint32    recipient_channel
        uint32    reason
        string    descriptive-text [UTF8]
        string    language
        ... further request-specific data follows

It seems odd to refer to the three optional fields as "request
specific", when they are in fact required to be the same for all
requests. 

These two forms seems a little awkward, but I'm not sure what is the
best way to deal with it. I'm not terribly concerned about backwards
compatibility here, if the new fields are really needed, I'd prefer to
abandon the first shorter form completely. If you need to have an old
version talking to a new server, you can still get them to
interoperate by simply disabling all features that result in a
SSH_MSG_CHANNEL_FAILURE, so I think it may work well to skip the
backwards-compatibility complexity in this case. But perhaps I'm
naive.

The same reasoning applies to SSH_MSG_FAILURE.

* The new tcpip-bind requests:

        byte      SSH_MSG_GLOBAL_REQUEST
        string    "tcpip-bind"
        boolean   want reply
        string    address to bind (e.g. "0.0.0.0")
        uint32    port number to bind

       'Address to bind' and 'port number to bind' specify the IP address
       and port to which the socket to be listened is bound.  The address
       should be "0.0.0.0" if connections are allowed from anywhere.

I'd prefer to change the last sentence to 

       The address should be "" if connections are allowed from
       anywhere. 

That means, listen on all interfaces, be they ipv4 or ipv6. "0.0.0.0"
and "::" can also be used, but they would be needed only in special
circumstances. 

(I'd also like to be allowed to use dns names everywhere in the
protocol, but that's an extension that it's simple to make later.It
might also be nice to have a defined way to say "listen on localhost
only, no matter if ipv4 or ipv6 is used". Perhaps the string
"localhost" could be used for that).

* And finally, I feel a little uneasy about creating new request types
  for all this.

Do we need that much backwards compatibility? As far as I see, the
cases that matters at all from a backwards-compatibility point of view
are (i) failure cases (see above), and (ii) binding port 0, which is
something that no old client should try, and which an old server
should simply refuse.

So do we really need to create new request types?

Best regards,
/Niels

---

From: "Joseph Galbraith" <[email-masked]>
Date: Wed, 8 Aug 2001 22:42:36 +0100

> backwards-compatibility complexity in this case. But perhaps I'm

Actually, old client to new server would be the worst,
because the client sends a whole bunch of requests
(pty, shell, subsystem, agent, etc.) and if any of
them failed, the client would notice too much data
in the response and report a protocol error.

Imagine an SFTP client -- you can't really disable
subsystem requests, which might generate failures.

I'd be willing to rework the wording a little and
see if we can't get the idea expressed a little
less awkwardly.  For example, something along
the lines of "unless otherwise specified, a request
uses the basic version of the response messages.  New
requests SHOULD use the extended version of the failure
message which is defines as follows ... "

Would that make you happier?

>        The address should be "" if connections are allowed from

I like that -- we talked about several possiblities
for this during the working group meeting, but that one wasn't
mentioned -- I like it better then anything that was.

What do other people think about this?

> So do we really need to create new request types?

Well, that was what the consensus at the meeting --
I think just doing something different in the case
of zero came up, and was felt to be a little ugly.

I actually I think the new messages are for the best,
since the old drafts didn't actually disallow binding
to port 0 (even if it wasn't specifically allowed either.)

SecureCRT probably doesn't check to make the port isn't
zero -- and there might be other clients out there that
would allow it to happen if the user requested it.

Also, do old servers actually refuse, or does it succeed --
I'd bet succeed -- but I don't have easy access right now
to test -- but it seems like I tested this once.

- Joseph

---

From: Alok Aggarwal <[email-masked]>
Date: Wed, 8 Aug 2001 14:47:21 -0700 (PDT)

> What do other people think about this?

It seems to solve the problem. Also, the ability to send "localhost" as string
incase the client wants the server to listen on localhost, seems like a good
idea (it makes the draft complete too).

I think it's useful to make this modification in the draft.

-Alok

---

From: [email-masked] (Niels M�ller)
Date: 09 Aug 2001 12:16:20 +0200

> to port 0 (even if it wasn't specifically allowed either.)

A datapoint: lshd checks that the port is larger than 1024. I don't know
what other servers do. The reason lshd does that is that it usually
runs as root at the time it binds the port. 

/Niels

---

From: [email-masked] (Niels M�ller)
Date: 11 Aug 2001 13:04:33 +0200

> in the response and report a protocol error.

This is the most problematic case, I guess. If for instance agent
forwarding is denied, the user would have to use some
--no-agent-forward option. But to be precise exactl which are the
requests that are sent by default and which will reasonably fail? pty
and agent forwarding are in that class (and I think they are used mostly
in interactive mode, not when scripting ssh).

shell and subsystem isn't in that class IMO: The typical use is to
send only one of them, and if it fails, there's not much point going
on anyway. I don't think it is a big problem if the user can sometimes
get a message  "protocol error..." rather than "the request you really
needed to send failed".

> subsystem requests, which might generate failures.

I don't think this case is no real problem. If the client wants to
start sftp, and the server doesn't let it, the client will fail in one
way or the other. It doesn't matter too much in which way.

> For example, something along

The below is your proposal (I hope I found the latest one):

:	 byte      SSH_MSG_CHANNEL_FAILURE
:	 uint32    recipient_channel
:	 ...request specific data
:
:	These messages do not consume window space and can be sent even if
:	no window space is available.
:
:	Unless otherwise specified, a request uses the general form
:	of these messages, with no request specific failure or success
:	data.
:
:	If the recipient doesn't recognize the request, it
:	will send a SSH_MSG_CHANNEL_FAILURE without any
:	request specific data.  This is called the generic
:	form.
:
:	Requests that do send information during failure MUST
:	use the following format:
:
:	 byte      SSH_MSG_CHANNEL_FAILURE
:	 uint32    recipient_channel
:	 uint32    reason
:	 string    descriptive-text [UTF8]
:	 string    language
:	 ... further request-specific data follows
:
:	New requests SHOULD use this extended failure message
:	in order to provide end users and server administrators
:	with information about a failure.

I think I'd prefer something like

	These messages do not consume window space and can be sent even if
	no window space is available.

	For backwards compatibility, a shorter form is sometimes used,

        If a certain request REQUIRES the shorter form is described
        together with that request.

That is mostly a wording change. I'd be happier to say that the
shorter form MAY be used for backwards compatibility, but that the
longer canonical form is always allowed.

[ about the new tcpip forwarding request types ]

> to port 0 (even if it wasn't specifically allowed either.)

It will add a significant amount of complexity to clients to say that
they should first try the new request, then fall back to the old ones
(on the server side, it's easier to support one or both at the same
time). I wouldn't do that in my client; I'd probably just use the good
old tcpip-forwarding request, except when the user wants to bind port
zero, in which case I'd use the new one.

To me, that indicates that the idea of having two parallell request
types with overlapping functionality is bad design. If there are two
ways to do the same thing, it is likely that one of the ways will be
the one used in practice, while the other one must still be there for
conformance. The implementation of the "unusual way" of doing things
will attract bugs, which may even break security. It would be better
to either

  Extend the existing tcpip-forward, saying that binding port 0 is
  allowed, and that it will result in a special success message. This
  is the solution that I would prefer.

  Or invent a new request type for the _sole_ purpose of binding port
  0.

I think both these alternatives are backwards compatible (I don't
think we have any obligation to support existing clients that use
tcpip-forward to bind port 0 and expects any particular behaviour).

I also feel that those changes can be made easily at any time, so I
don't think we need to do anything with the core specs in this regard
except perhaps to point out that they don't define the bahaviour of
tcpip-forward when binding port 0.

> to test -- but it seems like I tested this once.

I don't think any of that is behaviour that any server, client or user
should use or depend on. Do you know of any real world usage?

Regards,
/Niels

---

From: K S Braunsdorf <[email-masked]>
Date: Mon, 13 Aug 2001 09:13:13 -0500

>runs as root at the time it binds the port. 

Well that brings up the issue of privileged ports.  There are really
a few cases the client might ask for:
	"give me any (unprivileged) port"
	"give me an explicit port numbered P"
	"give me a privileged port"

We have 2 of those covered,
	0 -> any unprivileged port
	P -> P

But nothing in the requests I've seen allows "any privileged port",
or am I behind the times?  The obvious (work around) implementation
is to scan all the privileged ports with requests -- really yucky,
and we don't really know the rules for "privileged ports" on a remote
system.

--
ksb

---

From: [email-masked] (Niels M�ller)
Date: 13 Aug 2001 17:29:49 +0200

K S Braunsdorf <[email-masked]> writes:

> or am I behind the times?

Well, such a request could be allowed only if the client session is
authenticated as root (or else, the ports are in effect not privileged
anymore ;-). As it doesn't apply to ordinary user sessions, I don't
think such a feature would be terribly important.

> The obvious (work around) implementation is to scan all the
> privileged ports with requests -- really yucky,

The operation "give me a privileged port" is yucky, even if you could
do it with a single ssh request. The server would have to try binding
ports until it succeeds.

> and we don't really know the rules for "privileged ports" on a remote

I think "privileged ports" is a somewhat broken concept anyway, but it
isn't relative. The whole point of binding an unspecified privileged
port is to be able to convince remote peers that you are indeed
"privileged" in some way. Like with the .rhosts hack. This test is
based on the portnumber only. So the port range is the same on all
hosts, only the meaning of "privileged" varies.

Bottom line: I don't think a request for binding "any privileged port"
is very useful. Do you have any scenario where you'd like to use it?

Best regards,
/Niels