Imported Upstream version 1.15.1
[deb_xorg-server.git] / os / auth.c
CommitLineData
a09e091a
JB
1/*
2
3Copyright 1988, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * authorization hooks for the server
31 * Author: Keith Packard, MIT X Consortium
32 */
33
34#ifdef HAVE_DIX_CONFIG_H
35#include <dix-config.h>
36#endif
37
38#include <X11/X.h>
39#include <X11/Xauth.h>
40#include "misc.h"
41#include "osdep.h"
42#include "dixstruct.h"
43#include <sys/types.h>
44#include <sys/stat.h>
45#ifdef WIN32
46#include <X11/Xw32defs.h>
47#endif
48
49struct protocol {
50 unsigned short name_length;
51 const char *name;
52 AuthAddCFunc Add; /* new authorization data */
53 AuthCheckFunc Check; /* verify client authorization data */
54 AuthRstCFunc Reset; /* delete all authorization data entries */
55 AuthToIDFunc ToID; /* convert cookie to ID */
56 AuthFromIDFunc FromID; /* convert ID to cookie */
57 AuthRemCFunc Remove; /* remove a specific cookie */
58#ifdef XCSECURITY
59 AuthGenCFunc Generate;
60#endif
61};
62
63static struct protocol protocols[] = {
64 {(unsigned short) 18, "MIT-MAGIC-COOKIE-1",
65 MitAddCookie, MitCheckCookie, MitResetCookie,
66 MitToID, MitFromID, MitRemoveCookie,
67#ifdef XCSECURITY
68 MitGenerateCookie
69#endif
70 },
71#ifdef HASXDMAUTH
72 {(unsigned short) 19, "XDM-AUTHORIZATION-1",
73 XdmAddCookie, XdmCheckCookie, XdmResetCookie,
74 XdmToID, XdmFromID, XdmRemoveCookie,
75#ifdef XCSECURITY
76 NULL
77#endif
78 },
79#endif
80#ifdef SECURE_RPC
81 {(unsigned short) 9, "SUN-DES-1",
82 SecureRPCAdd, SecureRPCCheck, SecureRPCReset,
83 SecureRPCToID, SecureRPCFromID, SecureRPCRemove,
84#ifdef XCSECURITY
85 NULL
86#endif
87 },
88#endif
89};
90
91#define NUM_AUTHORIZATION (sizeof (protocols) /\
92 sizeof (struct protocol))
93
94/*
95 * Initialize all classes of authorization by reading the
96 * specified authorization file
97 */
98
99static char *authorization_file = (char *) NULL;
100
101static Bool ShouldLoadAuth = TRUE;
102
103void
104InitAuthorization(char *file_name)
105{
106 authorization_file = file_name;
107}
108
109static int
110LoadAuthorization(void)
111{
112 FILE *f;
113 Xauth *auth;
114 int i;
115 int count = 0;
116
117 ShouldLoadAuth = FALSE;
118 if (!authorization_file)
119 return 0;
120
121 f = Fopen(authorization_file, "r");
122 if (!f)
123 return -1;
124
125 while ((auth = XauReadAuth(f)) != 0) {
126 for (i = 0; i < NUM_AUTHORIZATION; i++) {
127 if (protocols[i].name_length == auth->name_length &&
128 memcmp(protocols[i].name, auth->name,
129 (int) auth->name_length) == 0 && protocols[i].Add) {
130 ++count;
131 (*protocols[i].Add) (auth->data_length, auth->data,
132 FakeClientID(0));
133 }
134 }
135 XauDisposeAuth(auth);
136 }
137
138 Fclose(f);
139 return count;
140}
141
142#ifdef XDMCP
143/*
144 * XdmcpInit calls this function to discover all authorization
145 * schemes supported by the display
146 */
147void
148RegisterAuthorizations(void)
149{
150 int i;
151
152 for (i = 0; i < NUM_AUTHORIZATION; i++)
153 XdmcpRegisterAuthorization(protocols[i].name,
154 (int) protocols[i].name_length);
155}
156#endif
157
158XID
159CheckAuthorization(unsigned int name_length,
160 const char *name,
161 unsigned int data_length,
162 const char *data, ClientPtr client, const char **reason)
163{ /* failure message. NULL for default msg */
164 int i;
165 struct stat buf;
166 static time_t lastmod = 0;
167 static Bool loaded = FALSE;
168
169 if (!authorization_file || stat(authorization_file, &buf)) {
170 if (lastmod != 0) {
171 lastmod = 0;
172 ShouldLoadAuth = TRUE; /* stat lost, so force reload */
173 }
174 }
175 else if (buf.st_mtime > lastmod) {
176 lastmod = buf.st_mtime;
177 ShouldLoadAuth = TRUE;
178 }
179 if (ShouldLoadAuth) {
180 int loadauth = LoadAuthorization();
181
182 /*
183 * If the authorization file has at least one entry for this server,
184 * disable local host access. (loadauth > 0)
185 *
186 * If there are zero entries (either initially or when the
187 * authorization file is later reloaded), or if a valid
188 * authorization file was never loaded, enable local host access.
189 * (loadauth == 0 || !loaded)
190 *
191 * If the authorization file was loaded initially (with valid
192 * entries for this server), and reloading it later fails, don't
193 * change anything. (loadauth == -1 && loaded)
194 */
195
196 if (loadauth > 0) {
197 DisableLocalHost(); /* got at least one */
198 loaded = TRUE;
199 }
200 else if (loadauth == 0 || !loaded)
201 EnableLocalHost();
202 }
203 if (name_length) {
204 for (i = 0; i < NUM_AUTHORIZATION; i++) {
205 if (protocols[i].name_length == name_length &&
206 memcmp(protocols[i].name, name, (int) name_length) == 0) {
207 return (*protocols[i].Check) (data_length, data, client,
208 reason);
209 }
210 *reason = "Protocol not supported by server\n";
211 }
212 }
213 else
214 *reason = "No protocol specified\n";
215 return (XID) ~0L;
216}
217
218void
219ResetAuthorization(void)
220{
221 int i;
222
223 for (i = 0; i < NUM_AUTHORIZATION; i++)
224 if (protocols[i].Reset)
225 (*protocols[i].Reset) ();
226 ShouldLoadAuth = TRUE;
227}
228
229int
230AuthorizationFromID(XID id,
231 unsigned short *name_lenp,
232 const char **namep, unsigned short *data_lenp, char **datap)
233{
234 int i;
235
236 for (i = 0; i < NUM_AUTHORIZATION; i++) {
237 if (protocols[i].FromID &&
238 (*protocols[i].FromID) (id, data_lenp, datap)) {
239 *name_lenp = protocols[i].name_length;
240 *namep = protocols[i].name;
241 return 1;
242 }
243 }
244 return 0;
245}
246
247int
248RemoveAuthorization(unsigned short name_length,
249 const char *name,
250 unsigned short data_length, const char *data)
251{
252 int i;
253
254 for (i = 0; i < NUM_AUTHORIZATION; i++) {
255 if (protocols[i].name_length == name_length &&
256 memcmp(protocols[i].name, name, (int) name_length) == 0 &&
257 protocols[i].Remove) {
258 return (*protocols[i].Remove) (data_length, data);
259 }
260 }
261 return 0;
262}
263
264int
265AddAuthorization(unsigned name_length, const char *name,
266 unsigned data_length, char *data)
267{
268 int i;
269
270 for (i = 0; i < NUM_AUTHORIZATION; i++) {
271 if (protocols[i].name_length == name_length &&
272 memcmp(protocols[i].name, name, (int) name_length) == 0 &&
273 protocols[i].Add) {
274 return (*protocols[i].Add) (data_length, data, FakeClientID(0));
275 }
276 }
277 return 0;
278}
279
280#ifdef XCSECURITY
281
282XID
283GenerateAuthorization(unsigned name_length,
284 const char *name,
285 unsigned data_length,
286 const char *data,
287 unsigned *data_length_return, char **data_return)
288{
289 int i;
290
291 for (i = 0; i < NUM_AUTHORIZATION; i++) {
292 if (protocols[i].name_length == name_length &&
293 memcmp(protocols[i].name, name, (int) name_length) == 0 &&
294 protocols[i].Generate) {
295 return (*protocols[i].Generate) (data_length, data,
296 FakeClientID(0),
297 data_length_return, data_return);
298 }
299 }
300 return -1;
301}
302
303void
304GenerateRandomData(int len, char *buf)
305{
306 int fd;
307
308 fd = open("/dev/urandom", O_RDONLY);
309 read(fd, buf, len);
310 close(fd);
311}
312
313#endif /* XCSECURITY */