1972599cfSmrg<?xml version="1.0" encoding="UTF-8" ?>
2972599cfSmrg<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3972599cfSmrg                   "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
4972599cfSmrg[
5972599cfSmrg<!ENTITY % defs SYSTEM "defs.ent"> %defs;
6972599cfSmrg]>
7972599cfSmrg
8972599cfSmrg
9972599cfSmrg<!--translated from secint.tex, on 2010-06-27 15:38:00,
10972599cfSmrgby TeX4ht (http://www.cse.ohio-state.edu/~gurari/TeX4ht/)
11972599cfSmrgxhtml,docbook,html,refcaption -->
12972599cfSmrg
13972599cfSmrg<book id="secint">
14972599cfSmrg
15972599cfSmrg<bookinfo>
16972599cfSmrg   <title>Security Extension Server Design Draft</title>
17972599cfSmrg   <subtitle>X Consortium Standard</subtitle>
18972599cfSmrg   <authorgroup>
19972599cfSmrg      <author>
20972599cfSmrg         <firstname>David</firstname><othername>P.</othername><surname>Wiggins</surname>
21972599cfSmrg         <affiliation><orgname>X Consortium</orgname></affiliation>
22972599cfSmrg      </author>
23972599cfSmrg   </authorgroup>
24972599cfSmrg   <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
25972599cfSmrg   <releaseinfo>Version 3.0</releaseinfo>
26972599cfSmrg   <copyright><year>1996</year><holder>X Consortium</holder></copyright>
27972599cfSmrg
28972599cfSmrg<legalnotice>
29972599cfSmrg<para>
30972599cfSmrgPermission is hereby granted, free of charge, to any person obtaining
31972599cfSmrga copy of this software and associated documentation files (the
32972599cfSmrg"Software"), to deal in the Software without restriction, including
33972599cfSmrgwithout limitation the rights to use, copy, modify, merge, publish,
34972599cfSmrgdistribute, sublicense, and/or sell copies of the Software, and to
35972599cfSmrgpermit persons to whom the Software is furnished to do so, subject to
36972599cfSmrgthe following conditions:
37972599cfSmrg</para>
38972599cfSmrg<para>
39972599cfSmrgThe above copyright notice and this permission notice shall be included
40972599cfSmrgin all copies or substantial portions of the Software.
41972599cfSmrg</para>
42972599cfSmrg<para>
43972599cfSmrgTHE SOFTWARE IS PROVIDED &ldquo;AS IS&rdquo;, WITHOUT WARRANTY OF ANY KIND, EXPRESS
44972599cfSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
45972599cfSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
46972599cfSmrgIN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
47972599cfSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
48972599cfSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
49972599cfSmrgOTHER DEALINGS IN THE SOFTWARE.
50972599cfSmrg</para>
51972599cfSmrg<para>
52972599cfSmrgExcept as contained in this notice, the name of the X Consortium shall
53972599cfSmrgnot be used in advertising or otherwise to promote the sale, use or
54972599cfSmrgother dealings in this Software without prior written authorization
55972599cfSmrgfrom the X Consortium.
56972599cfSmrg</para>
57972599cfSmrg<para>X Window System is a trademark of The Open Group.</para>
58972599cfSmrg</legalnotice>
59972599cfSmrg<pubdate>June 27, 2010</pubdate>
60972599cfSmrg
61972599cfSmrg<abstract>
62972599cfSmrg<para>This paper describes the implementation strategy used to implement
63972599cfSmrg     various pieces of the SECURITY Extension.
64972599cfSmrg</para>
65972599cfSmrg</abstract>
66972599cfSmrg
67972599cfSmrg</bookinfo>
68972599cfSmrg
69972599cfSmrg
70972599cfSmrg<chapter id='Generate_Authorization_Request'>
71972599cfSmrg<title>Generate Authorization Request</title>
72972599cfSmrg
73972599cfSmrg<para>
74972599cfSmrgThe major steps taken to execute this request are as follows.
75972599cfSmrg</para>
76972599cfSmrg
77972599cfSmrg<para>
78972599cfSmrgSanity check arguments. The interesting one is the group, which must be
79972599cfSmrgchecked by some other module(s), initially just the embedding extension.
80972599cfSmrgUse a new callback for this. The callback functions will be passed a small
81972599cfSmrgstructure containing the group ID and a Boolean value which is initially
82972599cfSmrgfalse. If any of the callbacks recognize the ID, they should set the boolean
83972599cfSmrgto true. If after the callbacks have been called the boolean is false, return
84972599cfSmrgan error, since nobody recognized it.
85972599cfSmrg</para>
86972599cfSmrg
87972599cfSmrg<para>
88972599cfSmrgUse the existing Xkey library function XkeyGenerateAuthorization to generate
89972599cfSmrgthe new authorization.
90972599cfSmrg</para>
91972599cfSmrg
92972599cfSmrg<para>
93972599cfSmrgUse the existing os layer function AddAuthorization to add the new
94972599cfSmrgauthorization to the server's internal database.
95972599cfSmrg</para>
96972599cfSmrg
97972599cfSmrg<para>
98972599cfSmrgUse the existing os layer function AuthorizationToID to retrieve
99972599cfSmrgthe authorization ID that the os layer assigned to the new authorization.
100972599cfSmrg</para>
101972599cfSmrg
102972599cfSmrg<para>Change the os layer to use authorization IDs allocated from the
103972599cfSmrgserver's ID range via FakeClientID(0) instead of using a simple incrementing
104972599cfSmrginteger. This lets us use the resource database to attach additional
105972599cfSmrginformation to an authorization without needing any changes to os
106972599cfSmrgdata structures.
107972599cfSmrg</para>
108972599cfSmrg
109972599cfSmrg<para>
110972599cfSmrgAdd the authorization ID as a server resource. The structure for an
111972599cfSmrgauthorization resource will contain the timeout, trust-level, and group
112972599cfSmrgsent in the request, a reference count of how many clients are connected
113972599cfSmrgwith this authorization, a timer pointer, and time-remaining counter.
114972599cfSmrg</para>
115972599cfSmrg
116972599cfSmrg<para>
117972599cfSmrgReturn the authorization ID and generated auth data to the client.
118972599cfSmrg</para>
119972599cfSmrg
120972599cfSmrg</chapter>
121972599cfSmrg<chapter id='Client_Connection'>
122972599cfSmrg<title>Client Connection</title>
123972599cfSmrg
124972599cfSmrg<para>
125972599cfSmrgThe Security extension needs to be aware of new client connections
126972599cfSmrgprimarily so that it copy the trust-level of the authorization that was
127972599cfSmrgused to the client structure.  The trust-level is needed in the client
128972599cfSmrgstructure because it will be accessed frequently to make access control
129972599cfSmrgdecisions for the client. We will use the existing ClientStateCallback
130972599cfSmrgto catch new client connections.
131972599cfSmrg</para>
132972599cfSmrg
133972599cfSmrg<para>
134972599cfSmrgWe also need to copy the authorization ID into the client structure. The
135972599cfSmrgauthorization ID is already stored in an os private hung from the client,
136972599cfSmrgand we will add a new os function AuthorizationIDOfClient to retrieve it.
137972599cfSmrgHowever, when a client disconnects, this os private is already gone before
138972599cfSmrgClientStateCallbacks are called. We need the authorization ID at client
139972599cfSmrgdisconnect time for reasons described below.
140972599cfSmrg</para>
141972599cfSmrg
142972599cfSmrg<para>
143972599cfSmrgNow that we know what needs to be done and why, let's walk through the
1445eeb4e8fSmrgsequence of events.
145972599cfSmrg</para>
146972599cfSmrg
147972599cfSmrg<para>
148972599cfSmrgWhen a new client connects, get the authorization ID with
149972599cfSmrgAuthorizationIDOfClient, store it in the client, then pass that ID to
150972599cfSmrgLookupIDByType to find the authorization. If we get a non-NULL pointer
151972599cfSmrgback, this is a generated authorization, not one of the predefined ones in
152972599cfSmrgthe server's authority file. In this case, increment the authorization's
153972599cfSmrgreference count. If the reference count is now 1, cancel the timer
154972599cfSmrgfor this authorization using the trivial new os layer function TimerCancel.
155972599cfSmrgLastly, copy the trust-level of this authorization into the client structure
156972599cfSmrgso that it can be reached quickly for future access control decisions.
157972599cfSmrg</para>
158972599cfSmrg
159972599cfSmrg<para>
160972599cfSmrgThe embedding extension can determine the group to use for a new client in
161972599cfSmrgthe same way that we determined the trust level: get the authorization ID,
162972599cfSmrglook it up, and if that succeeds, pluck the group out of the returned
163972599cfSmrgauthorization structure.
164972599cfSmrg</para>
165972599cfSmrg</chapter>
166972599cfSmrg
167972599cfSmrg<chapter id='Client_disconnection'>
168972599cfSmrg<title>Client disconnection</title>
169972599cfSmrg
170972599cfSmrg<para>
171972599cfSmrgUse the existing ClientStateCallback to catch client disconnections. If the
172972599cfSmrgclient was using a generated authorization, decrement its reference count.
173972599cfSmrgIf the reference count is now zero, use the existing os layer function
174972599cfSmrgTimerSet to start a timer to count down the timeout period for this
175972599cfSmrgauthorization. Record the timer ID for this authorization. When the timer
176972599cfSmrgfires, the authorization should be freed, removing all
177972599cfSmrgtraces of it from the server.
178972599cfSmrg</para>
179972599cfSmrg
180972599cfSmrg<para>
181972599cfSmrgThere is a slight complication regarding the timeout because the timer
182972599cfSmrginterface in the server allows for 32 bits worth of milliseconds, while
183972599cfSmrgthe timeout specified in GenerateAuthorization has 32 bits worth of seconds.
184972599cfSmrgTo handle this, if the specified time is more than the timer interface can
185972599cfSmrghandle, the maximum possible timeout will be set, and time-remaining counter
186972599cfSmrgfor this authorization will be used to track the leftover part. When the
187972599cfSmrgtimer fires, it should first check to see if there is any leftover
188972599cfSmrgtime to wait. If there is, it should set another timer to the minimum of (the
189972599cfSmrgmaximum possible timeout) and the time remaining, and not do the revocation
190972599cfSmrgyet.
191972599cfSmrg</para>
192972599cfSmrg</chapter>
193972599cfSmrg
194972599cfSmrg<chapter id='Resource_ID_Security'>
195972599cfSmrg<title>Resource ID Security</title>
196972599cfSmrg
197972599cfSmrg<para>
198972599cfSmrgTo implement the restriction that untrusted clients cannot access resources
199972599cfSmrgof trusted clients, we add two new functions to dix: SecurityLookupIDByType
200972599cfSmrgand SecurityLookupIDByClass. Hereafter we will use SecurityLookupID to refer
201972599cfSmrgto both functions. In addition to the parameters of the existing LookupID
202972599cfSmrgfunctions, these functions also take a pointer to the client doing the lookup,
203972599cfSmrgand an access mode that conveys a high-level idea of what the client intends
204972599cfSmrgto do with the resource (currently just read, write, destroy, and unknown).
205972599cfSmrgPassing NullClient for the client turns off access checks. SecurityLookupID can
206972599cfSmrgreturn NULL for two reasons: the resource doesn't exist, or it does but the
207972599cfSmrgclient isn't allowed to access it. The caller cannot tell the difference. Most
208972599cfSmrgplaces in dix call these new lookup functions instead of the old LookupID,
209972599cfSmrgwhich continue to do no access checking. Extension "Proc" functions should
210972599cfSmrgprobably use SecurityLookupID, not LookupID. Ddxen can continue to use
211972599cfSmrgLookupID.
212972599cfSmrg</para>
213972599cfSmrg
214972599cfSmrg<para>
215972599cfSmrgInside SecurityLookupID, the function client -&gt; CheckAccess is called
216972599cfSmrgpassing the client, resource id, resource type/class, resource value, and
217972599cfSmrgaccess mode. CheckAccess returns the resource value if access is allowed,
218972599cfSmrgelse it returns NULL. The entire resource ID security policy of the Security
219972599cfSmrgextension can be replaced by plugging in your own access decision function
220972599cfSmrghere. This in combination with the access mode parameter should be enough to
221972599cfSmrgimplement a more traditional DAC (discretionary access control) policy.
222972599cfSmrg</para>
223972599cfSmrg
224972599cfSmrg<para>
225972599cfSmrgSince we need client and access mode information to do access controlled
226972599cfSmrgresource lookups, we add (and use) several other macros and functions that
227972599cfSmrgparallel existing ones with the addition of the missing information. The list
228972599cfSmrgincludes SECURITY_VERIFY_GC, SECURITY_VERIFY_DRAWABLE,
229972599cfSmrgSECURITY_VERIFY_GEOMETRABLE, SecurityLookupWindow,
230972599cfSmrgSecurityLookupDrawable, and dixChangeGC. The dixChangeGC interface is
231972599cfSmrgworth mentioning because in addition to a client parameter, we introduce a
232972599cfSmrgpointer-to-union parameter that should let us eliminate the warnings that some
233972599cfSmrgcompilers give when you assign small integers to pointers, as the DoChangeGC
234972599cfSmrginterface required. For more details, see the comment preceding dixChangeGC in
235972599cfSmrg;&lt;dix/gc.c;&gt;.
236972599cfSmrg</para>
237972599cfSmrg
238972599cfSmrg<para>
239972599cfSmrgIf XCSECURITY is not defined (the Security extension is not being built),
240972599cfSmrgthe server uses essentially the same code as before for resource lookups.
241972599cfSmrg</para>
242972599cfSmrg
243972599cfSmrg</chapter>
244972599cfSmrg<chapter id='Extension_Security'>
245972599cfSmrg<title>Extension Security</title>
246972599cfSmrg
247972599cfSmrg<para>
248972599cfSmrgA new field in the ExtensionEntry structure, Bool secure, tells whether the
249972599cfSmrgextension is considered secure. It is initialized to FALSE by AddExtension.
250972599cfSmrgThe following new dix function can be used to set the secure field:
251972599cfSmrg</para>
252972599cfSmrg
253972599cfSmrg<funcsynopsis id='DeclareExtensionSecurity'>
254972599cfSmrg<funcprototype>
255972599cfSmrg  <funcdef>void <function>DeclareExtensionSecurity</function></funcdef>
256972599cfSmrg    <paramdef>char <parameter> *extname</parameter></paramdef>
257972599cfSmrg    <paramdef>Bool <parameter>secure</parameter></paramdef>
258972599cfSmrg</funcprototype>
259972599cfSmrg</funcsynopsis>
260972599cfSmrg
261972599cfSmrg<para>
262972599cfSmrgThe name of the extension and the desired value of the secure field are
263972599cfSmrgpassed. If an extension is secure, a call to this function with
264972599cfSmrgsecure = TRUE will typically appear right after the call to
265972599cfSmrg<function>AddExtension</function>.
266972599cfSmrg<xref linkend='DeclareExtensionSecurity' xrefstyle='select: title'/>
267972599cfSmrgshould be called during server reset. It should not
268972599cfSmrgbe called after the first client has connected. Passing the name of an
269972599cfSmrgextension that has not been initialized has no effect (the secure value will
270972599cfSmrgnot be remembered in case the extension is later initialized).
271972599cfSmrg</para>
272972599cfSmrg
273972599cfSmrg<para>
274972599cfSmrgFor untrusted clients, <function>ProcListExtensions</function> omits
275972599cfSmrgextensions that have secure = FALSE, and
276972599cfSmrg<function>ProcQueryExtension</function> reports that such
277972599cfSmrgextensions don't exist.
278972599cfSmrg</para>
279972599cfSmrg
280972599cfSmrg<para>
281972599cfSmrgTo prevent untrusted clients from using extensions by guessing their major
2825eeb4e8fSmrgopcode, one of two new Proc vectors are used by untrusted clients,
283972599cfSmrg<function>UntrusedProcVector</function> and
284972599cfSmrg<function>SwappedUntrustedProcVector</function>. These have the same contents
285972599cfSmrgas <function>ProcVector</function> and
286972599cfSmrg<function>SwappedProcVector</function> respectively for the first 128
287972599cfSmrgentries. Entries 128 through 255 are initialized to ProcBadRequest. If
288972599cfSmrg<xref linkend='DeclareExtensionSecurity' xrefstyle='select: title'/> is called with secure =
289972599cfSmrgTRUE, that extension's dispatch function is plugged into the appropriate entry
290972599cfSmrgso that the extension can be used. If
291972599cfSmrg<xref linkend='DeclareExtensionSecurity' xrefstyle='select: title'/> is called with secure =
292972599cfSmrgFALSE, the appropriate entry is reset to ProcBadRequest.
293972599cfSmrg</para>
294972599cfSmrg
295972599cfSmrg<para>
296972599cfSmrgNow we can explain why <xref linkend='DeclareExtensionSecurity' xrefstyle='select: title'/>
297972599cfSmrgshould not be called after the first client connects. In some cases,
298972599cfSmrgthe Record extension gives clients a private copy of the proc vector,
299972599cfSmrgwhich it then changes to intercept certain requests. Changing entries in
300972599cfSmrg<function>UntrusedProcVector</function> and
301972599cfSmrg<function>SwappedUntrustedProcVector</function> will have no effect on these
302972599cfSmrgcopied proc vectors. If we get to the point of needing an extension request
303972599cfSmrgto control which extensions are secure, we'll need to invent a way to
304972599cfSmrgget those copied proc vectors changed.
305972599cfSmrg</para>
306972599cfSmrg</chapter>
307972599cfSmrg</book>
308972599cfSmrg
309972599cfSmrg
310