Subject: New requests to support binding port 0

From: "Joseph Galbraith" <[email-masked]>
Date: Tue, 7 Aug 2001 13:21:53 +0100

As promised during the meeting, here are the changes
required to support binding to port 0.

There are two sets of changes -- the first changes global
requests in a fully backward compatible manner to make the
second set of changes legal.

The second set of changes define two new requests,
"tcpip-bind" and "tcpip-unbind" which replace the
existing "tcpip-forward" and "cancel-tcpip-forward"
requests.

The "tcpip-forward" and "cancel-tcpip-forward" requests
are still defined, but are deprecated.

I also clarified multiple requests and ordering.

Please let me know if this is satisfactory, or if
people what changes, or if I totally screwed up what
I agreed to do :-)

Joseph Galbraith
[email-masked]

-------------------------------------------------------

For section 2 of the connection draft:

    2. Global Requests

       There are several kinds of requests that affect the state
       of the remote end "globally", independent of any channels.
       An example is a request to start TCP/IP forwarding for a
       specific port.  All such requests use the following format.

        byte      SSH_MSG_GLOBAL_REQUEST
        string    request name (restricted to US-ASCII)
        boolean   want reply
        ... request-specific data follows

       The recipient will respond to this message with
       SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, or some
       request-specific continuation messages if `want reply'
       is TRUE.

        byte      SSH_MSG_REQUEST_SUCCESS
        ... request-specific data follows

       Unless otherwise specified, a request sends no additional
       data with it's success message.

       If the recipient does not recognize, it simply responds
       with SSH_MSG_REQUEST_FAILURE.

        byte      SSH_MSG_REQUEST_FAILURE

       If the recipient recognizes the request, but can not
       complete the request because of local policy or because
       an error occurs processing the request, it responds with:

        byte      SSH_MSG_REQUEST_FAILURE
        ... request-specific data follows

       Unless otherwise specified, a request sends no additional
       data with it's failure message.  In this case, it is not
       possible to distinguish between the unrecognized request
       case and the failed request case.

       Requests that do send information during failure MUST
       use the following format:

        byte      SSH_MSG_REQUEST_FAILURE
        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.

    2.1 Multiple requests and ordering

       Multiple requests may be sent without waiting
       for replies.  The receiver must complete requests
       in the order which they are received so that
       responses can be matched with requests.

    2.2 Compatibility with existing implementations

       Since all previously defined requests are defined as
       having no request-specific data for either success or
       failure messages, existing implementations can send
       these previously define requests without fear of receiving
       an extended failure or success message in response.

       New implementations might send a new request to an old
       implementation.  In this case, the old implementation
       will not recognize the request, and will respond with
       the "unrecognized" form of the SSH_MSG_REQUEST_FAILURE
       message -- the only form of failure message previously
       defined.

------ New text for Section 5.1:

    5.1 Requesting Port Forwarding

       A party need not explicitly request forwardings from its own end
       to the other direction.  However, if it wishes that connections to
       a port on the other side be forwarded to the local side, it must
       explicitly request that the port be bound on the remote side.

        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.
       (Note that the client can still filter connections based on
       information passed in the open request.)  The port should be 0
       to bind to any available port.

       Implementations should only allow forwarding privileged ports if
       the user has been authenticated as a privileged user.

       Client implementations SHOULD reject these messages; they are
       normally only sent by the client.

       The server responds with either

        byte    SSH_MSG_REQUEST_SUCCESS
        uint32  port that was bound

       or

        byte    SSH_MSG_REQUEST_FAILURE
        uint32  reason
        string  descriptive-text [UTF8]
        string  language

       where reason is one of the reason codes defined
       below.

       A port forwarding can be cancelled with the following message.
       Note that channel open requests may be received until a reply to
       this message is received.

        byte      SSH_MSG_GLOBAL_REQUEST
        string    "tcpip-unbind"
        boolean   want reply
        string    address_to_bind (e.g. "127.0.0.1")
        uint32    port number to bind

       Client implementations SHOULD reject these messages; they are
       normally only sent by the client.

       The port number may not be 0.

       The server responds with either

        byte    SSH_MSG_REQUEST_SUCCESS

       or

        byte    SSH_MSG_REQUEST_FAILURE
        uint32  reason
        string  descriptive-text [UTF8]
        string  language

       Reason codes are one of the following:
    
        SSH_BIND_GENERAL_FAILURE                0
        SSH_BIND_ADMINISTRATIVELY_PROHIBITED    1
        SSH_BIND_PORT_IN_USE                    2
        SSH_BIND_INVALID_ADDRESS                3
        SSH_BIND_INVALID_PORT                   4
        SSH_BIND_PORT_NOT_BOUND                 5

    5.1.1 Compatibility with previous Port Forwarding requests

       Previously, these requests were "tcpip-forward" and
       "cancel-tcpip-forward"  These requests are still supported,
       but implementations SHOULD move away from using them.

       The requests are identical to the "tcpip-bind" and
       "tcpip-unbind" requests, except that the generic
       success and failure messages are sent (with no request
       specific data attached.)

       Because it is not possible to get information about
       what port was bound, it is also prohibited to bind
       to port 0 when using a "tcpip-forward" request.

       "tcpip-forward" and "cancel-tcpip-forward" should be
       considered deprecated.

       If a new client sends a "tcpip-bind" request
       to an old server, it will receive the "unrecognized-
       request" form of the failure message.  In this case, binding
       to port 0 is not possible, but all other requests can still
       be made by falling back into a "compatibility mode" and
       issuing "tcpip-forward" requests instead.