Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
/********************************************************************
 *
 * 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;
}
Example #7
0
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;
}