auth.c revision 4059972a
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    char    *name;
52    AuthAddCFunc	Add;	/* new authorization data */
53    AuthCheckFunc	Check;	/* verify client authorization data */
54    AuthRstCFunc	Reset;	/* delete all authorization data entries */
55    AuthFromIDFunc	FromID;	/* convert ID to cookie */
56    AuthRemCFunc	Remove;	/* remove a specific cookie */
57#ifdef XCSECURITY
58    AuthGenCFunc	Generate;
59#endif
60};
61
62static struct protocol   protocols[] = {
63{   (unsigned short) 18,    "MIT-MAGIC-COOKIE-1",
64		MitAddCookie,	MitCheckCookie,	MitResetCookie,
65		MitFromID,	MitRemoveCookie,
66#ifdef XCSECURITY
67		MitGenerateCookie
68#endif
69},
70#ifdef HASXDMAUTH
71{   (unsigned short) 19,    "XDM-AUTHORIZATION-1",
72		XdmAddCookie,	XdmCheckCookie,	XdmResetCookie,
73		XdmFromID,	XdmRemoveCookie,
74#ifdef XCSECURITY
75		NULL
76#endif
77},
78#endif
79#ifdef SECURE_RPC
80{   (unsigned short) 9,    "SUN-DES-1",
81		SecureRPCAdd,	SecureRPCCheck,	SecureRPCReset,
82		SecureRPCFromID,SecureRPCRemove,
83#ifdef XCSECURITY
84		NULL
85#endif
86},
87#endif
88};
89
90# define NUM_AUTHORIZATION  (sizeof (protocols) /\
91			     sizeof (struct protocol))
92
93/*
94 * Initialize all classes of authorization by reading the
95 * specified authorization file
96 */
97
98static char *authorization_file = (char *)NULL;
99
100static Bool ShouldLoadAuth = TRUE;
101
102void
103InitAuthorization (char *file_name)
104{
105    authorization_file = file_name;
106}
107
108static int
109LoadAuthorization (void)
110{
111    FILE    *f;
112    Xauth   *auth;
113    int	    i;
114    int	    count = 0;
115
116    ShouldLoadAuth = FALSE;
117    if (!authorization_file)
118	return 0;
119
120    f = Fopen (authorization_file, "r");
121    if (!f)
122	return -1;
123
124    while ((auth = XauReadAuth (f)) != 0) {
125	for (i = 0; i < NUM_AUTHORIZATION; i++) {
126	    if (protocols[i].name_length == auth->name_length &&
127		memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 &&
128		protocols[i].Add)
129	    {
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 (
160    unsigned int name_length,
161    const char	*name,
162    unsigned int data_length,
163    const char	*data,
164    ClientPtr client,
165    char	**reason)	/* failure message.  NULL for default msg */
166{
167    int	i;
168    struct stat buf;
169    static time_t lastmod = 0;
170    static Bool loaded = FALSE;
171
172    if (!authorization_file || stat(authorization_file, &buf))
173    {
174	if (lastmod != 0) {
175	    lastmod = 0;
176	    ShouldLoadAuth = TRUE;	/* stat lost, so force reload */
177	}
178    }
179    else if (buf.st_mtime > lastmod)
180    {
181	lastmod = buf.st_mtime;
182	ShouldLoadAuth = TRUE;
183    }
184    if (ShouldLoadAuth)
185    {
186	int loadauth = LoadAuthorization();
187
188	/*
189	 * If the authorization file has at least one entry for this server,
190	 * disable local host access. (loadauth > 0)
191	 *
192	 * If there are zero entries (either initially or when the
193	 * authorization file is later reloaded), or if a valid
194	 * authorization file was never loaded, enable local host access.
195	 * (loadauth == 0 || !loaded)
196	 *
197	 * If the authorization file was loaded initially (with valid
198	 * entries for this server), and reloading it later fails, don't
199	 * change anything. (loadauth == -1 && loaded)
200	 */
201
202	if (loadauth > 0)
203	{
204	    DisableLocalHost(); /* got at least one */
205	    loaded = TRUE;
206	}
207	else if (loadauth == 0 || !loaded)
208	    EnableLocalHost ();
209    }
210    if (name_length) {
211	for (i = 0; i < NUM_AUTHORIZATION; i++) {
212	    if (protocols[i].name_length == name_length &&
213		memcmp (protocols[i].name, name, (int) name_length) == 0)
214	    {
215		return (*protocols[i].Check) (data_length, data, client, reason);
216	    }
217	    *reason = "Protocol not supported by server\n";
218	}
219    } else *reason = "No protocol specified\n";
220    return (XID) ~0L;
221}
222
223void
224ResetAuthorization (void)
225{
226    int	i;
227
228    for (i = 0; i < NUM_AUTHORIZATION; i++)
229	if (protocols[i].Reset)
230	    (*protocols[i].Reset)();
231    ShouldLoadAuth = TRUE;
232}
233
234int
235AuthorizationFromID (
236	XID 		id,
237	unsigned short	*name_lenp,
238	char		**namep,
239	unsigned short	*data_lenp,
240	char		**datap)
241{
242    int	i;
243
244    for (i = 0; i < NUM_AUTHORIZATION; i++) {
245	if (protocols[i].FromID &&
246	    (*protocols[i].FromID) (id, data_lenp, datap)) {
247	    *name_lenp = protocols[i].name_length;
248	    *namep = protocols[i].name;
249	    return 1;
250	}
251    }
252    return 0;
253}
254
255int
256RemoveAuthorization (
257	unsigned short	name_length,
258	const char	*name,
259	unsigned short	data_length,
260	const char	*data)
261{
262    int	i;
263
264    for (i = 0; i < NUM_AUTHORIZATION; i++) {
265    	if (protocols[i].name_length == name_length &&
266	    memcmp (protocols[i].name, name, (int) name_length) == 0 &&
267	    protocols[i].Remove)
268    	{
269	    return (*protocols[i].Remove) (data_length, data);
270    	}
271    }
272    return 0;
273}
274
275int
276AddAuthorization (unsigned name_length, const char *name,
277		  unsigned data_length, char *data)
278{
279    int	i;
280
281    for (i = 0; i < NUM_AUTHORIZATION; i++) {
282    	if (protocols[i].name_length == name_length &&
283	    memcmp (protocols[i].name, name, (int) name_length) == 0 &&
284	    protocols[i].Add)
285    	{
286	    return (*protocols[i].Add) (data_length, data, FakeClientID(0));
287    	}
288    }
289    return 0;
290}
291
292#ifdef XCSECURITY
293
294XID
295GenerateAuthorization(
296	unsigned name_length,
297	const char	*name,
298	unsigned data_length,
299	const char	*data,
300	unsigned *data_length_return,
301	char	**data_return)
302{
303    int	i;
304
305    for (i = 0; i < NUM_AUTHORIZATION; i++) {
306    	if (protocols[i].name_length == name_length &&
307	    memcmp (protocols[i].name, name, (int) name_length) == 0 &&
308	    protocols[i].Generate)
309    	{
310	    return (*protocols[i].Generate) (data_length, data,
311			FakeClientID(0), data_length_return, data_return);
312    	}
313    }
314    return -1;
315}
316
317void
318GenerateRandomData (int len, char *buf)
319{
320    int fd;
321
322    fd = open("/dev/urandom", O_RDONLY);
323    read(fd, buf, len);
324    close(fd);
325}
326
327#endif /* XCSECURITY */
328