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