auth.c revision 706f2543
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 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, (int) auth->name_length) == 0 && 129 protocols[i].Add) 130 { 131 ++count; 132 (*protocols[i].Add) (auth->data_length, auth->data, 133 FakeClientID(0)); 134 } 135 } 136 XauDisposeAuth (auth); 137 } 138 139 Fclose (f); 140 return count; 141} 142 143#ifdef XDMCP 144/* 145 * XdmcpInit calls this function to discover all authorization 146 * schemes supported by the display 147 */ 148void 149RegisterAuthorizations (void) 150{ 151 int i; 152 153 for (i = 0; i < NUM_AUTHORIZATION; i++) 154 XdmcpRegisterAuthorization (protocols[i].name, 155 (int)protocols[i].name_length); 156} 157#endif 158 159XID 160CheckAuthorization ( 161 unsigned int name_length, 162 const char *name, 163 unsigned int data_length, 164 const char *data, 165 ClientPtr client, 166 char **reason) /* failure message. NULL for default msg */ 167{ 168 int i; 169 struct stat buf; 170 static time_t lastmod = 0; 171 static Bool loaded = FALSE; 172 173 if (!authorization_file || stat(authorization_file, &buf)) 174 { 175 if (lastmod != 0) { 176 lastmod = 0; 177 ShouldLoadAuth = TRUE; /* stat lost, so force reload */ 178 } 179 } 180 else if (buf.st_mtime > lastmod) 181 { 182 lastmod = buf.st_mtime; 183 ShouldLoadAuth = TRUE; 184 } 185 if (ShouldLoadAuth) 186 { 187 int loadauth = LoadAuthorization(); 188 189 /* 190 * If the authorization file has at least one entry for this server, 191 * disable local host access. (loadauth > 0) 192 * 193 * If there are zero entries (either initially or when the 194 * authorization file is later reloaded), or if a valid 195 * authorization file was never loaded, enable local host access. 196 * (loadauth == 0 || !loaded) 197 * 198 * If the authorization file was loaded initially (with valid 199 * entries for this server), and reloading it later fails, don't 200 * change anything. (loadauth == -1 && loaded) 201 */ 202 203 if (loadauth > 0) 204 { 205 DisableLocalHost(); /* got at least one */ 206 loaded = TRUE; 207 } 208 else if (loadauth == 0 || !loaded) 209 EnableLocalHost (); 210 } 211 if (name_length) { 212 for (i = 0; i < NUM_AUTHORIZATION; i++) { 213 if (protocols[i].name_length == name_length && 214 memcmp (protocols[i].name, name, (int) name_length) == 0) 215 { 216 return (*protocols[i].Check) (data_length, data, client, reason); 217 } 218 *reason = "Protocol not supported by server\n"; 219 } 220 } else *reason = "No protocol specified\n"; 221 return (XID) ~0L; 222} 223 224void 225ResetAuthorization (void) 226{ 227 int i; 228 229 for (i = 0; i < NUM_AUTHORIZATION; i++) 230 if (protocols[i].Reset) 231 (*protocols[i].Reset)(); 232 ShouldLoadAuth = TRUE; 233} 234 235int 236AuthorizationFromID ( 237 XID id, 238 unsigned short *name_lenp, 239 char **namep, 240 unsigned short *data_lenp, 241 char **datap) 242{ 243 int i; 244 245 for (i = 0; i < NUM_AUTHORIZATION; i++) { 246 if (protocols[i].FromID && 247 (*protocols[i].FromID) (id, data_lenp, datap)) { 248 *name_lenp = protocols[i].name_length; 249 *namep = protocols[i].name; 250 return 1; 251 } 252 } 253 return 0; 254} 255 256int 257RemoveAuthorization ( 258 unsigned short name_length, 259 const char *name, 260 unsigned short data_length, 261 const char *data) 262{ 263 int i; 264 265 for (i = 0; i < NUM_AUTHORIZATION; i++) { 266 if (protocols[i].name_length == name_length && 267 memcmp (protocols[i].name, name, (int) name_length) == 0 && 268 protocols[i].Remove) 269 { 270 return (*protocols[i].Remove) (data_length, data); 271 } 272 } 273 return 0; 274} 275 276int 277AddAuthorization (unsigned name_length, const char *name, 278 unsigned data_length, char *data) 279{ 280 int i; 281 282 for (i = 0; i < NUM_AUTHORIZATION; i++) { 283 if (protocols[i].name_length == name_length && 284 memcmp (protocols[i].name, name, (int) name_length) == 0 && 285 protocols[i].Add) 286 { 287 return (*protocols[i].Add) (data_length, data, FakeClientID(0)); 288 } 289 } 290 return 0; 291} 292 293#ifdef XCSECURITY 294 295XID 296GenerateAuthorization( 297 unsigned name_length, 298 const char *name, 299 unsigned data_length, 300 const char *data, 301 unsigned *data_length_return, 302 char **data_return) 303{ 304 int i; 305 306 for (i = 0; i < NUM_AUTHORIZATION; i++) { 307 if (protocols[i].name_length == name_length && 308 memcmp (protocols[i].name, name, (int) name_length) == 0 && 309 protocols[i].Generate) 310 { 311 return (*protocols[i].Generate) (data_length, data, 312 FakeClientID(0), data_length_return, data_return); 313 } 314 } 315 return -1; 316} 317 318void 319GenerateRandomData (int len, char *buf) 320{ 321 int fd; 322 323 fd = open("/dev/urandom", O_RDONLY); 324 read(fd, buf, len); 325 close(fd); 326} 327 328#endif /* XCSECURITY */ 329