int auth_initialize(char *authfilename) { int n; AuthList *head, *tail; FILE *authfp; Bool exists; xauth_filename = authfilename; /* used in cleanup, prevent race with signals */ register_signals (); bzero ((char *) hexvalues, sizeof hexvalues); hexvalues['0'] = 0; hexvalues['1'] = 1; hexvalues['2'] = 2; hexvalues['3'] = 3; hexvalues['4'] = 4; hexvalues['5'] = 5; hexvalues['6'] = 6; hexvalues['7'] = 7; hexvalues['8'] = 8; hexvalues['9'] = 9; hexvalues['a'] = hexvalues['A'] = 0xa; hexvalues['b'] = hexvalues['B'] = 0xb; hexvalues['c'] = hexvalues['C'] = 0xc; hexvalues['d'] = hexvalues['D'] = 0xd; hexvalues['e'] = hexvalues['E'] = 0xe; hexvalues['f'] = hexvalues['F'] = 0xf; if (break_locks && verbose) { printf ("Attempting to break locks on authority file %s\n", authfilename); } if (ignore_locks) { if (break_locks) XauUnlockAuth (authfilename); } else { n = XauLockAuth (authfilename, XAUTH_DEFAULT_RETRIES, XAUTH_DEFAULT_TIMEOUT, (break_locks ? 0L : XAUTH_DEFAULT_DEADTIME)); if (n != LOCK_SUCCESS) { char *reason = "unknown error"; switch (n) { case LOCK_ERROR: reason = "error"; break; case LOCK_TIMEOUT: reason = "timeout"; break; } fprintf (stderr, "%s: %s in locking authority file %s\n", ProgramName, reason, authfilename); return -1; } else xauth_locked = True; } /* these checks can only be done reliably after the file is locked */ exists = (access (authfilename, F_OK) == 0); if (exists && access (authfilename, W_OK) != 0) { fprintf (stderr, "%s: %s not writable, changes will be ignored\n", ProgramName, authfilename); xauth_allowed = False; } original_umask = umask (0077); /* disallow non-owner access */ authfp = fopen (authfilename, "rb"); if (!authfp) { int olderrno = errno; /* if file there then error */ if (access (authfilename, F_OK) == 0) { /* then file does exist! */ errno = olderrno; return -1; } /* else ignore it */ fprintf (stderr, "%s: creating new authority file %s\n", ProgramName, authfilename); } else { xauth_existed = True; n = read_auth_entries (authfp, False, &head, &tail); (void) fclose (authfp); if (n < 0) { fprintf (stderr, "%s: unable to read auth entries from file \"%s\"\n", ProgramName, authfilename); return -1; } xauth_head = head; } n = strlen (authfilename); xauth_filename = malloc (n + 1); if (xauth_filename) strcpy (xauth_filename, authfilename); else { fprintf(stderr,"cannot allocate memory\n"); return -1; } xauth_modified = False; if (verbose) { printf ("%s authority file %s\n", ignore_locks ? "Ignoring locks on" : "Using", authfilename); } return 0; }
int auth_finalize(void) { char temp_name[1024]; /* large filename size */ if (xauth_modified) { if (dieing) { if (verbose) { /* * called from a signal handler -- printf is *not* reentrant; also * fileno() might not be reentrant, avoid it if possible, and use * stderr instead of stdout */ #ifdef STDERR_FILENO WRITES(STDERR_FILENO, "\nAborting changes to authority file "); WRITES(STDERR_FILENO, xauth_filename); WRITES(STDERR_FILENO, "\n"); #else WRITES(fileno(stderr), "\nAborting changes to authority file "); WRITES(fileno(stderr), xauth_filename); WRITES(fileno(stderr), "\n"); #endif } } else if (!xauth_allowed) { fprintf (stderr, "%s: %s not writable, changes ignored\n", ProgramName, xauth_filename); } else { if (verbose) { printf ("%s authority file %s\n", ignore_locks ? "Ignoring locks and writing" : "Writing", xauth_filename); } temp_name[0] = '\0'; if (write_auth_file (temp_name) == -1) { fprintf (stderr, "%s: unable to write authority file %s\n", ProgramName, temp_name); } else { (void) unlink (xauth_filename); #if defined(WIN32) || defined(__UNIXOS2__)|| defined(__CYGWIN__) if (rename(temp_name, xauth_filename) == -1) #else if (link (temp_name, xauth_filename) == -1) #endif { fprintf (stderr, "%s: unable to link authority file %s, use %s\n", ProgramName, xauth_filename, temp_name); } else { (void) unlink (temp_name); } } } } if (xauth_locked) { XauUnlockAuth (xauth_filename); } (void) umask (original_umask); return 0; }
/* If ADD-ENTRIES is true, merge our auth entries into the existing Xauthority file. If ADD-ENTRIES is false, remove our entries. */ static int write_auth_file (int add_entries) { char *home, newname[1024]; int fd, ret; FILE *new_fh, *old_fh; addr_list *addr; Xauth *auth; if (auth_file == NULL) return FALSE; home = getenv ("HOME"); if (home == NULL) { auth_file = NULL; return FALSE; } snprintf (newname, sizeof (newname), "%s/.XauthorityXXXXXX", home); mktemp (newname); if (XauLockAuth (auth_file, 1, 2, 10) != LOCK_SUCCESS) { /* FIXME: do something here? */ auth_file = NULL; return FALSE; } fd = open (newname, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd >= 0) { new_fh = fdopen (fd, "w"); if (new_fh != NULL) { if (add_entries) { for (addr = addresses; addr != NULL; addr = addr->next) { XauWriteAuth (new_fh, &addr->auth); } } old_fh = fopen (auth_file, "r"); if (old_fh != NULL) { while ((auth = XauReadAuth (old_fh)) != NULL) { if (!check_auth_item (auth)) XauWriteAuth (new_fh, auth); XauDisposeAuth (auth); } fclose (old_fh); } fclose (new_fh); unlink (auth_file); ret = rename (newname, auth_file); if (ret != 0) auth_file = NULL; XauUnlockAuth (auth_file); return ret == 0; } close (fd); } XauUnlockAuth (auth_file); auth_file = NULL; return FALSE; }