Subject: Publickey subsystem draft posted

From: "Brent McClure" <[email-masked]>
Date: Tue, 8 Jul 2003 14:16:32 -0600

We've refreshed the individual draft of the "Secure Shell Public-Key Subsystem". 
The new draft is available here:

  http://www.ietf.org/internet-drafts/draft-galb-secsh-publickey-subsystem-01.txt

The public-key subsystem is a mechanism that allows authenticated clients
to upload/manage their public keys through an implementation-independent
interface.

In the past, we've felt that there has been some interest in pursuing
this draft as a working group document.

I'd be happy to hear whatever feedback you have on what steps might help 
move the document in that direction.

thanks,
Brent McClure
[email-masked]

---

From: Bill Sommerfeld <[email-masked]>
Date: Wed, 16 Jul 2003 04:45:54 -0400

> move the document in that direction.

I'd like to hear feedback from the rest of the WG as to whether this
is of interest as a WG item.  [I haven't heard a whole lot one way or
the other on this and while it appears to be in scope for the WG, I'd
like to see some actual enthusiasm for it as well..]

					- Bill

---

From: Simon Tatham <[email-masked]>
Date: Wed, 16 Jul 2003 09:51:22 +0100

Bill Sommerfeld  <[email-masked]> wrote:
> is of interest as a WG item.

I quite like the idea in principle; I get a fair amount of mail from
people who can't figure out how to set up public-key authentication,
and I can't imagine that the variety of implementations all doing it
in different ways can possibly be helping that. A standard protocol
for setting up the server would mean users wouldn't need to bounce
back and forth between the client and server documentation, but
could simply follow one set of instructions.

I haven't looked at the details yet, though.

Cheers,
Simon
-- 
Simon Tatham         "A defensive weapon is one with my finger on the
<[email-masked]>    trigger. An offensive weapon is one with yours."

---

From: Darren J Moffat <[email-masked]>
Date: Wed, 16 Jul 2003 12:21:56 -0700 (PDT)

> like to see some actual enthusiasm for it as well..]

I support the concept and I believe that it is appropriate work for this WG.

I'll need to spend some time reading the draft again to see if I support this
actual proposal or not.

-- 
Darren J Moffat

---

From: Darren J Moffat <[email-masked]>
Date: Wed, 16 Jul 2003 12:40:27 -0700 (PDT)

In the introduction you say:

   This protocol requires that the user be able to authenticate in some
   fashion before it can be used. If password authentication is used,
   servers SHOULD provide a configuration option to disable the use of
   password authentication after the first public key is added.

While I support the intent of this the functionality seems like it would
actually be more appropriate for one of the core drafts rather than this one.

  3.2 Adding a public key

   If the client wishes to add a public key, the client sends:

   	string    "add"
   	string    comment
   	string    public-key algorithm name
   	string    public-key blob

   The server MUST attempt to store the public key for the user in the
   appropriate location so the public key can be used for subsequent
   public-key authentications.

   The comment field contains user-specified text about the public key
   and MAY be empty.

I'd like to see text added to say that the server is not supposed to
interpret the comment in any way and is NOT required to preserve it for
subsequent return in a list command.

 3.4 Listing public keys

   If the client wishes to list the known public keys, the client sends:

   	string    "list"

   The server will respond with zero or more of the following responses:

   	string    "publickey"
   	string    comment
   	string    public-key algorithm name
   	string    public-key blob

   The comment field contains user-specified text about the public key
   and MAY be empty.

   Following the last "publickey" response, a status packet MUST be
   sent.

   An implementation MAY choose not to support this request.

How long is the client supposed to wait for the server to send the
status packet to say it is done ?

I would have expected the server to send a packed more like this:

	string "publickey-list"
	uint32 number of following public keys
	string comment
	string public-key algorithm name
	string public-key blob
	.... and so on upto uint32 number of keys

OR something like

	string "publickey-list"
	uint32 number of following public keys

	then send the publickeys in the packet format you defined in 3.4

Telling the client how many keys are comming would probably be helpful
for implementers building a UI to display this info.

--
Darren J Moffat

---

From: "Brent McClure" <[email-masked]>
Date: Mon, 21 Jul 2003 17:23:56 -0600

Darren, Sorry for the delay responding to your comments.

> actually be more appropriate for one of the core drafts rather than this one.

It seems to me that the core drafts are pretty well closed up at this point.
I'm not sure yet if I understand completely why some language like this
would be inappropriate in this document. I'd be happy to see it changed
to "MAY provide a configuration option...". I could also see rephrasing it
to not specifically mention password authentication. Otherwise this 
seems pretty innocuous.

> subsequent return in a list command.

Sounds good. But, I do think it would be nice to have a statement that indicates 
that returning the comment in a list would be helpful to users trying to
distinguish keys from each other in a listing (other than by looking at fingerprints).

> status packet to say it is done ?

On one hand I'd say that how long a client decides to wait could
be implementation dependent. I suppose some implementations might
simply hang until the status packet comes through assuming that 
a user would cancel or interrupt the whole thing...

I see your point though. I believe one of the reasons we chose to 
have a bunch of 'list' responses followed by a 'status' response
was that we found it easy to parse.

> for implementers building a UI to display this info.

--Brent

---

From: Bill Sommerfeld <[email-masked]>
Date: Tue, 22 Jul 2003 09:17:33 -0400

> to not specifically mention password authentication. Otherwise this 

there is no strong requirement that the document boundaries exactly
match the implementation boundaries.  as a quality of implementation
issue it seems like the "disable password once a public key is
registered" should be enforced on a user-by-user basis (some users may
haev a need to be able use passwords even when a public key is
present) which suggests to me that the feature description touches
both parts and could end up in either place...

> Sounds good. But, I do think it would be nice to have a statement
> that indicates that returning the comment in a list would be helpful
> to users trying to distinguish keys from each other in a listing
> (other than by looking at fingerprints).

[wg chair hat off..]

For what it's worth, the management UI guy who sits next to me really
seems to like this sort of thing and i'm inclined to take his word for
it.  However, as long-lived user-visible text, you've just invoked the
full complexity of I18N:

    All user-visible text fields must be internationalizable
    See RFC 2277. For most cases, this means UTF-8.
    If text fields are included in some calculation, like matching,
    sorting etc, it must be described in detail how those operations are
    applied to the Unicode/ISO 10646 character set. see "stringprep" for
    more information on the recommended way of handling comparisons.

I think the case we want to worry about is -- what happens when you
get a client from mars which registers a key with a comment in
martian, then a client from venus connects to the same account and
registers a comment in venusian.. you need to tag each comment with an
appropriate language:

quoting from 2277:

   Protocols that transfer text MUST provide for carrying information
   about the language of that text.

   Protocols SHOULD also provide for carrying information about the
   language of names, where appropriate.

   Note that this does NOT mean that such information must always be
   present; the requirement is that if the sender of information
   wishes to send information about the language of a text, the protocol
   provides a well-defined way to carry this information.

					- Bill

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 22 Jul 2003 07:02:35 -0700

> was that we found it easy to parse.

If you want to keep to one packet per-listed key then you could add a
bit to the packet to indicate whether more are coming or not...

Cheers,

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 22 Jul 2003 07:13:31 -0700

I think this subsystem should model some of the pubkey restrictions
implemented by OpenSSH and others.  E.g., "this key can use the sftp
subsystem but cannot forward any ports."

Some such restrictions may be platform specific and therefore do not
belong in your I-D.  But certainly some are generic.

Cheers,

Nico
--

---

From: Simon Tatham <[email-masked]>
Date: Tue, 22 Jul 2003 15:58:14 +0100

> The new draft is available here:
[...]

OK, here are some comments. I'm in favour of a protocol of this type
existing, but I think this draft is going to need some work before
it's useful.

 - You don't mention any kind of packet structure within the
   subsystem channel, like SFTP has. Is this deliberate? It looks at
   the moment as if the individual components of any given request
   (e.g. string "add", string comment, string algorithm, string
   pubkey blob) are sent straight to the subsystem without any
   overall length field.

   If that's correct and not simply a documentation error, it
   _completely_ destroys extensibility: if a subsystem receives any
   request with a name it doesn't recognise, then it cannot know how
   much of the following data belongs to that request, so after
   returning REQUEST_NOT_SUPPORTED it _can't_ resume parsing at the
   next request boundary. Without this basic extensibility property,
   what was the point of having request types described in an
   extensible string namespace at all?

 - Speaking of extensibility, I strongly support Nicolas Williams's
   comment that there already exist SSH server implementations
   supporting a greater range of public key options and restrictions
   than your draft specifies. Surely at the very least there ought
   to be some sort of extension mechanism within the "add" request
   type?

 - The "command" request is seriously under-specified. It does not
   mention whether the key in question is expected to have been
   added using "add" previously, or is added by the "command"
   request itself.

    * If the former, this is a security hazard if naively
      implemented: the _only_ way to set up a restricted key is by
      issuing "add" and then "command", but between those two
      requests, there is a window of opportunity in which someone
      possessing the private key can gain unrestricted access to the
      target account. Since restricted keys are typically keys you
      don't fully trust not to fall into enemy hands, there should
      never be such a window of opportunity. Therefore, an
      implementation MUST delay actually making the changes until
      the subsystem channel is closed or a subsequent
      synchronisation message is sent; this should be clearly
      specified.

    * If the latter, this would make far more sense to me, except
      that the comment field present in the "add" request is missing
      in the "command" request.

   Since I've already proposed an extensibility field in the "add"
   request, I'm tempted to suggest that "command" is a complete
   misfeature and ought to be implemented in terms of that instead.

Cheers,
Simon
-- 
Simon Tatham         These are my opinions. There are many
<[email-masked]>   like them but these ones are mine.

---

From: Joseph Galbraith <[email-masked]>
Date: Tue, 22 Jul 2003 12:16:37 -0600

>    extensible string namespace at all?

It is a documentation error-- thank heavens.

The generalized message format is:

UINT32 length
string type
... request specific data follows

Sections 2.2 and 2.3 should be updated to reflect this.

>    to be some sort of extension mechanism within the "add" request

Yes, this makes sense.  The "command" option was supposed to deal
with the various restrictions supported by openssh and other 
implementations, but...

   a. Since we don't support it, we were kind of shooting in the
      dark as to what people needed, and clearly, we undershot.
   b. As you point out below, it needs to be integrated with the
      add command to prevent 'vulnerability windows'

>    misfeature and ought to be implemented in terms of that instead.

What if the "add" command where changed as follows?

	string "add"
	string public-key algorithm
	string public-key blob
	uint32 attribute-count
		string attrib-name
		string attrib-value
		bool   mandatory
	repeated attribute-count times

   attrib-names without a '@' are reserved to the IETF.  Extensions
   MAY be used by composing the '@' with a DNS name, for example,
   [email-masked]'

   If the server does not implement a mandatory attribute, it MUST fail
   the add.  For the purposes of a mandatory attribute, storage of the
   attribute is not sufficient, but requires that the server understand
   and implement the intent of the attribute.

   The following attributes are defined by this draft.

   "comment"
	The comment field contains user-specified text
	about the public key.  The server SHOULD make every
	effort to preserve this value and return it with the
	key during a list operation.

	The comment field is useful so the user can identify the
	key without resorting to comparing it's fingerprint.

   "command"
	Command bypasses the session channel "exec" and "shell"
         requests by always execution the specified command.

	This attribute SHOULD be mandatory.

   "restrict"
	The value of this attribute contains server functions that
	may not be preformed when this key is used.  It is a comma
	seperated list.  Elements containing an '@' are reserved for
	implementation / site specific extension; all other elements
	are reserved for use by the IETF.

	Currently defined restrictions are:

		"x11"
		"shell"
		"exec"
		"port-forward"
		"reverse-forward"

	This attribute SHOULD be mandatory.

   For example, we might have:

   "add"
   "ssh-rsa"
   public-key-blob
   4
   "comment"
   "2048 bit RSA key for my daughter"
   "[email-masked]"
   <special data, could be binary>
   "restrict"
   "port-forward,reverse-forward,x11,exec"
   "command"
   "daughter-shell"

The 'list' command would need to be updated to have
a similar extension format.

What do you think?  What other extensions should we
define here?  What other types ofrestrictions should
be defined?

- Joseph

---

From: Simon Tatham <[email-masked]>
Date: Tue, 22 Jul 2003 21:21:10 +0100

> ... request specific data follows

Does the length include the 4 bytes of the length field itself? (I
don't care, but don't forget to state it either way :-)

> What if the "add" command were changed as follows?
> 
> 	string "add"

Works for me. If anyone needs an attrib-value which is more complex
than a simple string, there's nothing to stop them treating the
string as a blob, and formatting the data inside the blob using
another layer of SSH data types, or indeed any other format they
feel like.

Is it worth defining what should happen if a user attempts to add a
key which is already present, but with different attributes? Should
the add operation fail, or succeed and alter the key setup?

>    and implement the intent of the attribute.

I particularly like that. It reminds me of the bits in PNG that
define what an editing program should do to chunk types it doesn't
recognise. Simple and effective.

> 	key without resorting to comparing it's fingerprint.

(As a vague aside: has anyone done a detailed study of what attacks
might be possible by people - malicious clients, servers, agents,
people, software, sysadmins or anyone else - substituting the
comment for one valid key on another? PuTTY's custom-designed SSH2
key format contains a passphrase-keyed MAC designed to make the
comment field tamper-evident, largely because I couldn't work out
whether there was a possibility of an attack or not, and could see
no reason not to be ultra-cautious. Anyone else had any thoughts on
the subject?)

[...]
> 	Currently defined restrictions are:

What about "subsystem"? Is that worth putting in as a separate one?
Or even "subsystem:foo", for any value of foo?

Actually, the latter might get messy, since subsystem names are
permitted to contain commas by my understanding. And in practice,
anyone restricting a key would be more likely to want to forbid _all
but_ specific subsystems rather than restricting particular ones.

Cheers,
Simon
-- 
Simon Tatham         "infinite loop _see_ loop, infinite"
<[email-masked]>     - Index, Borland Pascal Language Guide

---

From: Joseph Galbraith <[email-masked]>
Date: Tue, 22 Jul 2003 15:03:22 -0600

> don't care, but don't forget to state it either way :-)

I believe it is like both Sftp and the SSH Transport layer;
the length is not included.

> the add operation fail, or succeed and alter the key setup?

Hmmm-- since we don't have a modify, maybe we should
change add as follows:
	...
	string public-key-blob
	bool overwrite
	...

with wording like:

    Clients SHOULD send the add request the first time
    with overwrite false, and then, if the key turns out
    to be already present, give the user the option of
    overwriting the key.

We would also need to add a KEY_ALREADY_PRESENT status
message.

> but_ specific subsystems rather than restricting particular ones.

How about this:
		"subsystem"

And an additional attribute:

	"subsystem"

	The value is a subsystem that will be run when the key is
	used.  Any attempt to access an different subsystem MUST
	fail.  Any attempt to access other features is governed
	by the "restrict" attribute.

Are there restrictions that can be expressed for
openssh keys or ssh.com keys that can't be expressed
in what is proposed?

Joseph

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 22 Jul 2003 14:37:00 -0700

> 	key without resorting to comparing it's fingerprint.

See Bill Sommerfeld's comment about I18N.  You ought to associate a
language tag with the comment.

> 	This attribute SHOULD be mandatory.

This attibute's values are generally going to be platform-specific.
There's no avoiding that, but it might be a good idea to have a way for
clients to find out about the server's platform and/or validate the
command.

> 	are reserved for use by the IETF.

I think of "command" as a restriction, and all of these should be
treated the same way, perhaps with each having it's own attribute name.

> 	This attribute SHOULD be mandatory.

Don't forget about subsystems.  And no, I don't think the "command"
restriction should be conflated with subsystem restrictions.

For the port forwarding restrictions there should probably be a list of
host:port restrictions associated.

There should probably be a list of host:ports which are allowed to use
this key to authenticate.

> a similar extension format.

Yes.

> define here?  What other types ofrestrictions should

See above.

Cheers,

Nico
--

---

From: Darren J Moffat <[email-masked]>
Date: Wed, 23 Jul 2003 12:03:19 -0700 (PDT)

> We would also need to add a KEY_ALREADY_PRESENT status

Which needs to have the possibility of permission denied, so that an
admin can setup a set of restrictions on a key that the user can't
later override by using the public key subsystem to modify the attributes
of an already existing key.

-- 
Darren J Moffat

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 23 Jul 2003 15:25:52 -0700

> of an already existing key.

Also, the restrictions actually stored need not match the restrictions
listed in the add request.  This could allow sysadmins to force
restriction templates.

Nico
--

---

From: Bill Sommerfeld <[email-masked]>
Date: Wed, 23 Jul 2003 18:35:06 -0400

> listed in the add request.  This could allow sysadmins to force

[wg chair hat off]

I'd hope that the set of restrictions stored would be spec'ed to be a
superset of the restrictions requested.  

looking at it another way, the set of things permitted to be done with
a key would be a subset of the things that the add request requested
to be permitted...

						- Bill

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 23 Jul 2003 15:33:00 -0700

Yes.

Nico
--

---

From: "Jon Bright" <[email-masked]>
Date: Thu, 24 Jul 2003 00:54:16 +0200 (CEST)

> listed in the add request.  This could allow sysadmins to force

This sounds like a good plan.  From a GUI perspective, though, it'd be
nice to have a facility to additionally have operations to:

a) List restrictions the sever supports.
b) Discover which of those restrictions will be compulsorily applied.

The first enables presenting a list of checkboxes to the user (with, for
those restrictions the client know
 of, human-friendly text).  The second allows certain of those checkboxes
to be compulsorily checked, thereby (hopefully) avoiding user confusion
about the restrictions applied to the key.

-- 
Jon Bright
Lead Programmer, Silicon Circus Ltd.
http://www.siliconcircus.com

---

From: Jon Bright <[email-masked]>
Date: Thu, 24 Jul 2003 15:42:12 +0200

Hi,

>   http://www.ietf.org/internet-drafts/draft-galb-secsh-publickey-subsystem-01.txt

Following the various comments from the WG, I have the following 
suggested text for the changes discussed.  A lot of this is taken 
directly from things people posted to the mailing list.  I think I 
caught all the suggested changes.  Any errors are my fault.  My comments 
on the change appear above each patch hunk (I realise you're probably 
not going to be able to apply the patch, since the text output is not 
the source format, but this seemed the easiest way of presenting it all).

"will" doesn't seem especially RFCish...

@@ -207,7 +207,7 @@
     Client implementations SHOULD reject this request; it is normally
     only sent by the client.

-   If want reply is TRUE, the server will respond with
+   If want reply is TRUE, the server MUST respond with
     SSH_MSG_CHANNEL_SUCCESS if the public-key subsystem was successfully
     started or SSH_MSG_CHANNEL_FAILURE if the server failed to start or
     does not support the public-key subsystem.

As Joseph mentioned, length was omitted in the previous version. 
Additionally, clarify what the length specifies.

@@ -228,23 +228,25 @@

  2.2 Requests

-   All public-key subsystem requests are sent request in the following
-   form:
+   All public-key subsystem requests are sent in the following form:

+   	uint32    length
     	string    request-name

-   The client MUST receive acknowledgement of each request prior to
-   sending a new request.
+   The length field describes the length of the request-name field and
+   the request-specific data, but not of the length field itself.  The
+   client MUST receive a response to each request prior to sending a
+   new request.

-   All requests described in Section 3 are a description of the 'data'
-   portion of the packet.
+   All requests described in Section 3 are a description of the
+   'request-name' and 'data' portions of the packet.

  2.3 Responses

-   All public-key subsystem requests are sent request in the following
-   form:
+   All public-key subsystem responses are sent in the following form:

+   	uint32    length
     	string    response-name
     	... response specific data follows

All the other drafts define a prefix of the form SSH_<something_ before 
their defines.  This seems like a sane practice.

@@ -268,12 +270,13 @@
     The status code gives the status in a more machine-readable format
     (suitable for localization), and can have the following values:

-   	SUCCESS                      0
-   	ACCESS_DENIED                1
-   	STORAGE_EXCEEDED             2
-   	REQUEST_NOT_SUPPORTED        3
-   	KEY_NOT_FOUND                4
-   	KEY_NOT_SUPPORTED            5
+   	SSH_PUBLICKEY_SUCCESS                      0
+   	SSH_PUBLICKEY_ACCESS_DENIED                1
+   	SSH_PUBLICKEY_STORAGE_EXCEEDED             2
+   	SSH_PUBLICKEY_REQUEST_NOT_SUPPORTED        3
+   	SSH_PUBLICKEY_KEY_NOT_FOUND                4
+   	SSH_PUBLICKEY_KEY_NOT_SUPPORTED            5
+       SSH_PUBLICKEY_KEY_ALREADY_PRESENT          6

@@ -282,7 +285,7 @@
  Internet-Draft     Secure Shell Public-Key Subsystem           June 2003

-   	GENERAL_FAILURE              6
+   	SSH_PUBLICKEY_GENERAL_FAILURE              7

Not sure if this is a useful clarification, but it seemed so.

@@ -355,7 +358,7 @@

     Both sides send the highest version that they implement. The lower of
     the version numbers is the version of the protocol to use.  If either
-   side can't support the lower version, it should close the subsystem.
+   side can't support the lower version, it should close the subsystem
+   and notify the other side by sending an SSH_MSG_CHANNEL_CLOSE message.

     Both sides MUST wait to receive this version before continuing.

The big change.  This is mostly Joseph's suggested text.  I added 
"agent", "env" and "subsystem" to the restrictions and moved 
"port-forward" and "reverse-forward" to be attributes, to allow for 
specification of allowed-host lists.  Additionally integrated Nicolas' 
suggestion regarding mandatory restrictions.  Finally, added overwrite, 
with behaviour as discussed.

@@ -364,16 +368,124 @@

     	string    "add"
-   	string    comment
     	string    public-key algorithm name
     	string    public-key blob
+       boolean   overwrite
+   	uint32    attribute-count
+		string attrib-name
+		string attrib-value
+		bool   mandatory
+	repeated attribute-count times

     The server MUST attempt to store the public key for the user in the
     appropriate location so the public key can be used for subsequent
-   public-key authentications.
+   public-key authentications.  If the overwrite field is false and the
+   specified key already exists, the server MUST return
+   SSH_PUBLICKEY_KEY_ALREADY_PRESENT.  If the server returns this, the
+   client SHOULD provide an option to the user to overwrite the key.
+   If the overwrite field is true and the specified key already exists
+   but cannot be overwritten, the server MUST return
+   SSH_PUBLICKEY_ACCESS_DENIED.
+
+   Attribute names are defined following the same scheme laid out for
+   algorithm names in [SSH-ARCH] (section 5).  If the server does not
+   implement a mandatory attribute, it MUST fail the add.  For the
+   purposes of a mandatory attribute, storage of the attribute is not
+   sufficient, but requires that the server understand and implement
+   the intent of the attribute.
+
+   The following attributes are currently defined:
+
+   "comment"
+       The comment field contains user-specified text about the
+       public key.  The server SHOULD make every effort to preserve
+       this value and return it with the key during a list operation.
+       The server MUST NOT attempt to interpret or act upon the content
+       of the comment field in any way.
+
+       The comment field is useful so the user can identify the key
+       without resorting to comparing its fingerprint.
+
+       This attribute SHOULD NOT be mandatory.
+
+   "comment-language"
+       If this attribute is specified, it MUST immediately follow a
+       "comment" attribute and specifies the language for that attribute
+       [RFC1766].  The client MAY specify more than comment if it
+       additionally specifies a different language for each of those
+       comments.  The server SHOULD attempt to store each comment,
+       together with that comment's lanuage attribute.
+
+       This attribute SHOULD NOT be mandatory.
+
+   "command"
+       "command" bypasses the session channel "exec" and "shell" requests
+       by always executing the specified command (as if it had been
+       executed using an "exec" request).
+
+       This attribute SHOULD be mandatory.  This attribute MUST NOT be
+       specified if the "subsystem" attribute is specified.
+
+   "subsystem"
+       "subsystem" specifies that the specified subsystem should be started
+       when this key is used (as if it had been started using a "subsystem"
+       request.
+
+       This attribute SHOULD be mandatory.  This attribute MUST NOT be
+       specified if the "command" attribute is specified.

-   The comment field contains user-specified text about the public key
-   and MAY be empty.
+   "restrict"
+       The value of this attribute contains server functions that may
+       not be performed when this key is used.  It is a comma seperated
+       list.  Element names are specified in the same way as attribute
+       names, above.  The following restrictions are currently defined:
+
+       Currently defined restrictions are:
+
+        "x11"
+        "shell"
+        "exec"
+        "agent"
+        "env"
+        "subsystem"
+
+	 The "x11" restriction specifies that X11 forwarding may not be
+       performed when this key is in use.  The "shell" restriction
+       specifies that session channel "shell" requests should be denied
+       when this key is in use.  The "exec" restriction specifies that
+       session channel "exec" requests should be denied when this key
+       is in use.  The "agent" restriction specifies that session channel
+       "auth-agent-req" requests should be denied when this key is in use.
+       The "env" restriction specifies that session channel "env" requests
+       should be denied when this key is in use.  The "subsystem"
+       restriction specifies that subsystems may not be started when this
+       public key is in use (if the "subsystem" attribute is also 
specified,
+       the subsystem specified in that attribute is exempted from this
+       restriction).
+
+       This attribute SHOULD be mandatory.
+
+   "port-forward"
+       "port-forward" specifies that no "direct-tcpip" requests should be
+       accepted, except to those hosts specified in the comma-separated
+       list supplied as a value to this attribute.  If the value of this
+       attribute is empty, all "direct-tcpip" requests should be refused
+       when using this key.
+
+       This attribute SHOULD be mandatory.
+
+   "reverse-forward"
+       "reverse-forward" specifies that no "tcpip-forward" requests should
+       be accepted, accept for the port numbers in the comma-separated
+       list supplied as a value to this attribute.  If the value of this
+       attribute is empty, all "tcpip-forward" requests should be refused
+       when using this key.
+
+       This attribute SHOULD be mandatory.
+
+   In addition to the attributes and restrictions specified by the client,
+   the server MAY provide a method for administrators to compulsorily 
enforce
+   certain attributes or restrictions.

  3.3 Removing a public key

Integrate the attribute stuff into the list response.  Further, remove 
the "command" request, since it's no longer useful in light of the 
additional "add" functionality.  Finally, add a method of discovering 
the server's supported restrictions.  I'm convinced this will assist in 
building a sane GUI for this stuff.  The split that's present between 
"attributes" and "restrictions" makes the response to this request a 
little messy.  I'm not sure whether it would be better to make the 
"restrictions" be freestanding attributes, being that they're (as far as 
I can tell) all boolean.

@@ -403,35 +515,47 @@

     	string    "publickey"
-   	string    comment
     	string    public-key algorithm name
     	string    public-key blob
-
-   The comment field contains user-specified text about the public key
-   and MAY be empty.
+   	uint32    attribute-count
+		string attrib-name
+		string attrib-value
+	repeated attribute-count times

-3.5 Associate public key with a mandatory command
+3.5 Listing server capabilities

-   If the client wishes to associate a command with a specific public
-   key, the client sends:
-
-   	string    "command"
-   	string    public-key algorithm name
-   	string    public-key blob
-   	string    command
+   If the client wishes to know which restrictions the server supports,
+   it sends:

-   The request MUST fail if the public key does not already exist on the
-   server.
+      string    "listattributes"

-   An implementation MAY choose not to support this request.
+   The server will respond with zero or more of the following responses:

+      string    "attribute"
+      string    attribute name
+      boolean   compulsory
+
+   The server will then respond with zero or more of the following
+   responses:
+
+      string    "restriction"
+      string    restriction name
+      boolean   compulsory
+
+   The server MAY include "restrict" in the list of attributes it supports.
+   The client SHOULD NOT require the server to do so in order to accept
+   that the server supports the list of restrictions returned by the
+   server.

+   Following the last "restriction" response, a status packet MUST be
+   sent.

+   An implementation MAY choose not to support this request.

If I should avoid wholesale editing of other people's documents in the 
future, please let me know :-)

---

From: Bill Sommerfeld <[email-masked]>
Date: Thu, 24 Jul 2003 10:25:18 -0400

> future, please let me know :-)

One common fix to this problem is to add the new editor's name to the
document ;-)

other meta-comments:  [not speaking as WG chair..]

it would be helpful to also add a list of some well-known
restrictions, while making it clear that precise interpretation is a
local matter on the server.

Decide whether to call them "attributes" or "restrictions"

Having a "critical bit" for restrictions may be important.  (this
means "fail the request if I don't know what to do with it")

Maybe the way to go is to define restrictions as attributes with the
critical bit set?

					- Bill

---

From: Jon Bright <[email-masked]>
Date: Thu, 24 Jul 2003 16:42:00 +0200

> One common fix to this problem is to add the new editor's name to the

I wouldn't want to go treading on other people's toes :-)

> local matter on the server.

I'm not sure what you mean by this - we're already listing x11, shell, 
exec, agent, env and subsystem?

> Decide whether to call them "attributes" or "restrictions"

At the moment, they're two different things (and I think I used the 
names consistently to refer to one or the other).  I'm increasingly 
inclined to the view that the restrictions should become attributes.

> Maybe the way to go is to define restrictions as attributes with the

I think so.  If everyone else also thinks so, I'd be happy to produce 
another version of my edits with this changed.

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 24 Jul 2003 10:36:09 -0700

> "restrictions" be freestanding attributes, being that they're (as far as 

I think "from" should be added also (i.e., what source addresses a
client may use this key from).

Yeah, all restrictions should be standalone attributes.  Those
restrictions which you modeled as values of the "restrict" attributes
could be standalone attributes with boolean values (or null; if the
attribute is present, the restriction is on, if not, not).

The "subsystem" restriction should go and be replaced by the subsystem
attribute which should list the sub-systems that a user is allowed to
start (if the list empty, then none are allowed; if the attribute is
missing or if the value is "*", then all are allowed).

Cheers,

Nico
--

---

From: Jon Bright <[email-masked]>
Date: Thu, 24 Jul 2003 19:48:42 +0200

(a side not - Brent has sent me the XML source, which I'm currently 
updating to match my earlier mail)

> client may use this key from).

Sounds like a good idea.

> Yeah, all restrictions should be standalone attributes.  Those

I've now converted them all to be.

> attribute is present, the restriction is on, if not, not).

I've defined them as being null.

> missing or if the value is "*", then all are allowed).

This doesn't match the "command" attribute, which starts the command 
itself.  Then again, I'm unhappy with that aspect of the "command" 
attribute's behaviour - it raises questions such as When does it start 
the command?, Does it wait for the client to request a pty or run the 
command without one?, etc.  Maybe change "command" to specify a command 
which the user's allowed to execute.  Ideally, change it to specify more 
than one command, but in that case, I'm not sure what could be used as a 
separator.  Maybe allow for more than one command attribute to be set?

---

From: Joseph Galbraith <[email-masked]>
Date: Thu, 24 Jul 2003 12:25:53 -0600

> separator.  Maybe allow for more than one command attribute to be set?

If I'm not mistaken openssh allows a command to be associated
with the key?  I believe ssh.com and f-secure do as well.

Does any one know what their behavior is?  I was thinking that
whenever one of exec / shell where issued, the command specified
by the publickey was substituted.  But maybe that isn't the case.

If we really wanted allowed commands, and I'm not sure we do,
the attrib-value string could be:

string attrib-value
	uint32 command-count
	string command[1]
	string command[2]
	string command[...]
	string command[command-count]

But, how closely doe the user have to match the command?
Exactly?  Just the first argument?

I'm worried about over complexifying things... sure we could do
it, but one of the goals of the subsystem is to be easy to
implement.

Maybe we should rename command to command-override and
specify that it forces either the 'exec' or the 'shell'
session channel requests to act as if the 'exec' request
had been issued with the given command.

- Joseph

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 24 Jul 2003 11:32:06 -0700

> separator.  Maybe allow for more than one command attribute to be set?

The "command" attribute should apply to "session" type channels and
should be executed when the "exec" or "shell" channel requests are
processed.  If a null "command" is given then neither should be allowed.
If no "command" is given both should be allowed.

The "subsystem" attribute should apply to "session" type channels when
the "subsystem" requests are processed.  If a null "subsystem" is given
then none should be allowed.  If no "subsystem" is given then any should
be allowed.

Cheers,

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 24 Jul 2003 11:37:22 -0700

> by the publickey was substituted.  But maybe that isn't the case.

That's exactly it.

> had been issued with the given command.

That's how we should define its semantics.

Cheers,

Nico
--