| <?xml version="1.0" encoding="UTF-8" ?> |
| <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" |
| "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" |
| [ |
| <!ENTITY % defs SYSTEM "defs.ent"> %defs; |
| ]> |
| |
| |
| |
|
|
| <book id="security"> |
|
|
| <bookinfo> |
| <title>Security Extension Specification</title> |
| <subtitle>X Consortium Standard</subtitle> |
| <authorgroup> |
| <author> |
| <firstname>David</firstname><othername>P.</othername><surname>Wiggins</surname> |
| <affiliation><orgname>X Consortium</orgname></affiliation> |
| </author> |
| </authorgroup> |
| <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> |
| <releaseinfo>Version 7.1</releaseinfo> |
| <copyright><year>1996</year><holder>X Consortium</holder></copyright> |
|
|
| <legalnotice> |
| <para> |
| Permission is hereby granted, free of charge, to any person obtaining a copy |
| of this software and associated documentation files (the “Software”), to deal |
| in the Software without restriction, including without limitation the rights |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| copies of the Software, and to permit persons to whom the Software is |
| furnished to do so, subject to the following conditions: |
| </para> |
| <para> |
| The above copyright notice and this permission notice shall be included in |
| all copies or substantial portions of the Software. |
| </para> |
| <para> |
| THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| </para> |
| <para> |
| Except as contained in this notice, the name of the X Consortium shall not be |
| used in advertising or otherwise to promote the sale, use or other dealings |
| in this Software without prior written authorization from the X Consortium. |
| </para> |
| <para>X Window System is a trademark of The OpenGroup.</para> |
| </legalnotice> |
|
|
| <pubdate>November 15, 1996</pubdate> |
|
|
| </bookinfo> |
|
|
| <chapter id='Introduction'> |
| <title>Introduction</title> |
|
|
| <para> |
| The Security extension contains new protocol needed to provide enhanced X |
| server security. The Security extension should not be exposed to untrusted |
| clients (defined below). |
| </para> |
|
|
| </chapter> |
|
|
| <chapter id='Requests'> |
| <title>Requests</title> |
|
|
| <sect1 id='SecurityQueryVersion'> |
| <title>SecurityQueryVersion</title> |
| <para> |
| This request returns the major and minor version numbers of this extension. |
| </para> |
|
|
| <para>SecurityQueryVersion</para> |
|
|
| <informaltable frame='none'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='2' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.5*"/> |
| <tbody> |
| <row> |
| <entry> |
| <para>client-major-version</para> |
| </entry> |
| <entry> |
| <para>CARD16</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>client-minor-version</para> |
| </entry> |
| <entry> |
| <para>CARD16</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>=></para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>server-major-version</para> |
| </entry> |
| <entry> |
| <para>CARD16</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>server-minor-version</para> |
| </entry> |
| <entry> |
| <para>CARD16</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| The client-major-version and client-minor-version numbers indicate what |
| version of the protocol the client wants the server to implement. The |
| server-major-version and the server-minor-version numbers returned |
| indicate the protocol this extension actually supports. This might not |
| equal the version sent by the client. An implementation can (but need not) |
| support more than one version simultaneously. The server-major-version |
| and server-minor-version allow the creation of future revisions of the |
| Security protocol that may be necessary. In general, the major version |
| would increment for incompatible changes, and the minor version would |
| increment for small, upward-compatible changes. Servers that support |
| the protocol defined in this document will return a server-major-version |
| of one (1), and a server-minor-version of zero (0). |
| </para> |
|
|
| <para> |
| Clients using the Security extension must issue a SecurityQueryVersion |
| request before any other Security request in order to negotiate a compatible |
| protocol version; otherwise, the client will get undefined behavior |
| (Security may or may not work). |
| </para> |
| </sect1> |
|
|
| <sect1 id='SecurityGenerateAuthorization'> |
| <title>SecurityGenerateAuthorization</title> |
|
|
| <para> |
| This request causes the server to create and return a new authorization with |
| specific characteristics. Clients can subsequently connect using the new |
| authorization and will inherit some of the characteristics of the |
| authorization. |
| </para> |
|
|
| <para> |
| SecurityGenerateAuthorization |
| </para> |
| <informaltable frame='none'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='2' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.5*"/> |
| <tbody> |
| <row> |
| <entry> |
| <para>authorization-protocol-name</para> |
| </entry> |
| <entry> |
| <para>STRING8</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>authorization-protocol-data</para> |
| </entry> |
| <entry> |
| <para>STRING8</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>value-mask</para> |
| </entry> |
| <entry> |
| <para>BITMASK</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>value-list</para> |
| </entry> |
| <entry> |
| <para>LISTofVALUE</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>=></para> |
| </entry> |
| <entry> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>authorization-id</para> |
| </entry> |
| <entry> |
| <para>AUTHID</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>authorization-data-return</para> |
| </entry> |
| <entry> |
| <para>STRING8</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| Errors: <function>AuthorizationProtocol</function>, <function>Value</function>, <function>Alloc</function> |
| </para> |
|
|
| <para> |
| authorization-protocol-name is the name of the authorization method for |
| which the server should generate a new authorization that subsequent |
| clients can use to connect to the server. If the authorization-protocol-name |
| is not one that the server supports, or if authorization-protocol-data |
| does not make sense for the given authorization-protocol-name, an |
| AuthorizationProtocol error results. |
| </para> |
|
|
| <para> |
| authorization-protocol-data is authorization-method specific data that can |
| be used in some way to generate the authorization. |
| </para> |
|
|
| <note><para> |
| In this version of the extension, the only authorization method |
| required to be supported is "MIT-MAGIC-COOKIE-1" with any amount |
| of authorization-protocol-data (including none). The server may use the |
| authorization-protocol-data as an additional source of randomness used |
| to generate the authorization. Other authorization methods can supply |
| their own interpretation of authorization-protocol-data. |
| </para></note> |
|
|
| <para> |
| The value-mask and value-list specify attributes of the authorization |
| that are to be explicitly initialized. The possible values are: |
| </para> |
|
|
| <informaltable frame='topbot'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='3' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.0*"/> |
| <colspec colname='c3' colwidth="1.0*"/> |
| <thead> |
| <row rowsep='1'> |
| <entry>Attribute</entry> |
| <entry>Type</entry> |
| <entry>Default</entry> |
| </row> |
| </thead> |
| <tbody> |
| <row> |
| <entry> |
| <para>timeout</para> |
| </entry> |
| <entry> |
| <para>CARD32</para> |
| </entry> |
| <entry> |
| <para>60</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>group</para> |
| </entry> |
| <entry> |
| <para>XID or None</para> |
| </entry> |
| <entry> |
| <para>None</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>trust-level</para> |
| </entry> |
| <entry> |
| <para>{SecurityClientTrusted,</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para></para> |
| </entry> |
| <entry> |
| <para>SecurityClientUntrusted}</para> |
| </entry> |
| <entry> |
| <para>SecurityClientUntrusted</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>event-mask</para> |
| </entry> |
| <entry> |
| <para>SecurityAuthorizationRevoked,</para> |
| </entry> |
| </row> |
| <row rowsep="1"> |
| <entry> |
| <para></para> |
| </entry> |
| <entry> |
| <para>or None</para> |
| </entry> |
| <entry> |
| <para>None</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| timeout is the timeout period in seconds for this authorization. A |
| timeout value of zero means this authorization will never expire. For |
| non-zero timeout values, when timeout seconds have elapsed since the |
| last time that the authorization entered the state of having no |
| connections authorized by it, and if no new connections used the |
| authorization during that time, the authorization is automatically purged. |
| (Note that when an authorization is created, it enters the state of having no |
| connections authorized by it.) Subsequent connection attempts using that |
| authorization will fail. This is to facilitate "fire and forget" launching of |
| applications. |
| </para> |
|
|
| <para> |
| group is an application group ID as defined by the Application Group |
| extension, or None. Any other values will cause a Value error. When a |
| group is destroyed, all authorizations specifying that group are revoked |
| as described under the SecurityRevokeAuthorization request. The Application |
| Group extension attaches additional semantics to the group. |
| </para> |
|
|
| <para> |
| trust-level tells whether clients using the authorization are trusted or |
| untrusted. If trust-level is not one of the constants SecurityClientTrusted |
| or SecurityClientUntrusted, a Value error results. |
| </para> |
|
|
| <para> |
| event-mask defines which events the client is interested in for this |
| authorization. When the authorization expires or is revoked if event-mask |
| contains SecurityAuthorizationRevoked a SecurityAuthorizationRevoked event |
| is reported to the client. |
| </para> |
|
|
| <para> |
| The SecurityAuthorizationRevoked event contains the following field: |
| </para> |
|
|
| <informaltable frame='topbot'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='2' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.5*"/> |
| <thead> |
| <row rowsep="1"> |
| <entry>Field</entry> |
| <entry>Type</entry> |
| </row> |
| </thead> |
| <tbody> |
| <row> |
| <entry> |
| <para>authorization-id</para> |
| </entry> |
| <entry> |
| <para>AUTHID</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| where authorization-id is the identification of the authorization that was |
| revoked. |
| </para> |
| <para> |
| If an invalid value-mask is specified, a Value error occurs. |
| </para> |
|
|
| <para> |
| The returned authorization-id is a non-zero value that uniquely identifies |
| this authorization for use in other requests. The value space for type |
| AUTHID is not required to be disjoint from values spaces of other core |
| X types, e.g. resource ids, atoms, visual ids, and keysyms. Thus, a given |
| numeric value might be both a valid AUTHID and a valid atom, for example. |
| </para> |
|
|
| <para> |
| authorization-data-return is the data that a client should use in some |
| authorization-method-specific way to make a connection with this |
| authorization. For "MIT-MAGIC-COOKIE-1," authorization-data-return should |
| be sent as the authorization-protocol-data in the connection setup message. |
| It is not required that other authorization methods use |
| authorization-data-return this way. |
| </para> |
|
|
| </sect1> |
|
|
| <sect1 id='SecurityRevokeAuthorization'> |
| <title>SecurityRevokeAuthorization</title> |
|
|
| <para> |
| This request deletes an authorization created by SecurityGenerateAuthorization. |
| </para> |
|
|
| <para> |
| SecurityRevokeAuthorization |
| </para> |
|
|
| <informaltable frame='none'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='2' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.5*"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><emphasis remap='I'>authorization-id</emphasis></para> |
| </entry> |
| <entry> |
| <para>AUTHID</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| Errors: <function>Authorization</function> |
| </para> |
|
|
| <para> |
| If authorization-id does not name a valid authorization, an Authorization |
| error occurs. Otherwise, this request kills all clients currently connected |
| using the authorization specified by authorization-id. The authorization is |
| deleted from the server's database, so future attempts by clients to connect |
| with this authorization will fail. |
| </para> |
|
|
| </sect1> |
| </chapter> |
|
|
| <chapter id='Changes_to_Core_Requests'> |
| <title>Changes to Core Requests</title> |
|
|
| <para> |
| A server supporting this extension modifies the handling of some core |
| requests in the following ways. |
| </para> |
| <sect1 id='Resource_ID_Usage'> |
| <title>Resource ID Usage</title> |
|
|
| <para> |
| If an untrusted client makes a request that specifies a resource ID that is |
| not owned by another untrusted client, a protocol error is sent to the |
| requesting client indicating that the specified resource does not exist. |
| The following exceptions apply. An untrusted client can: |
| </para> |
|
|
| <orderedlist> |
| <listitem> |
| <para> |
| use the QueryTree, GetGeometry, and TranslateCoordinates requests |
| without restriction. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| use colormap IDs that are returned in the default-colormap field of its |
| connection setup information in any colormap requests. |
| </para> |
| </listitem> |
| <listitem> |
| <para>specify a root window as:</para> |
| <orderedlist> |
| <listitem> |
| <para> |
| the drawable field of CreatePixmap, CreateGC, and QueryBestSize. |
| </para> |
| </listitem> |
| <listitem> |
| <para>the parent field of CreateWindow.</para> |
| </listitem> |
| <listitem> |
| <para> |
| the window field of CreateColormap, ListProperties, and GetWindowAttributes. |
| </para> |
| </listitem> |
| <listitem> |
| <para>the grab-window or confine-to fields of GrabPointer. |
| </para> |
| </listitem> |
| <listitem> |
| <para>the grab-window field of UngrabButton.</para> |
| </listitem> |
| <listitem> |
| <para> |
| the destination of SendEvent, but only if all of the following are true. |
| (These conditions cover all the events that the ICCCM specifies with |
| a root window destination.) |
| </para> |
| <orderedlist> |
| <listitem> |
| <para>The propagate field of SendEvent is False.</para> |
| </listitem> |
| <listitem> |
| <para> |
| The event-mask field of SendEvent is ColormapChange, |
| StructureNotify, or the logical OR of SubstructureRedirect with |
| SubstructureNotify. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| The event type being sent is UnmapNotify, ConfigureRequest, or |
| ClientMessage. |
| </para> |
| </listitem> |
| </orderedlist> |
| </listitem> |
| <listitem> |
| <para> |
| the window field of ChangeWindowAttributes, but only if the value-mask |
| contains only event-mask and the corresponding value is StructureNotify, |
| PropertyChange, or the logical OR of both. |
| </para> |
| </listitem> |
| </orderedlist> |
| </listitem> |
| </orderedlist> |
|
|
| <note> |
| <para> |
| ISSUE: are root window exceptions needed for these? WarpPointer, ReparentWindow |
| (parent), CirculateWindow, QueryPointer (emacs does this), GetMotionEvents. |
| </para> |
| </note> |
|
|
| </sect1> |
| <sect1 id='Extension_Security'> |
| <title>Extension Security</title> |
|
|
| <para> |
| This extension introduces the notion of secure and insecure extensions. A |
| secure extension is believed to be safe to use by untrusted clients; that |
| is, there are no significant security concerns known that an untrusted |
| client could use to destroy, modify, or steal data of trusted clients. This |
| belief may be founded on a careful analysis of the extension protocol, |
| its implementation, and measures taken to "harden" the extension to close |
| security weaknesses. All extensions not considered secure are called |
| insecure. The implementation details of how an extension is identified as |
| secure or insecure are beyond the scope of this specification. |
| </para> |
|
|
| <para> |
| <function>ListExtensions</function> will only return names of secure |
| extensions to untrusted clients. |
| </para> |
|
|
| <para> |
| If an untrusted client uses <function>QueryExtension</function> on an |
| insecure extension that the server supports, the reply will have the |
| present field set to False and the major-opcode field set to zero to |
| indicate that the extension is not supported. |
| </para> |
|
|
| <para> |
| If an untrusted client successfully guesses the major opcode of an |
| insecure extension, attempts by it to execute requests with that major |
| opcode will fail with a Request error. |
| </para> |
|
|
| </sect1> |
|
|
| <sect1 id='Keyboard_Security'> |
| <title>Keyboard Security</title> |
|
|
|
|
| <para> |
| The protocol interpretation changes in this section are intended to prevent |
| untrusted applications from stealing keyboard input that was meant for |
| trusted clients and to prevent them from interfering with the use of the |
| keyboard. |
| </para> |
|
|
| <para> |
| The behavior of some keyboard-related requests and events is modified when |
| the client is untrusted depending on certain server state at the time of |
| request execution or event generation. Specifically, if a hypothetical |
| keyboard event were generated given the current input focus, pointer |
| position, keyboard grab state, and window event selections, and if that |
| keyboard event would not be delivered to any untrusted client, the |
| following changes apply: |
| </para> |
|
|
| <orderedlist> |
| <listitem> |
| <para> |
| The bit vector representing the up/down state of the keys returned by |
| <function>QueryKeymap</function> and |
| <function>KeymapNotify</function> is all zeroes. |
| </para> |
| </listitem> |
| <listitem> |
| <para>GrabKeyboard returns a status of AlreadyGrabbed.</para> |
| </listitem> |
| <listitem> |
| <para> |
| <function>SetInputFocus</function> does nothing. Note that this means the |
| Globally Active |
| Input and WM_TAKE_FOCUS mechanisms specified in the ICCCM will |
| not work with untrusted clients. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Passive grabs established by GrabKey that would otherwise have activated |
| do not activate. |
| </para> |
| </listitem> |
| </orderedlist> |
|
|
| <para> |
| If an untrusted client attempts to use any of the following requests, the |
| only effect is that the client receives an Access error: SetModifierMapping, |
| ChangeKeyboardMapping, ChangeKeyboardControl. |
| </para> |
|
|
| <para> |
| If an InputOnly window owned by an untrusted client has a parent owned by a |
| trusted client, all attempts to map the window will be ignored. This includes |
| mapping attempts resulting from MapWindow, MapSubwindows, ReparentWindow, |
| and save-set processing. |
| </para> |
| <para> |
| However, if the parent of an InputOnly window owned by an untrusted client |
| is the root window, attempts to map that window will be performed as |
| expected. This is in line with the root window exceptions above. |
| </para> |
| </sect1> |
|
|
| <sect1 id='Image_Security'> |
| <title>Image Security</title> |
|
|
| <para> |
| It should be impossible for an untrusted client to retrieve the image |
| contents of a trusted window unless a trusted client takes action to allow |
| this. We introduce the following defenses in support of this requirement. |
| </para> |
|
|
| <para> |
| The restrictions on resource ID usage listed above prevent untrusted clients |
| from using GetImage directly on windows not belonging to trusted clients. |
| </para> |
|
|
| <para> |
| If an untrusted client tries to set the background-pixmap attribute of an |
| untrusted window to None, the server will instead use a server-dependent |
| background which must be different than None. |
| </para> |
|
|
| <para> |
| The X protocol description of <function>GetImage</function> states that the |
| returned contents of regions of a window obscured by noninferior windows are |
| undefined if the window has no backing store. Some implementations return the |
| contents of the obscuring windows in these regions. When an untrusted client |
| uses <function>GetImage</function>, this behavior is forbidden; the server must |
| fill the obscured regions in the returned image with a server-dependent pattern. |
| </para> |
|
|
| <para> |
| If an untrusted window has trusted inferiors, their contents are vulnerable |
| to theft via <function>GetImage</function> on the untrusted parent, as well |
| as being vulnerable to destruction via drawing with subwindow-mode |
| IncludeInferiors on the untrusted parent. An untrusted window having trusted |
| inferiors can only occur at the request of a trusted client. It is expected |
| to be an unusual configuration. |
| </para> |
|
|
| </sect1> |
|
|
| <sect1 id='Property_Security'> |
| <title>Property Security</title> |
|
|
| <para> |
| Unlike the other security provisions described in this document, security for |
| property access is not amenable to a fixed policy because properties are |
| used for inter-client communication in diverse ways and may contain data of |
| varying degrees of sensitivity. Therefore, we only list the possible |
| restrictions the server may decide to impose on use of properties on trusted |
| windows by untrusted clients. How the server chooses which restrictions from |
| this list to apply to a particular property access is implementation dependent |
| <footnote><para> |
| In the X Consortium server implementation, property access is controlled by |
| a configuration file; see the -sp option in the Xserver(1) manual page. |
| </para></footnote>. |
| </para> |
|
|
| <para>The X Protocol property requests are |
| <function>ChangeProperty</function>, |
| <function>GetProperty</function>, |
| <function>DeleteProperty</function>, |
| <function>RotateProperties</function>, and |
| <function>ListProperties</function>. For these requests, the server can |
| allow the request to execute normally (as if it had been issued by a |
| trusted client), ignore the request completely (as if it were a NoOperation), |
| or ignore the request except to send an Atom error to the client. Ignoring |
| a <function>ListProperties</function> request means replying that |
| the window has no properties. <function>ListProperties</function> may also |
| reply with a subset of the existing properties if the server is doing |
| property hiding; see below. An ignored <function>GetProperty</function> |
| request may reply that the property does not exist, or that it exists but |
| contains no data. |
| </para> |
|
|
| <para> |
| The server may decide to hide certain properties on certain windows from |
| untrusted clients |
| <footnote><para> |
| The X Consortium server implementation does not currently provide a way to |
| hide properties. |
| </para></footnote>. |
| If a property is to be hidden, it must be done consistently to avoid |
| confusing clients. This means that for untrusted clients: |
| </para> |
|
|
| <itemizedlist> |
| <listitem> |
| <para> |
| That property should not be returned by |
| <function>ListProperties</function>. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <function>PropertyNotify</function> events should not be sent for that |
| property.</para> |
| </listitem> |
| <listitem> |
| <para> |
| <function>GetProperty</function> on that property should reply that the |
| property does not exist (the return type is None, the format and |
| bytes-after are zero, and the value is empty). |
| </para> |
| </listitem> |
| </itemizedlist> |
|
|
| <para> |
| For a property that the server is protecting but not hiding, consistency |
| must also be maintained: |
| </para> |
|
|
| <itemizedlist> |
| <listitem> |
| <para> |
| That property should be returned by <function>ListProperties</function>. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <function>PropertyNotify</function> events should be sent for that property. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <function>GetProperty</function> on that property should reply that the |
| property exists (if it really does) but the value is empty |
| (return type and format are their real values, and the "length of value" |
| field in the reply is zero). |
| </para> |
| </listitem> |
| </itemizedlist> |
|
|
| </sect1> |
|
|
| <sect1 id='Miscellaneous_Security'> |
| <title>Miscellaneous Security</title> |
|
|
| <para> |
| If an untrusted client attempts to use |
| <function>ChangeHosts</function>, |
| <function>ListHosts</function>, or |
| <function>SetAccessControl</function>, |
| the only effect is that the client receives an Access error. |
| </para> |
|
|
| <para> |
| If an untrusted client attempts to use <function>ConvertSelection</function> |
| on a selection with a trusted selection owner window, the server generates |
| a SelectionNotify event to the requestor with property None. |
| </para> |
| </sect1> |
| </chapter> |
|
|
| <chapter id='New_Authorization_Method'> |
| <title>New Authorization Method</title> |
|
|
| <para> |
| This extension includes a new authorization method named |
| "XC-QUERY-SECURITY-1". Its purpose is to allow an external agent such as |
| the X firewall proxy to probe an X server to determine whether that server |
| meets certain security criteria without requiring the agent to have its |
| own authorization for that server. The agent may use the returned information |
| to make a decision. For example, the X firewall proxy may choose not to |
| forward client connections to servers that do not meet the criteria. |
| </para> |
|
|
| <para> |
| To use this authorization method, the client (or proxy) sends |
| "XC-QUERY-SECURITY-1" as the authorization-protocol-name in the initial |
| connection setup message. The authorization-protocol-data may be empty or |
| may contain additional security criteria described below. If the success |
| field of the server's reply is Authenticate, the server supports the |
| security extension, and the server meets all specified additional security |
| criteria. In this case, the client should resend the initial connection |
| setup message substituting the authorization protocol name and data |
| that should be used to authorize the connection. If the success field of the |
| server's reply is anything other than Authenticate, either the server does not |
| support the security extension, does not meet (or cannot determine if it |
| meets) all of the additional security criteria, or chooses for internal reasons |
| not to answer with Authenticate. In this case, the client should close the |
| connection. |
| </para> |
|
|
| <para> |
| If the authorization-protocol-data sent with "XC-QUERY-SECURITY-1" is not |
| empty, it specifies additional security criteria for the server to check, as |
| follows. |
| </para> |
|
|
| <para> |
| <function>authorization-protocol-data</function> |
| </para> |
|
|
| <informaltable frame='none'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='2' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.5*"/> |
| <tbody> |
| <row> |
| <entry> |
| <para>policy-mask</para> |
| </entry> |
| <entry> |
| <para>BITMASK</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>policies</para> |
| </entry> |
| <entry> |
| <para>LISTofSECURITYPOLICY</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| The policy-mask field is any logical-OR combination of the constants |
| Extensions and SitePolicies. For each bit set in policy-mask, there is a |
| SECURITYPOLICY element in policies. The nth element in policies corresponds |
| to the nth 1-bit in policy-mask, counting upward from bit 0. |
| </para> |
|
|
| <para><function>SECURITYPOLICY</function></para> |
|
|
| <informaltable frame='none'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='2' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.5*"/> |
| <tbody> |
| <row> |
| <entry> |
| <para>policy-type</para> |
| </entry> |
| <entry> |
| <para>{Disallow, Permit}</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>names</para> |
| </entry> |
| <entry> |
| <para>LISTofSTR</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| For a SECURITYPOLICY corresponding to policy-mask Extensions, if |
| policy-type is Disallow the server is required to consider as insecure |
| all extensions given in names. No policy is specified for extensions |
| not listed in names. If policy-type is Permit the server may consider |
| only those extensions given in names to be secure; all other extensions |
| must be treated as insecure. If these constraints are not met, the server |
| should not return Authenticate in the success field of the reply. |
| Servers can but need not dynamically configure themselves in response |
| to an Extensions SECURITYPOLICY; a conforming server might simply compare |
| the policy with a compiled-in table of extensions and their security status. |
| </para> |
|
|
| <para> |
| For a SECURITYPOLICY corresponding to policy-mask SitePolicies, policy-type |
| Disallow means the server must not have been configured with any of the site |
| policies given in names. Policy-type Permit means the server must have |
| been configured with at least one of the site policies given in names. If |
| these constraints are not met, the server should not return Authenticate in |
| the success field of the reply. |
| </para> |
|
|
| <para> |
| SitePolicies provide a way to express new forms of security-relevant |
| information that could not be anticipated at the time of this writing. |
| For example, suppose the server is found to have a critical security defect. |
| When a fix is developed, a site policy string could be associated with the |
| fix. Servers with the fix would advertise that site policy, and the X |
| firewall proxy would specify that site policy in a SECURITYPOLICY with |
| policy-type Permit. |
| </para> |
|
|
| </chapter> |
|
|
| <chapter id='Encoding'> |
| <title>Encoding</title> |
|
|
| <para> |
| Please refer to the X11 Protocol Encoding document as this section |
| uses syntactic conventions and data types established there. |
| </para> |
|
|
| <para> |
| The name of this extension is "SECURITY". |
| </para> |
|
|
| <sect1 id='Types'> |
| <title>Types</title> |
| <para> |
| AUTHID: CARD32 |
| </para> |
| </sect1> |
|
|
| <sect1 id='Request_Encoding'> |
| <title>Request Encoding</title> |
|
|
| <para> |
| SecurityQueryVersion |
| </para> |
| <literallayout remap='FD'> |
| 1 CARD8 major-opcode |
| 1 0 minor-opcode |
| 2 2 request length |
| 2 CARD16 client-major-version |
| 2 CARD16 client-minor-version |
| => |
| 1 1 Reply |
| 1 unused |
| 2 CARD16 sequence number |
| 4 0 reply length |
| 2 CARD16 server-major-version |
| 2 CARD16 server-minor-version |
| 20 unused |
| </literallayout> |
|
|
| <para> |
| <function>SecurityRevokeAuthorization</function> |
| </para> |
|
|
| <literallayout remap='FD'> |
| 1 CARD8 major-opcode |
| 1 2 minor-opcode |
| 2 2 request length |
| 4 AUTHID authorization-id |
| </literallayout> |
|
|
| <para> |
| SecurityGenerateAuthorization |
| </para> |
|
|
| <literallayout remap='FD'> |
| 1 CARD8 major-opcode |
| 1 1 minor-opcode |
| 2 3 + (m+n+3)/4 + s request length |
| 2 CARD16 m, number of bytes in authorization protocol name |
| 2 CARD16 n, number of bytes in authorization data |
| m STRING8 authorization protocol name |
| n STRING8 authorization protocol data |
| p unused, p=pad(m+n) |
| 4 BITMASK value-mask (has s bits set to 1) |
| #x00000001 timeout |
| #x00000002 trust-level |
| #x00000004 group |
| #x00000008 event-mask |
| 4s LISTofVALUE value-list |
| </literallayout> |
|
|
| <para> |
| VALUES |
| </para> |
| <literallayout remap='FD'> |
| 4 CARD32 timeout |
| 4 trust-level |
| 0 SecurityClientTrusted |
| 1 SecurityClientUntrusted |
| 4 XID group |
| 0 None |
| 4 CARD32 event-mask |
| #x00000001 SecurityAuthorizationRevoked |
| => |
| 1 1 Reply |
| 1 unused |
| 2 CARD16 sequence number |
| 4 (q+3)/4 reply length |
| 4 AUTHID authorization-id |
| 2 CARD16 data-length |
| 18 unused |
| q STRING8 authorization-data-return |
| r unused, r=pad(q) |
| </literallayout> |
|
|
| </sect1> |
|
|
| <sect1 id='Event_Encoding'> |
| <title>Event Encoding</title> |
| <para> |
| <function>SecurityAuthorizationRevoked</function> |
| </para> |
|
|
| <literallayout remap='FD'> |
| 1 0+extension event base code |
| 1 unused |
| 2 CARD16 sequence number |
| 4 AUTHID authorization id |
| 24 unused |
| </literallayout> |
|
|
| </sect1> |
|
|
| <sect1 id='Authorization_Method_Encoding'> |
| <title>Authorization Method Encoding</title> |
|
|
| <para> |
| For authorization-protocol-name "XC-QUERY-SECURITY-1", the |
| authorization-protocol-data is interpreted as follows: |
| </para> |
|
|
| <para> |
| <function>authorization-protocol-data</function> |
| </para> |
| <literallayout remap='FD'> |
| 1 BITMASK policy-mask |
| #x00000001 Extensions |
| #x00000002 SitePolicies |
| m LISTofSECURITYPOLICY policies |
| </literallayout> |
|
|
| <para> |
| <function>SECURITYPOLICY</function> |
| </para> |
|
|
| <literallayout remap='FD'> |
| 1 policy-type |
| 0 Permit |
| 1 Disallow |
| 1 CARD8 number of STRs in names |
| n LISTofSTR names |
| </literallayout> |
|
|
| <para> |
| LISTofSTR has the same encoding as in the X protocol: each STR is a single |
| byte length, followed by that many characters, and there is no padding or |
| termination between STRs. |
| </para> |
| </sect1> |
|
|
| </chapter> |
| <chapter id='C_Language_Binding'> |
| <title>C Language Binding</title> |
|
|
| <para> |
| The header for this extension is <X11/extensions/security.h>. All |
| identifier names provided by this header begin with XSecurity. |
| </para> |
|
|
| <para> |
| All functions that have return type Status will return nonzero for |
| success and zero for failure. |
| </para> |
|
|
| <funcsynopsis id='XSecurityQueryExtension'> |
| <funcprototype> |
| <funcdef>Status <function>XSecurityQueryExtension</function></funcdef> |
| <paramdef>Display <parameter> *dpy</parameter></paramdef> |
| <paramdef>int <parameter> *major_version_return</parameter></paramdef> |
| <paramdef>int <parameter> *minor_version_return</parameter></paramdef> |
| </funcprototype> |
| </funcsynopsis> |
|
|
| <para> |
| <xref linkend='XSecurityQueryExtension' xrefstyle='select: title'/> sets major_version_return and |
| minor_version_return to the major and minor Security protocol version |
| supported by the server. If the Security library is compatible with the |
| version returned by the server, it returns nonzero. If dpy does not support |
| the Security extension, or if there was an error during communication with |
| the server, or if the server and library protocol versions are incompatible, |
| it returns zero. No other XSecurity functions may be called before this |
| function. If a client violates this rule, the effects of all subsequent |
| XSecurity calls that it makes are undefined. |
| </para> |
|
|
| <funcsynopsis id='XSecurityAllocXauth'> |
| <funcprototype> |
| <funcdef>Xauth *<function>XSecurityAllocXauth</function></funcdef> |
| <paramdef><parameter>void</parameter></paramdef> |
| </funcprototype> |
| </funcsynopsis> |
| <para> |
| In order to provide for future evolution, Xauth structures are used to |
| pass and return authorization data, and the library provides ways to |
| allocate and deallocate them. |
| </para> |
|
|
| <para> |
| <xref linkend='XSecurityAllocXauth' xrefstyle='select: title'/> must be used to allocate the |
| Xauth structure that is passed to |
| <xref linkend='XSecurityGenerateAuthorization' xrefstyle='select: title'/>. |
| </para> |
|
|
| <para> |
| For the purposes of the Security extension, the Xauth structure has |
| the following fields: |
| </para> |
|
|
| <informaltable frame='topbot'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='3' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.0*"/> |
| <colspec colname='c3' colwidth="3.0*"/> |
| <thead> |
| <row rowsep="1"> |
| <entry>Type</entry> |
| <entry>Field name</entry> |
| <entry>Description</entry> |
| </row> |
| </thead> |
| <tbody> |
| <row> |
| <entry> |
| <para>unsigned short</para> |
| </entry> |
| <entry> |
| <para>name_length</para> |
| </entry> |
| <entry> |
| <para>number of bytes in name</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>char *</para> |
| </entry> |
| <entry> |
| <para>name</para> |
| </entry> |
| <entry> |
| <para>authorization protocol name</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>unsigned short</para> |
| </entry> |
| <entry> |
| <para>data_length</para> |
| </entry> |
| <entry> |
| <para>number of bytes in data</para> |
| </entry> |
| </row> |
| <row rowsep="1"> |
| <entry> |
| <para>char *</para> |
| </entry> |
| <entry> |
| <para>data</para> |
| </entry> |
| <entry> |
| <para>authorization protocol data</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
| <para> |
| The Xauth structure returned by this function is initialized as follows: |
| name_length and data_length are zero, and name and data are NULL. |
| </para> |
|
|
| <funcsynopsis id='XSecurityFreeXauth'> |
| <funcprototype> |
| <funcdef>void <function>XSecurityFreeXauth</function></funcdef> |
| <paramdef>Xauth<parameter> *auth</parameter></paramdef> |
| </funcprototype> |
| </funcsynopsis> |
|
|
| <para> |
| <xref linkend='XSecurityFreeXauth' xrefstyle='select: title'/> must be used to free Xauth |
| structures allocated by |
| <xref linkend='XSecurityAllocXauth' xrefstyle='select: title'/> or returned by |
| <xref linkend='XSecurityGenerateAuthorization' xrefstyle='select: title'/>. It is the |
| caller's responsibility to fill in the name and data fields of Xauth structures |
| allocated with <xref linkend='XSecurityAllocXauth' xrefstyle='select: title'/>, so this function |
| will not attempt to free them. In contrast, all storage associated with |
| Xauth structures returned from |
| <xref linkend='XSecurityGenerateAuthorization' xrefstyle='select: title'/> will be freed by this |
| function, including the name and data fields. |
| </para> |
|
|
|
|
| <funcsynopsis id='XSecurityRevokeAuthorization'> |
| <funcprototype> |
| <funcdef>Bool <function>XSecurityRevokeAuthorization</function></funcdef> |
| <paramdef>Display<parameter> *dpy</parameter></paramdef> |
| <paramdef>XSecurityAuthorization<parameter> auth_id</parameter></paramdef> |
| </funcprototype> |
| </funcsynopsis> |
|
|
| <para> |
| <xref linkend='XSecurityRevokeAuthorization' xrefstyle='select: title'/> deletes the authorization |
| specified by auth_id, which must be a value returned in the auth_id_return |
| parameter of <xref linkend='XSecurityGenerateAuthorization' xrefstyle='select: title'/>. All |
| clients that connected with that authorization are be killed. Subsequently, |
| clients that attempt to connect using that authorization will be refused. |
| </para> |
|
|
|
|
| <funcsynopsis id='XSecurityGenerateAuthorization'> |
| <funcprototype> |
| <funcdef>Xauth *<function>XSecurityGenerateAuthorization</function></funcdef> |
| <paramdef>Display<parameter> *dpy</parameter></paramdef> |
| <paramdef>Xauth<parameter> *auth_in</parameter></paramdef> |
| <paramdef>unsigned long<parameter> valuemask</parameter></paramdef> |
| <paramdef>XSecurityAutorizationAttributes <parameter> *attributes</parameter></paramdef> |
| <paramdef>XSecurityAutorization<parameter> *auth_id_return</parameter></paramdef> |
| </funcprototype> |
| </funcsynopsis> |
|
|
| <para> |
| <xref linkend='XSecurityGenerateAuthorization' xrefstyle='select: title'/> creates a new |
| authorization with the specified attributes. The auth_in argument must be |
| allocated by <xref linkend='XSecurityAllocXauth' xrefstyle='select: title'/>. The |
| name and name_length fields of auth_in should be initialized to the |
| authorization protocol name and its length in characters respectively. |
| If there is authorization data, the data and data_length fields of |
| auth_in should be initialized to the data and its length in characters |
| respectively. The library does not assume that name and data are |
| null-terminated strings. The auth_in argument must be freed with |
| <xref linkend='XSecurityFreeXauth' xrefstyle='select: title'/>. |
| </para> |
|
|
| <para> |
| The XSecurityAuthorizationAttributes structure has the following fields: |
| </para> |
|
|
| <informaltable frame='topbot'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='3' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.0*"/> |
| <colspec colname='c3' colwidth="3.0*"/> |
| <thead> |
| <row rowsep="1"> |
| <entry>Type</entry> |
| <entry>Field name</entry> |
| <entry>Mask</entry> |
| </row> |
| </thead> |
| <tbody> |
| <row> |
| <entry> |
| <para>unsigned int</para> |
| </entry> |
| <entry> |
| <para>trust_level</para> |
| </entry> |
| <entry> |
| <para>XSecurityTrustLevel</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>unsigned int</para> |
| </entry> |
| <entry> |
| <para>timeout</para> |
| </entry> |
| <entry> |
| <para>XSecurityTimeout</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>XID</para> |
| </entry> |
| <entry> |
| <para>group</para> |
| </entry> |
| <entry> |
| <para>XSecurityGroup</para> |
| </entry> |
| </row> |
| <row rowsep="1"> |
| <entry> |
| <para>long</para> |
| </entry> |
| <entry> |
| <para>event_mask</para> |
| </entry> |
| <entry> |
| <para>XSecurityEventMask</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
|
|
| <para> |
| These correspond to the trust-level, timeout, group, and event-mask |
| described in the SecurityGenerateAuthorization protocol request. The |
| caller can fill in values for any subset of these attributes. The valuemask |
| argument must be the bitwise OR of the symbols listed in the Mask column |
| for all supplied attributes. The event_mask attribute can be None, |
| XSecurityAuthorizationRevokedMask, or XSecurityAllEventMasks. In this |
| revision of the protocol specification XSecurityAllEventMasks is equivalent |
| to XSecurityAuthorizationRevokedMask. If the caller does not need to |
| specify any attributes, the attributes argument can be NULL, and the |
| valuemask argument must be zero. |
| </para> |
| <para> |
| If the function fails, NULL is returned and auth_id_return is filled in |
| with zero. Otherwise, a pointer to an Xauth structure is returned. The name |
| and name_length fields of the returned Xauth structure will be copies of the |
| name that was passed in, and the data and data_length fields will be set to |
| the authorization data returned by the server. The caller should not assume |
| that name and data are null-terminated strings. If no authorization data was |
| returned by the server, the data and data_length fields will be set to NULL |
| and zero respectively. The returned Xauth structure must be freed with |
| <xref linkend='XSecurityFreeXauth' xrefstyle='select: title'/>; the caller should not use any other |
| means free the structure or any of its components. The auth_id_return |
| argument will be filled in with the non-zero authorization id of the created |
| authorization. |
| </para> |
|
|
| <para> |
| The XSecurityAuthorizationRevokedEvent structure has the following fields: |
| </para> |
|
|
| <informaltable frame='topbot'> |
| <?dbfo keep-together="always" ?> |
| <tgroup cols='3' align='left' colsep='0' rowsep='0'> |
| <colspec colname='c1' colwidth="1.0*"/> |
| <colspec colname='c2' colwidth="1.0*"/> |
| <colspec colname='c3' colwidth="3.0*"/> |
| <thead> |
| <row rowsep="1"> |
| <entry>Type</entry> |
| <entry>Field name</entry> |
| <entry>Description</entry> |
| </row> |
| </thead> |
| <tbody> |
| <row> |
| <entry> |
| <para>int</para> |
| </entry> |
| <entry> |
| <para>type</para> |
| </entry> |
| <entry> |
| <para>event base + XSecurityAuthorizationRevoked</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>unsigned long</para> |
| </entry> |
| <entry> |
| <para>serial</para> |
| </entry> |
| <entry> |
| <para># of last request processed by server</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>Bool</para> |
| </entry> |
| <entry> |
| <para>send_event</para> |
| </entry> |
| <entry> |
| <para>true if this came from SendEvent</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para>Display*</para> |
| </entry> |
| <entry> |
| <para>display</para> |
| </entry> |
| <entry> |
| <para>Display the event was read from</para> |
| </entry> |
| </row> |
| <row rowsep="1"> |
| <entry> |
| <para>XSecurityAuthorization</para> |
| </entry> |
| <entry> |
| <para>auth_id</para> |
| </entry> |
| <entry> |
| <para>revoked authorization id</para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
| </chapter> |
| </book> |
|
|