3 Copyright 1988, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
30 * authorization hooks for the server
31 * Author: Keith Packard, MIT X Consortium
34 #include <dix-config.h>
37 #include <X11/Xauth.h>
40 #include "dixstruct.h"
41 #include <sys/types.h>
45 #include <X11/Xw32defs.h>
47 #include <stdlib.h> /* for arc4random_buf() */
56 unsigned short name_length
;
58 AuthAddCFunc Add
; /* new authorization data */
59 AuthCheckFunc Check
; /* verify client authorization data */
60 AuthRstCFunc Reset
; /* delete all authorization data entries */
61 AuthFromIDFunc FromID
; /* convert ID to cookie */
62 AuthRemCFunc Remove
; /* remove a specific cookie */
64 AuthGenCFunc Generate
;
68 static struct protocol protocols
[] = {
69 {(unsigned short) 18, "MIT-MAGIC-COOKIE-1",
70 MitAddCookie
, MitCheckCookie
, MitResetCookie
,
71 MitFromID
, MitRemoveCookie
,
77 {(unsigned short) 19, "XDM-AUTHORIZATION-1",
78 XdmAddCookie
, XdmCheckCookie
, XdmResetCookie
,
79 XdmFromID
, XdmRemoveCookie
,
87 #define NUM_AUTHORIZATION ARRAY_SIZE(protocols)
90 * Initialize all classes of authorization by reading the
91 * specified authorization file
94 static const char *authorization_file
= NULL
;
96 static Bool ShouldLoadAuth
= TRUE
;
99 InitAuthorization(const char *file_name
)
101 authorization_file
= file_name
;
105 LoadAuthorization(void)
112 ShouldLoadAuth
= FALSE
;
113 if (!authorization_file
)
117 f
= Fopen(authorization_file
, "r");
119 LogMessageVerb(X_ERROR
, 0,
120 "Failed to open authorization file \"%s\": %s\n",
122 errno
!= 0 ? strerror(errno
) : "Unknown error");
126 while ((auth
= XauReadAuth(f
)) != 0) {
127 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++) {
128 if (protocols
[i
].name_length
== auth
->name_length
&&
129 memcmp(protocols
[i
].name
, auth
->name
,
130 (int) auth
->name_length
) == 0 && protocols
[i
].Add
) {
132 (*protocols
[i
].Add
) (auth
->data_length
, auth
->data
,
136 XauDisposeAuth(auth
);
145 * XdmcpInit calls this function to discover all authorization
146 * schemes supported by the display
149 RegisterAuthorizations(void)
153 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++)
154 XdmcpRegisterAuthorization(protocols
[i
].name
,
155 (int) protocols
[i
].name_length
);
160 CheckAuthorization(unsigned int name_length
,
162 unsigned int data_length
,
163 const char *data
, ClientPtr client
, const char **reason
)
164 { /* failure message. NULL for default msg */
167 static time_t lastmod
= 0;
168 static Bool loaded
= FALSE
;
170 if (!authorization_file
|| stat(authorization_file
, &buf
)) {
173 ShouldLoadAuth
= TRUE
; /* stat lost, so force reload */
176 else if (buf
.st_mtime
> lastmod
) {
177 lastmod
= buf
.st_mtime
;
178 ShouldLoadAuth
= TRUE
;
180 if (ShouldLoadAuth
) {
181 int loadauth
= LoadAuthorization();
184 * If the authorization file has at least one entry for this server,
185 * disable local access. (loadauth > 0)
187 * If there are zero entries (either initially or when the
188 * authorization file is later reloaded), or if a valid
189 * authorization file was never loaded, enable local access.
190 * (loadauth == 0 || !loaded)
192 * If the authorization file was loaded initially (with valid
193 * entries for this server), and reloading it later fails, don't
194 * change anything. (loadauth == -1 && loaded)
198 DisableLocalAccess(); /* got at least one */
201 else if (loadauth
== 0 || !loaded
)
205 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++) {
206 if (protocols
[i
].name_length
== name_length
&&
207 memcmp(protocols
[i
].name
, name
, (int) name_length
) == 0) {
208 return (*protocols
[i
].Check
) (data_length
, data
, client
,
211 *reason
= "Authorization protocol not supported by server\n";
215 *reason
= "Authorization required, but no authorization protocol specified\n";
220 ResetAuthorization(void)
224 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++)
225 if (protocols
[i
].Reset
)
226 (*protocols
[i
].Reset
) ();
227 ShouldLoadAuth
= TRUE
;
231 AuthorizationFromID(XID id
,
232 unsigned short *name_lenp
,
233 const char **namep
, unsigned short *data_lenp
, char **datap
)
237 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++) {
238 if (protocols
[i
].FromID
&&
239 (*protocols
[i
].FromID
) (id
, data_lenp
, datap
)) {
240 *name_lenp
= protocols
[i
].name_length
;
241 *namep
= protocols
[i
].name
;
249 RemoveAuthorization(unsigned short name_length
,
251 unsigned short data_length
, const char *data
)
255 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++) {
256 if (protocols
[i
].name_length
== name_length
&&
257 memcmp(protocols
[i
].name
, name
, (int) name_length
) == 0 &&
258 protocols
[i
].Remove
) {
259 return (*protocols
[i
].Remove
) (data_length
, data
);
266 AddAuthorization(unsigned name_length
, const char *name
,
267 unsigned data_length
, char *data
)
271 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++) {
272 if (protocols
[i
].name_length
== name_length
&&
273 memcmp(protocols
[i
].name
, name
, (int) name_length
) == 0 &&
275 return (*protocols
[i
].Add
) (data_length
, data
, FakeClientID(0));
284 GenerateAuthorization(unsigned name_length
,
286 unsigned data_length
,
288 unsigned *data_length_return
, char **data_return
)
292 for (i
= 0; i
< NUM_AUTHORIZATION
; i
++) {
293 if (protocols
[i
].name_length
== name_length
&&
294 memcmp(protocols
[i
].name
, name
, (int) name_length
) == 0 &&
295 protocols
[i
].Generate
) {
296 return (*protocols
[i
].Generate
) (data_length
, data
,
298 data_length_return
, data_return
);
304 #endif /* XCSECURITY */
307 GenerateRandomData(int len
, char *buf
)
309 #ifdef HAVE_ARC4RANDOM_BUF
310 arc4random_buf(buf
, len
);
314 fd
= open("/dev/urandom", O_RDONLY
);