authutil.c revision c5629e66
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 static char slashDotICEauthority[] = "/.ICEauthority"; 77 char *name; 78 static char *buf; 79 static int bsize; 80 int size; 81#if defined(WIN32) || defined(__UNIXOS2__) 82#ifndef PATH_MAX 83#define PATH_MAX 512 84#endif 85 char dir[PATH_MAX]; 86#endif 87 88 if ((name = getenv ("ICEAUTHORITY"))) 89 return (name); 90 91 name = getenv ("HOME"); 92 93 if (!name) 94 { 95#ifdef WIN32 96 register char *ptr1; 97 register char *ptr2; 98 int len1 = 0, len2 = 0; 99 100 if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) { 101 len1 = strlen (ptr1); 102 len2 = strlen (ptr2); 103 } else if ((ptr2 = getenv("USERNAME"))) { 104 len1 = strlen (ptr1 = "/users/"); 105 len2 = strlen (ptr2); 106 } 107 if ((len1 + len2 + 1) < PATH_MAX) { 108 sprintf (dir, "%s%s", ptr1, (ptr2) ? ptr2 : ""); 109 name = dir; 110 } 111 if (!name) 112#endif 113#ifdef __UNIXOS2__ 114 strcpy (dir,"c:"); 115 name = dir; 116 if (!name) 117#endif 118 return (NULL); 119 } 120 121 size = strlen (name) + strlen (&slashDotICEauthority[1]) + 2; 122 123 if (size > bsize) 124 { 125 if (buf) 126 free (buf); 127 buf = malloc ((unsigned) size); 128 if (!buf) 129 return (NULL); 130 bsize = size; 131 } 132 133 strcpy (buf, name); 134 strcat (buf, slashDotICEauthority + (name[1] == '\0' ? 1 : 0)); 135 136 return (buf); 137} 138 139 140 141int 142IceLockAuthFile ( 143 char *file_name, 144 int retries, 145 int timeout, 146 long dead 147) 148{ 149 char creat_name[1025], link_name[1025]; 150 struct stat statb; 151 Time_t now; 152 int creat_fd = -1; 153 154 if ((int) strlen (file_name) > 1022) 155 return (IceAuthLockError); 156 157 strcpy (creat_name, file_name); 158 strcat (creat_name, "-c"); 159 strcpy (link_name, file_name); 160 strcat (link_name, "-l"); 161 162 if (stat (creat_name, &statb) != -1) 163 { 164 now = time ((Time_t *) 0); 165 166 /* 167 * NFS may cause ctime to be before now, special 168 * case a 0 deadtime to force lock removal 169 */ 170 171 if (dead == 0 || now - statb.st_ctime > dead) 172 { 173 unlink (creat_name); 174 unlink (link_name); 175 } 176 } 177 178 while (retries > 0) 179 { 180 if (creat_fd == -1) 181 { 182 creat_fd = creat (creat_name, 0666); 183 184 if (creat_fd == -1) 185 { 186 if (errno != EACCES) 187 return (IceAuthLockError); 188 } 189 else 190 close (creat_fd); 191 } 192 193 if (creat_fd != -1) 194 { 195 if (link (creat_name, link_name) != -1) 196 return (IceAuthLockSuccess); 197 198 if (errno == ENOENT) 199 { 200 creat_fd = -1; /* force re-creat next time around */ 201 continue; 202 } 203 204 if (errno != EEXIST) 205 return (IceAuthLockError); 206 } 207 208 sleep ((unsigned) timeout); 209 --retries; 210 } 211 212 return (IceAuthLockTimeout); 213} 214 215 216 217void 218IceUnlockAuthFile ( 219 char *file_name 220) 221{ 222#ifndef WIN32 223 char creat_name[1025]; 224#endif 225 char link_name[1025]; 226 227 if ((int) strlen (file_name) > 1022) 228 return; 229 230#ifndef WIN32 231 strcpy (creat_name, file_name); 232 strcat (creat_name, "-c"); 233#endif 234 strcpy (link_name, file_name); 235 strcat (link_name, "-l"); 236 237#ifndef WIN32 238 unlink (creat_name); 239#endif 240 unlink (link_name); 241} 242 243 244 245IceAuthFileEntry * 246IceReadAuthFileEntry ( 247 FILE *auth_file 248) 249{ 250 IceAuthFileEntry local; 251 IceAuthFileEntry *ret; 252 253 local.protocol_name = NULL; 254 local.protocol_data = NULL; 255 local.network_id = NULL; 256 local.auth_name = NULL; 257 local.auth_data = NULL; 258 259 if (!read_string (auth_file, &local.protocol_name)) 260 return (NULL); 261 262 if (!read_counted_string (auth_file, 263 &local.protocol_data_length, &local.protocol_data)) 264 goto bad; 265 266 if (!read_string (auth_file, &local.network_id)) 267 goto bad; 268 269 if (!read_string (auth_file, &local.auth_name)) 270 goto bad; 271 272 if (!read_counted_string (auth_file, 273 &local.auth_data_length, &local.auth_data)) 274 goto bad; 275 276 if (!(ret = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry)))) 277 goto bad; 278 279 *ret = local; 280 281 return (ret); 282 283 bad: 284 285 if (local.protocol_name) free (local.protocol_name); 286 if (local.protocol_data) free (local.protocol_data); 287 if (local.network_id) free (local.network_id); 288 if (local.auth_name) free (local.auth_name); 289 if (local.auth_data) free (local.auth_data); 290 291 return (NULL); 292} 293 294 295 296void 297IceFreeAuthFileEntry ( 298 IceAuthFileEntry *auth 299) 300{ 301 if (auth) 302 { 303 if (auth->protocol_name) free (auth->protocol_name); 304 if (auth->protocol_data) free (auth->protocol_data); 305 if (auth->network_id) free (auth->network_id); 306 if (auth->auth_name) free (auth->auth_name); 307 if (auth->auth_data) free (auth->auth_data); 308 free ((char *) auth); 309 } 310} 311 312 313 314Status 315IceWriteAuthFileEntry ( 316 FILE *auth_file, 317 IceAuthFileEntry *auth 318) 319{ 320 if (!write_string (auth_file, auth->protocol_name)) 321 return (0); 322 323 if (!write_counted_string (auth_file, 324 auth->protocol_data_length, auth->protocol_data)) 325 return (0); 326 327 if (!write_string (auth_file, auth->network_id)) 328 return (0); 329 330 if (!write_string (auth_file, auth->auth_name)) 331 return (0); 332 333 if (!write_counted_string (auth_file, 334 auth->auth_data_length, auth->auth_data)) 335 return (0); 336 337 return (1); 338} 339 340 341 342IceAuthFileEntry * 343IceGetAuthFileEntry ( 344 char *protocol_name, 345 char *network_id, 346 char *auth_name 347) 348{ 349 FILE *auth_file; 350 char *filename; 351 IceAuthFileEntry *entry; 352 353 if (!(filename = IceAuthFileName ())) 354 return (NULL); 355 356 if (access (filename, R_OK) != 0) /* checks REAL id */ 357 return (NULL); 358 359 if (!(auth_file = fopen (filename, "rb"))) 360 return (NULL); 361 362 for (;;) 363 { 364 if (!(entry = IceReadAuthFileEntry (auth_file))) 365 break; 366 367 if (strcmp (protocol_name, entry->protocol_name) == 0 && 368 strcmp (network_id, entry->network_id) == 0 && 369 strcmp (auth_name, entry->auth_name) == 0) 370 { 371 break; 372 } 373 374 IceFreeAuthFileEntry (entry); 375 } 376 377 fclose (auth_file); 378 379 return (entry); 380} 381 382 383 384/* 385 * local routines 386 */ 387 388static Status 389read_short (FILE *file, unsigned short *shortp) 390{ 391 unsigned char file_short[2]; 392 393 if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 394 return (0); 395 396 *shortp = file_short[0] * 256 + file_short[1]; 397 return (1); 398} 399 400 401static Status 402read_string (FILE *file, char **stringp) 403 404{ 405 unsigned short len; 406 char *data; 407 408 if (!read_short (file, &len)) 409 return (0); 410 411 data = malloc ((unsigned) len + 1); 412 413 if (!data) 414 return (0); 415 416 if (len != 0) 417 { 418 if (fread (data, (int) sizeof (char), (int) len, file) != len) 419 { 420 free (data); 421 return (0); 422 } 423 424 } 425 data[len] = '\0'; 426 427 *stringp = data; 428 429 return (1); 430} 431 432 433static Status 434read_counted_string (FILE *file, unsigned short *countp, char **stringp) 435{ 436 unsigned short len; 437 char *data; 438 439 if (!read_short (file, &len)) 440 return (0); 441 442 if (len == 0) 443 { 444 data = NULL; 445 } 446 else 447 { 448 data = malloc ((unsigned) len); 449 450 if (!data) 451 return (0); 452 453 if (fread (data, (int) sizeof (char), (int) len, file) != len) 454 { 455 free (data); 456 return (0); 457 } 458 } 459 460 *stringp = data; 461 *countp = len; 462 463 return (1); 464} 465 466 467static Status 468write_short (FILE *file, unsigned short s) 469{ 470 unsigned char file_short[2]; 471 472 file_short[0] = (s & (unsigned) 0xff00) >> 8; 473 file_short[1] = s & 0xff; 474 475 if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 476 return (0); 477 478 return (1); 479} 480 481 482static Status 483write_string (FILE *file, char *string) 484{ 485 unsigned short count = strlen (string); 486 487 if (!write_short (file, count)) 488 return (0); 489 490 if (fwrite (string, (int) sizeof (char), (int) count, file) != count) 491 return (0); 492 493 return (1); 494} 495 496 497static Status 498write_counted_string (FILE *file, unsigned short count, char *string) 499{ 500 if (!write_short (file, count)) 501 return (0); 502 503 if (fwrite (string, (int) sizeof (char), (int) count, file) != count) 504 return (0); 505 506 return (1); 507} 508