IETF-SSH archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: X forwarding



>>> In more general terms, letting the server do the authentication is
>>> in a way making an (X11) client responsible for X11 server
>>> security, which is not good practice.

>> I don't understand the point here.  I have been unable to come up
>> with a threat model against which having the client provide an
>> authentication method and data blob provides any defense.

> Maybe not a good example, but I think you may failure mode when
> talking to a server that doesn't do any authentication at all [...]

True enough.  I was considering only malicious servers and servers that
cared about the security of the forwarded connection, not servers that,
while not actively compromised, just didn't care.  (I suppose my stance
is that you shouldn't be having your client attempt X forwarding when
connecting to a machine running a server whose X forwarding security
stance you don't know.)

> If the client expects a cookie in the ssh channel, it will reject
> unathorized connections.

This depends on the server doing something with the cookie like putting
it in a .Xauthority file, as opposed to just saving it and bashing it
into the authorization data fields of the X connection-open packet.
But doing that while not taking any other measures to secure the
connection is getting pretty close to the poin twhere I'd call it
actively malicious.

>> I'm implementing X forwarding as a private request which carries
>> only a uint32 cookie and a screen number; when the server wants to
>> forward an X connection, the channel open carries the cookie and the
>> first six bytes of the X protocol stream sent by the client (I could
>> have sent these as the first data on the new connection, but this
>> way seems marginally simpler).
> Please write up a spec for this.

Sure.  See below.

> Including details such as the expectation that the server will ensure
> [...] that only authorized processes can use the X forwarding.  And
> in which way the forwarding is associated to a session (for example,
> if the forwarding is cancelled automatically when the session channel
> is closed).

To request X forwarding, the client sends

     byte      SSH_MSG_CHANNEL_REQUEST
     uint32    recipient channel
     string    "fixed-x11-req%rodents.montreal.qc.ca@localhost"
     boolean   want reply
     uint32    token
     uint32    x11 screen number

The server is, yes, expected to take appropriate steps (some form of
authentication at least as strong as MIT-MAGIC-COOKIE-1) to ensure that
only authorized processes use the connection.

There is no single-connection boolean; that struck me as unnecessary
complexity, and if the client wants those semantics, it can cancel the
forwarding (see below) and reject any extra CHANNEL_OPENs that arrive
because of the race or because the server rejects the cancel.

The token is entirely opaque to the (ssh) server; the only things the
server ever does with it are (a) send it back when an X connection is
opened and (b) compare it when cancelling X forwarding.

Upon getting a forwarded X connetion and its passing whatever security
checks, the server generates

     byte      SSH_MSG_CHANNEL_OPEN
     string    "fixed-x11%rodents.montreal.qc.ca@localhost"
     uint32    sender channel
     uint32    initial window size
     uint32    maximum packet size
     uint32    token from the corresponding CHANNEL_REQUEST
     byte[6]   first six bytes of the client X setup packet (the byte
                order and version numbers)
     string    connection method ("tcp" for TCP, others not yet
                specified - I'm imagining things like "decnet" and
                "local" for DECnet sockets and /tmp/.X11-unix/* - see
                below for more on this).
     connection-method-specific data
     for method "tcp":
         string    originator address (e.g. "192.168.7.38")
         uint32    originator port

The initial client->server setup packet is not carried as channel data;
the first six bytes of it are carried in the open request with the rest
being synthesized locally by the client.  In the Xserver->Xclient
direction, the channel carries pure X data right from the beginning of
the Xserver's response, but in the Xclient->Xserver direction, the
first channel data consists of the client's first request, if any.

In general, I don't like ssh's dependence on something TCP-like in the
protocol (for example, it assumes that the protocol has something like
port numbers that can fit in a uint32, and it thus is not possible to
run ssh, as defined, over DECnet stream sockets).  Since I didn't want
to redesign the whole protocol, I've lived with this in most respects.
But since I'm designing a new request for X, I wanted to fix at least
that much of it, especially since the connection in question is
entirely out of ssh's purview.  (This also addresses the question I saw
in the archives about "what originator info do I use for an AF_LOCAL X
connection?").

I have not actually implemented cancelling X forwarding.  Here's a
first stab at it:

     byte      SSH_MSG_CHANNEL_REQUEST
     uint32    recipient channel
     string    "cancel-x11-req%rodents.montreal.qc.ca@localhost"
     boolean   want reply
     uint32    token
     uint32    x11 screen number

This cancels all previous X forwardings for that channel, token, and
screen number.  I see no need for a way to wildcard any of these; if
others disagree, two additional bits (to indicate wildcarding of the
token or screen number) could be added, either as two booleans or as a
uint32 flags bitmask....

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse%rodents.montreal.qc.ca@localhost
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B



Home | Main Index | Thread Index | Old Index