From ylo@ssh.fi Thu Mar 27 20:05:27 1997
Received: from muuri.ssh.fi (ssh.fi [194.100.44.97]) by lox.sandelman.ottawa.on.ca (8.7.5/8.7.3) with ESMTP id UAA07721 for <mcr@sandelman.ottawa.on.ca>; Thu, 27 Mar 1997 20:04:55 -0500 (EST)
Received: from pilari.ssh.fi (pilari.ssh.fi [192.168.2.1])
	by muuri.ssh.fi (8.8.5/8.8.5/EPIPE-1.10) with ESMTP id DAA10341;
	Fri, 28 Mar 1997 03:19:19 +0200 (EET)
Received: (from ylo@localhost)
	by pilari.ssh.fi (8.8.5/8.8.5/1.9) id DAA26506;
	Fri, 28 Mar 1997 03:19:19 +0200 (EET)
Date: Fri, 28 Mar 1997 03:19:19 +0200 (EET)
Message-Id: <199703280119.DAA26506@pilari.ssh.fi>
From: Tatu Ylonen <ylo@ssh.fi>
To: Michael Richardson <mcr@sandelman.ottawa.on.ca>
Cc: ietf-ssh@clinet.fi, ylo@ssh.fi
Subject: Re: draft-ietf-secsh-userauth-00.txt (fwd) 
In-Reply-To: <199703271333.IAA04306@amaterasu.sandelman.ottawa.on.ca>
References: <199703270812.KAA19048@pilari.ssh.fi>
	<199703271333.IAA04306@amaterasu.sandelman.ottawa.on.ca>
Organization: SSH Communications Security, Finland

>   I do not see how the client can ever know that it needs to do
> multiple authentications. The server is purposely vague about what
> kind of authentication is requires, and in the case of multiple
> authentication is vague about when the client has satisfied it.

Every time an authentication request fails (or succeeds but more
authentications are required), the server responds with
a SSH_MSG_USERAUTH_FAILURE message that contains a list of
authentication methods that could usefully continue the dialog.
The list changes as some authentications are accepted.

Suppose, for example, that the server's policy says:
  - from within foo.org, accept password, hostbased, one-time
    password, and publickey authentication
  - from anywhere else, require hostbased authentication PLUS one-time
    password

The client would typically first send a "none" authentication request.
The server responds with the list of methods that can reasonably
continue: "password,hostbased,publickey,skey,opie" if from inside
foo.org (maybe not all of these for every user), and
"hostbased,skey,opie" if outside.  Suppose the client is outside, and
it now sends a correct hostbased request.  The server responds with
SSH_MSG_USERAUTH_FAILURE, but this time lists only "skey,opie".  If
the client now sends a successful "skey" authentication, the server
responds with SSH_MSG_USERAUTH_SUCCESS.

Note that it would have been equally legal for the server to first
list only "hostbased" when coming from outside the organization, and
then change the list to "skey,opie" when hostbased authentication has
been successfully performed.

I've already clarified some of the wording in the draft regarding
authentication being client-driven.  It is really server-driven, with
some flexibility allowed for the client (the client chooses from the
methods offered by the server).

>   I realize that there are many that prefer that the server not give
> away its security policy. I know we had this debate before.

In the current design, the server reveals which methods it is willing
to accept.  This may depend on where the user is logging in from, and
may depend on the user.  Other details of the policy are only revealed
after the client has successfully performed some authentication.

>   I would like to see text that explains how a multiple levels of
> authentication could be performed, preferably where the proxy server
> connected the client to a final destination after the initial
> authentication. (This would happen with the proxy server creating a
> new transport layer to the new server) 

I assume you mean like a firewall proxy, and the user first
authenticates to the firewall and only then gets connected to the real
host where he needs to autenticate again?

This has currently not been thought of.  I welcome any suggestions on
how this should work.  Issues to consider include:
  - how does the client know whether it can know the proxy server (the
    man in the middle)?
  - how does the server know that it can trust the proxy server (the
    man in the middle)?
  - how to tell the real server who the real client is?

One part of the solution could be to create a certificate that
authorizes the proxy to act on behalf of each side.  Another part
could be a proxy authentication message that tells the server that it
should use another session id and host name as the basis for
authentication than that supplied by the transport layer.

This could work as follows:

1. The client connects the target host, but the firewall redirects the
connection to the proxy (or should there be a mechanism to have it
connect the proxy directly?).  The proxy sends its own host key,
together with a trusted certificate saying that it is an authorized
representative of the target host.

2. The client then authenticates itself to the proxy, using any
authentication methods the proxy asks for.  The dialog is as described
in the userauth draft.

3. When the proxy is satisfied that the connection is legal (it would
normally send SSH_MSG_USERAUTH_SUCCESS), it suppresses the success
message, connects the real target host, and establishes a transport
layer connection.

4. It sends the real target a "proxied-connection" authentication
message that looks like the following:
     vlint32   SSH_MSG_USERAUTH_REQUEST
     string    user
     string    service
     string    "proxied-connection"
     string    proxy_host_key_algorithm
     string    proxy_public_host_key  (may include certificates)
     string    real client host IP address (e.g. "128.34.129.121")
     string    real client port
     string    real client session id
     string    signature of other data by proxy host key

5. The real server verifies that the proxy host key is trusted and the
signature is valid.  It then stores the real client host, port, and
session id for use in further authentication, and uses these to decide
the policy (which might also be affected by the fact that it is coming
through a proxy).  The server then performs authentication operations
similar to "none" authentication, and responds with
SSH_MSG_USERAUTH_FAILURE listing the authentication methods it still
wants (or might respond with SSH_MSG_USERAUTH_SUCCESS if it is willing
to trust the proxy's judgement).

As far as I can see, this would allow a firewall proxy to decrypt and
re-encrypt any sessions if properly authorized by the communicating
parties (or someone they trust).

This does not completely solve the problem for the case that the
client needs to directly connect to the proxy (is that case
relevant?).  For that to work, we need to pass the name of the real
target host somewhere, either on the transport layer or on the user
authentication layer.  One possibility would be to have a new
fake authentication mehthod "connect-to-real-host" that could look
like the following:
      vlint32   SSH_MSG_USERAUTH_REQUEST
      string	user
      string	service
      string    "connect-to-real-host"
      string	real-target-host-name
The proxy could request this authentication method either in the
beginning of the authentication or at the end of the authentication.
I don't think this is very elegant though.

>   An example is necessary here. I see contradictory text between the
> last paragraph of 2.6.1 and section 3: "any SSH_MSG_USERAUTH_REQUEST
> messages after sending this message will be silently ignored"
>   How can the client know that the initial partial authentication be
> successful except by receipt of a USERAUTH_SUCCESS?
>   Also, how does the client know which method succeeded? 

The client is allowed to send many authentication requests without
waiting for response.  In practise, it could send any such requests
immediately that are quick to process and do not require any user
interaction.  For example, it could send all "none", "publickeytest",
"hostbased", or "kerberos" requests right away, and only then proceed
with more interactive authentications guided by the server.

The server will respond with SSH_MSG_USERAUTH_FAILURE to every request
in sequence, until it responds with SSH_MSG_USERAUTH_SUCCESS, after
which all SSH_MSG_USERAUTH_REQUEST packets are ignored.

This basically just speeds up login on long-distance connections.

>   Further, I'm concerned about the text being silent about not sending
> password logins when the server host key is new, or has changed. 

What to do when the host key is unknown is a very tricky issue in
general.  In such a situation, the connection is fundamentally
insecure.  In future, the problem will be solved by a key
infrastructure, but for now it is practical in many situations to
trust the supplied host key if no other key is avaiable (it is an
insecure against active attacs vs. no connection at all choice, and
usually slightly insecure is better than no communication at all).

In my opinion this is beyond the scope of the protocol, and is more a
policy and implementation issue.  What do others think?

    Tatu


