authutil.c revision 266e564d
1/* $Xorg: authutil.c,v 1.5 2001/02/09 02:03:26 xorgcvs Exp $ */ 2/* $XdotOrg: xc/lib/ICE/authutil.c,v 1.3 2005/05/17 20:53:55 sandmann Exp $ */ 3/****************************************************************************** 4 5 6Copyright 1993, 1998 The Open Group 7 8Permission to use, copy, modify, distribute, and sell this software and its 9documentation for any purpose is hereby granted without fee, provided that 10the above copyright notice appear in all copies and that both that 11copyright notice and this permission notice appear in supporting 12documentation. 13 14The above copyright notice and this permission notice shall be included in 15all copies or substantial portions of the Software. 16 17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24Except as contained in this notice, the name of The Open Group shall not be 25used in advertising or otherwise to promote the sale, use or other dealings 26in this Software without prior written authorization from The Open Group. 27 28Author: Ralph Mor, X Consortium 29******************************************************************************/ 30/* $XFree86: authutil.c,v 3.9 2002/05/31 18:45:41 dawes Exp $ */ 31 32#ifdef HAVE_CONFIG_H 33#include <config.h> 34#endif 35#include <X11/ICE/ICElib.h> 36#include "ICElibint.h" 37#include <X11/ICE/ICEutil.h> 38#include <X11/Xos.h> 39#include <sys/stat.h> 40#include <errno.h> 41 42#include <time.h> 43#define Time_t time_t 44#ifdef __UNIXOS2__ 45extern char* getenv(const char*); 46#define link rename 47#endif 48#ifndef X_NOT_POSIX 49#include <unistd.h> 50#else 51#ifndef WIN32 52extern unsigned sleep (); 53#else 54#define link rename 55#endif 56#endif 57 58static Status read_short (FILE *file, unsigned short *shortp); 59static Status read_string (FILE *file, char **stringp); 60static Status read_counted_string (FILE *file, unsigned short *countp, char **stringp); 61static Status write_short (FILE *file, unsigned short s); 62static Status write_string (FILE *file, char *string); 63static Status write_counted_string (FILE *file, unsigned short count, char *string); 64 65 66 67/* 68 * The following routines are for manipulating the .ICEauthority file 69 * These are utility functions - they are not part of the standard 70 * ICE library specification. 71 */ 72 73char * 74IceAuthFileName (void) 75 76{ 77 static char slashDotICEauthority[] = "/.ICEauthority"; 78 char *name; 79 static char *buf; 80 static int bsize; 81 int size; 82#if defined(WIN32) || defined(__UNIXOS2__) 83#ifndef PATH_MAX 84#define PATH_MAX 512 85#endif 86 char dir[PATH_MAX]; 87#endif 88 89 if ((name = getenv ("ICEAUTHORITY"))) 90 return (name); 91 92 name = getenv ("HOME"); 93 94 if (!name) 95 { 96#ifdef WIN32 97 register char *ptr1; 98 register char *ptr2; 99 int len1 = 0, len2 = 0; 100 101 if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) { 102 len1 = strlen (ptr1); 103 len2 = strlen (ptr2); 104 } else if (ptr2 = getenv("USERNAME")) { 105 len1 = strlen (ptr1 = "/users/"); 106 len2 = strlen (ptr2); 107 } 108 if ((len1 + len2 + 1) < PATH_MAX) { 109 sprintf (dir, "%s%s", ptr1, (ptr2) ? ptr2 : ""); 110 name = dir; 111 } 112 if (!name) 113#endif 114#ifdef __UNIXOS2__ 115 strcpy (dir,"c:"); 116 name = dir; 117 if (!name) 118#endif 119 return (NULL); 120 } 121 122 size = strlen (name) + strlen (&slashDotICEauthority[1]) + 2; 123 124 if (size > bsize) 125 { 126 if (buf) 127 free (buf); 128 buf = malloc ((unsigned) size); 129 if (!buf) 130 return (NULL); 131 bsize = size; 132 } 133 134 strcpy (buf, name); 135 strcat (buf, slashDotICEauthority + (name[1] == '\0' ? 1 : 0)); 136 137 return (buf); 138} 139 140 141 142int 143IceLockAuthFile (file_name, retries, timeout, dead) 144 145char *file_name; 146int retries; 147int timeout; 148long dead; 149 150{ 151 char creat_name[1025], link_name[1025]; 152 struct stat statb; 153 Time_t now; 154 int creat_fd = -1; 155 156 if ((int) strlen (file_name) > 1022) 157 return (IceAuthLockError); 158 159 strcpy (creat_name, file_name); 160 strcat (creat_name, "-c"); 161 strcpy (link_name, file_name); 162 strcat (link_name, "-l"); 163 164 if (stat (creat_name, &statb) != -1) 165 { 166 now = time ((Time_t *) 0); 167 168 /* 169 * NFS may cause ctime to be before now, special 170 * case a 0 deadtime to force lock removal 171 */ 172 173 if (dead == 0 || now - statb.st_ctime > dead) 174 { 175 unlink (creat_name); 176 unlink (link_name); 177 } 178 } 179 180 while (retries > 0) 181 { 182 if (creat_fd == -1) 183 { 184 creat_fd = creat (creat_name, 0666); 185 186 if (creat_fd == -1) 187 { 188 if (errno != EACCES) 189 return (IceAuthLockError); 190 } 191 else 192 close (creat_fd); 193 } 194 195 if (creat_fd != -1) 196 { 197 if (link (creat_name, link_name) != -1) 198 return (IceAuthLockSuccess); 199 200 if (errno == ENOENT) 201 { 202 creat_fd = -1; /* force re-creat next time around */ 203 continue; 204 } 205 206 if (errno != EEXIST) 207 return (IceAuthLockError); 208 } 209 210 sleep ((unsigned) timeout); 211 --retries; 212 } 213 214 return (IceAuthLockTimeout); 215} 216 217 218 219void 220IceUnlockAuthFile (file_name) 221 222char *file_name; 223 224{ 225#ifndef WIN32 226 char creat_name[1025]; 227#endif 228 char link_name[1025]; 229 230 if ((int) strlen (file_name) > 1022) 231 return; 232 233#ifndef WIN32 234 strcpy (creat_name, file_name); 235 strcat (creat_name, "-c"); 236#endif 237 strcpy (link_name, file_name); 238 strcat (link_name, "-l"); 239 240#ifndef WIN32 241 unlink (creat_name); 242#endif 243 unlink (link_name); 244} 245 246 247 248IceAuthFileEntry * 249IceReadAuthFileEntry (auth_file) 250 251FILE *auth_file; 252 253{ 254 IceAuthFileEntry local; 255 IceAuthFileEntry *ret; 256 257 local.protocol_name = NULL; 258 local.protocol_data = NULL; 259 local.network_id = NULL; 260 local.auth_name = NULL; 261 local.auth_data = NULL; 262 263 if (!read_string (auth_file, &local.protocol_name)) 264 return (NULL); 265 266 if (!read_counted_string (auth_file, 267 &local.protocol_data_length, &local.protocol_data)) 268 goto bad; 269 270 if (!read_string (auth_file, &local.network_id)) 271 goto bad; 272 273 if (!read_string (auth_file, &local.auth_name)) 274 goto bad; 275 276 if (!read_counted_string (auth_file, 277 &local.auth_data_length, &local.auth_data)) 278 goto bad; 279 280 if (!(ret = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry)))) 281 goto bad; 282 283 *ret = local; 284 285 return (ret); 286 287 bad: 288 289 if (local.protocol_name) free (local.protocol_name); 290 if (local.protocol_data) free (local.protocol_data); 291 if (local.network_id) free (local.network_id); 292 if (local.auth_name) free (local.auth_name); 293 if (local.auth_data) free (local.auth_data); 294 295 return (NULL); 296} 297 298 299 300void 301IceFreeAuthFileEntry (auth) 302 303IceAuthFileEntry *auth; 304 305{ 306 if (auth) 307 { 308 if (auth->protocol_name) free (auth->protocol_name); 309 if (auth->protocol_data) free (auth->protocol_data); 310 if (auth->network_id) free (auth->network_id); 311 if (auth->auth_name) free (auth->auth_name); 312 if (auth->auth_data) free (auth->auth_data); 313 free ((char *) auth); 314 } 315} 316 317 318 319Status 320IceWriteAuthFileEntry (auth_file, auth) 321 322FILE *auth_file; 323IceAuthFileEntry *auth; 324 325{ 326 if (!write_string (auth_file, auth->protocol_name)) 327 return (0); 328 329 if (!write_counted_string (auth_file, 330 auth->protocol_data_length, auth->protocol_data)) 331 return (0); 332 333 if (!write_string (auth_file, auth->network_id)) 334 return (0); 335 336 if (!write_string (auth_file, auth->auth_name)) 337 return (0); 338 339 if (!write_counted_string (auth_file, 340 auth->auth_data_length, auth->auth_data)) 341 return (0); 342 343 return (1); 344} 345 346 347 348IceAuthFileEntry * 349IceGetAuthFileEntry (protocol_name, network_id, auth_name) 350 351char *protocol_name; 352char *network_id; 353char *auth_name; 354 355{ 356 FILE *auth_file; 357 char *filename; 358 IceAuthFileEntry *entry; 359 360 if (!(filename = IceAuthFileName ())) 361 return (NULL); 362 363 if (access (filename, R_OK) != 0) /* checks REAL id */ 364 return (NULL); 365 366 if (!(auth_file = fopen (filename, "rb"))) 367 return (NULL); 368 369 for (;;) 370 { 371 if (!(entry = IceReadAuthFileEntry (auth_file))) 372 break; 373 374 if (strcmp (protocol_name, entry->protocol_name) == 0 && 375 strcmp (network_id, entry->network_id) == 0 && 376 strcmp (auth_name, entry->auth_name) == 0) 377 { 378 break; 379 } 380 381 IceFreeAuthFileEntry (entry); 382 } 383 384 fclose (auth_file); 385 386 return (entry); 387} 388 389 390 391/* 392 * local routines 393 */ 394 395static Status 396read_short (FILE *file, unsigned short *shortp) 397{ 398 unsigned char file_short[2]; 399 400 if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 401 return (0); 402 403 *shortp = file_short[0] * 256 + file_short[1]; 404 return (1); 405} 406 407 408static Status 409read_string (FILE *file, char **stringp) 410 411{ 412 unsigned short len; 413 char *data; 414 415 if (!read_short (file, &len)) 416 return (0); 417 418 data = malloc ((unsigned) len + 1); 419 420 if (!data) 421 return (0); 422 423 if (len != 0) 424 { 425 if (fread (data, (int) sizeof (char), (int) len, file) != len) 426 { 427 free (data); 428 return (0); 429 } 430 431 } 432 data[len] = '\0'; 433 434 *stringp = data; 435 436 return (1); 437} 438 439 440static Status 441read_counted_string (FILE *file, unsigned short *countp, char **stringp) 442{ 443 unsigned short len; 444 char *data; 445 446 if (!read_short (file, &len)) 447 return (0); 448 449 if (len == 0) 450 { 451 data = 0; 452 } 453 else 454 { 455 data = malloc ((unsigned) len); 456 457 if (!data) 458 return (0); 459 460 if (fread (data, (int) sizeof (char), (int) len, file) != len) 461 { 462 free (data); 463 return (0); 464 } 465 } 466 467 *stringp = data; 468 *countp = len; 469 470 return (1); 471} 472 473 474static Status 475write_short (FILE *file, unsigned short s) 476{ 477 unsigned char file_short[2]; 478 479 file_short[0] = (s & (unsigned) 0xff00) >> 8; 480 file_short[1] = s & 0xff; 481 482 if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 483 return (0); 484 485 return (1); 486} 487 488 489static Status 490write_string (FILE *file, char *string) 491{ 492 unsigned short count = strlen (string); 493 494 if (!write_short (file, count)) 495 return (0); 496 497 if (fwrite (string, (int) sizeof (char), (int) count, file) != count) 498 return (0); 499 500 return (1); 501} 502 503 504static Status 505write_counted_string (FILE *file, unsigned short count, char *string) 506{ 507 if (!write_short (file, count)) 508 return (0); 509 510 if (fwrite (string, (int) sizeof (char), (int) count, file) != count) 511 return (0); 512 513 return (1); 514} 515