static char * prepare_auth_file (void) { FILE *fp = NULL; char *filename = NULL; GError *error = NULL; gboolean prepared = FALSE; Xauth auth_entry = { 0 }; char localhost[HOST_NAME_MAX + 1] = ""; g_debug ("Preparing auth file for X server"); fp = create_auth_file (&filename); if (fp == NULL) { return NULL; } if (gethostname (localhost, HOST_NAME_MAX) < 0) { strncpy (localhost, "localhost", sizeof (localhost) - 1); } auth_entry.family = FamilyLocal; auth_entry.address = localhost; auth_entry.address_length = strlen (auth_entry.address); auth_entry.name = "MIT-MAGIC-COOKIE-1"; auth_entry.name_length = strlen (auth_entry.name); auth_entry.data_length = 16; auth_entry.data = gdm_generate_random_bytes (auth_entry.data_length, &error); if (error != NULL) { goto out; } if (!XauWriteAuth (fp, &auth_entry) || fflush (fp) == EOF) { goto out; } auth_entry.family = FamilyWild; if (!XauWriteAuth (fp, &auth_entry) || fflush (fp) == EOF) { goto out; } prepared = TRUE; out: g_clear_pointer (&auth_entry.data, g_free); g_clear_pointer (&fp, fclose); if (!prepared) { g_clear_pointer (&filename, g_free); } return filename; }
static int write_auth_file(char *tmp_nam) { FILE *fp = NULL; int fd; AuthList *list; /* * xdm and auth spec assumes auth file is 12 or fewer characters */ strcpy (tmp_nam, xauth_filename); strcat (tmp_nam, "-n"); /* for new */ (void) unlink (tmp_nam); /* CPhipps 2000/02/12 - fix file unlink/fopen race */ fd = open(tmp_nam, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd != -1) fp = fdopen (fd, "wb"); if (!fp) { if (fd != -1) close(fd); fprintf (stderr, "%s: unable to open tmp file \"%s\"\n", ProgramName, tmp_nam); return -1; } /* * Write MIT-MAGIC-COOKIE-1 first, because R4 Xlib knows * only that and uses the first authorization it finds. */ for (list = xauth_head; list; list = list->next) { if (list->auth->name_length == 18 && strncmp(list->auth->name, "MIT-MAGIC-COOKIE-1", 18) == 0) { if (!XauWriteAuth(fp, list->auth)) { (void) fclose(fp); return -1; } } } for (list = xauth_head; list; list = list->next) { if (list->auth->name_length != 18 || strncmp(list->auth->name, "MIT-MAGIC-COOKIE-1", 18) != 0) { if (!XauWriteAuth(fp, list->auth)) { (void) fclose(fp); return -1; } } } (void) fclose (fp); return 0; }
static int session_setup_auth (char* display, char* auth_data, int auth_fd) { Xauth auth; int random_fd, i; ssize_t bytes, size; char auth_host[256]; FILE *file; auth.family = FamilyLocal; gethostname (auth_host, sizeof (auth_host)); auth.address = auth_host; auth.address_length = strlen (auth_host); auth.number = display; auth.number_length = strlen (auth.number); auth.name = "MIT-MAGIC-COOKIE-1"; auth.name_length = strlen (auth.name); random_fd = open ("/dev/urandom", O_RDONLY); if (random_fd == -1) return 1; bytes = 0; do { size = read (random_fd, auth_data + bytes, AUTH_DATA_LEN - bytes); if (size <= 0) break; bytes += size; } while (bytes != AUTH_DATA_LEN); close (random_fd); if (bytes != AUTH_DATA_LEN) return 1; auth.data = auth_data; auth.data_length = AUTH_DATA_LEN; file = fdopen (auth_fd, "w"); if (!file) { close (auth_fd); return 1; } XauWriteAuth (file, &auth); fclose (file); return 0; }
static Bool xglxSetupAuth (char *name, int authFd) { Xauth auth; int randomFd; ssize_t bytes, size; char authHost[256]; char authData[AUTH_DATA_LEN]; FILE *file; auth.family = FamilyLocal; gethostname (authHost, sizeof (authHost)); auth.address = authHost; auth.address_length = strlen (authHost); auth.number = strrchr (xorgDisplay, ':'); if (!auth.number) { ErrorF ("Bad Xorg display name: %s\n", xorgDisplay); return FALSE; } auth.number++; auth.number_length = strlen (auth.number); if (!auth.number_length) { ErrorF ("Bad Xorg display name: %s\n", xorgDisplay); return FALSE; } auth.name = "MIT-MAGIC-COOKIE-1"; auth.name_length = strlen (auth.name); randomFd = open (XORG_DEV_RANDOM, O_RDONLY); if (randomFd == -1) { ErrorF ("Failed to open " XORG_DEV_RANDOM "\n"); return FALSE; } bytes = 0; do { size = read (randomFd, authData + bytes, AUTH_DATA_LEN - bytes); if (size <= 0) break; bytes += size; } while (bytes != AUTH_DATA_LEN); close (randomFd); if (bytes != AUTH_DATA_LEN) { ErrorF ("Failed to read %d random bytes from " XORG_DEV_RANDOM "\n", AUTH_DATA_LEN); return FALSE; } auth.data = authData; auth.data_length = AUTH_DATA_LEN; file = fdopen (authFd, "w"); if (!file) { ErrorF ("Failed to open authorization file: %s\n", name); close (authFd); return FALSE; } XauWriteAuth (file, &auth); fclose (file); return TRUE; }
/******************************************************************** * * fork/exec a child pdm after setting up a message pipe. */ void mgr_launch_pdm( XpPdmServiceRec *rec ) { int i; struct sigaction svec; char buf[1024]; int original_umask; char *existing_name; FILE *existing_file; Xauth *entry; char *envstr; /* * Setup message pipe. */ if ( pipe(rec->message_pipe) == -1 ) { rec->pdm_exec_errorcode = g.pdm_start_error; sprintf( buf, PDMD_MSG_8, g.prog_name ); rec->pdm_exec_errormessage = xpstrdup( buf ); return; } rec->message_xtid = XtAppAddInput( g.context, rec->message_pipe[0], (XtPointer) XtInputReadMask, message_pipe_handler, (XtPointer) NULL ); /* * See if a cookie file is needed. */ if (rec->cookie_cnt) { /* * Create new .Xauthority file. */ original_umask = umask (0077); /* disallow non-owner access */ tmpnam( rec->auth_filename ); rec->auth_file = fopen( rec->auth_filename, "w" ); if (rec->auth_file) { /* * Copy existing .Xauthority entries. */ existing_name = XauFileName (); if (existing_name) { if (access (existing_name, R_OK) == 0) { /* checks REAL id */ existing_file = fopen (existing_name, "r"); if (existing_file) { for (;;) { entry = XauReadAuth (existing_file); if (!entry) break; XauWriteAuth( rec->auth_file, entry ); XauDisposeAuth (entry); } fclose (existing_file); } } } /* * Merge in cookies recently sent. */ for ( i = 0; i < rec->cookie_cnt; i++ ) { XauWriteAuth( rec->auth_file, rec->cookies[i] ); } fclose( rec->auth_file ); } original_umask = umask (original_umask); } rec->pid = fork(); if ( rec->pid < 0 ) { rec->pdm_exec_errorcode = g.pdm_start_error; sprintf( buf, PDMD_MSG_9, g.prog_name ); rec->pdm_exec_errormessage = xpstrdup( buf ); return; } else if ( rec->pid == 0) { /* * Child process. */ /* * Hook stderr back to parent via message pipe. */ dup2(rec->message_pipe[1], 2); close(rec->message_pipe[0]); /* * The child should have default behavior for all signals. */ sigemptyset(&svec.sa_mask); svec.sa_flags = 0; svec.sa_handler = SIG_DFL; (void) sigaction(SIGCHLD, &svec, (struct sigaction *) NULL); for (i=3; i < FOPEN_MAX; i++) { if ((i != rec->message_pipe[1]) && (rec->auth_file && (i != fileno(rec->auth_file)))) { (void) fcntl (i, F_SETFD, 1); } } /* * Set the new locale for the child. * * note: the locale hint will be of the form: * * name_spec[;registry_spec[;ver_spec[;encoding_spec]]] * * for now, just pull out the name_spec (e.g. 'C') * and use it. With a little work, a more complex * syntax could be understood and the appropriate * actions taken here rather than just wedging * name_spec into setlocale() and hoping. */ if ( !(rec->locale_hint) ) { /* * Leave current locale alone. */ } else if ( strcmp( rec->locale_hint, "" ) ) { /* * Leave current locale alone. Note that "" into * setlocale says to go with default vs leave it alone. */ } else { char *tptr1, *tptr2; tptr1 = xpstrdup( rec->locale_hint ); tptr2 = strchr( tptr1, ';' ); if (tptr2) *tptr2 = '\0'; setlocale( LC_ALL, tptr1 ); XFree( tptr1 ); } /* * Set XAUTHORITY env var if needed. */ if ((rec->cookie_cnt) && (rec->auth_filename) && (rec->auth_file)) { envstr = Xmalloc( strlen(rec->auth_filename) + 12 ); sprintf( envstr, "XAUTHORITY=%s", rec->auth_filename ); putenv( envstr ); } /* * Start the child for real. */ (void) execvp(rec->pdm_exec_argvs[0], rec->pdm_exec_argvs); (void) fprintf (stderr, PDMD_MSG_10, g.prog_name, rec->pdm_exec_argvs[0]); /* * tomg - need to deal with failed child start. */ exit(PDM_EXIT_ERROR); } else { /* * Parent process. */ /* * Close the write end of the pipe - only the child needs it. */ close(rec->message_pipe[1]); rec->message_pipe[1] = -1; } }
/* 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; }
int create_and_write_cookie (char *file, size_t file_size, u_char *cookie_buf, size_t cookie_sz) { Xauth auth; char tmp[64]; int fd; FILE *f; char hostname[MaxHostNameLen]; int saved_errno; gethostname (hostname, sizeof(hostname)); auth.family = FamilyLocal; auth.address = hostname; auth.address_length = strlen(auth.address); snprintf (tmp, sizeof(tmp), "%d", display_num); auth.number_length = strlen(tmp); auth.number = tmp; auth.name = COOKIE_TYPE; auth.name_length = strlen(auth.name); auth.data_length = cookie_sz; auth.data = (char*)cookie_buf; #ifdef KRB5 krb5_generate_random_block (cookie_buf, cookie_sz); #else krb_generate_random_block (cookie_buf, cookie_sz); #endif strlcpy(file, "/tmp/AXXXXXX", file_size); fd = mkstemp(file); if(fd < 0) { saved_errno = errno; syslog(LOG_ERR, "create_and_write_cookie: mkstemp: %m"); return saved_errno; } f = fdopen(fd, "r+"); if(f == NULL){ saved_errno = errno; close(fd); return errno; } if(XauWriteAuth(f, &auth) == 0) { saved_errno = errno; fclose(f); return saved_errno; } /* * I would like to write a cookie for localhost:n here, but some * stupid code in libX11 will not look for cookies of that type, * so we are forced to use FamilyWild instead. */ auth.family = FamilyWild; auth.address_length = 0; if (XauWriteAuth(f, &auth) == 0) { saved_errno = errno; fclose (f); return saved_errno; } if(fclose(f)) return errno; return 0; }