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 “AS IS”, 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 -> 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;<dix/gc.c;>. 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