Example #1
0
/* This just gets a cookie of MIT-MAGIC-COOKIE-1 type */
char *
mdmcomm_get_a_cookie (gboolean binary)
{
	FILE *fp;
	char *number;
	char *cookie = NULL;
	Xauth *xau;

	VE_IGNORE_EINTR (fp = fopen (XauFileName (), "r"));
	if (fp == NULL) {
		return NULL;
	}

	number = get_dispnum ();

	cookie = NULL;

	while ((xau = XauReadAuth (fp)) != NULL) {
		/* Just find the FIRST magic cookie, that's what mdm uses */
		if (xau->number_length != strlen (number) ||
		    strncmp (xau->number, number, xau->number_length) != 0 ||
		    /* mdm sends MIT-MAGIC-COOKIE-1 cookies of length 16,
		     * so just do those */
		    xau->data_length != 16 ||
		    xau->name_length != strlen ("MIT-MAGIC-COOKIE-1") ||
		    strncmp (xau->name, "MIT-MAGIC-COOKIE-1",
			     xau->name_length) != 0) {
			XauDisposeAuth (xau);
			continue;
		}

		if (binary) {
			cookie = g_new0 (char, 16);
			memcpy (cookie, xau->data, 16);
		} else {
			int i;
			GString *str;

			str = g_string_new (NULL);

			for (i = 0; i < xau->data_length; i++) {
				g_string_append_printf
					(str, "%02x",
					 (guint)(guchar)xau->data[i]);
			}
			cookie = g_string_free (str, FALSE);
		}

		XauDisposeAuth (xau);

		break;
	}
Example #2
0
static Xauth*
find_auth_cookie (FILE *f)
{
    Xauth *ret = NULL;
    char local_hostname[MaxHostNameLen];
    char *display_str = getenv("DISPLAY");
    char d[MaxHostNameLen + 4];
    char *colon;
    struct addrinfo *ai;
    struct addrinfo hints;
    int disp;
    int error;

    if(display_str == NULL)
	display_str = ":0";
    strlcpy(d, display_str, sizeof(d));
    display_str = d;
    colon = strchr (display_str, ':');
    if (colon == NULL)
	disp = 0;
    else {
	*colon = '\0';
	disp = atoi (colon + 1);
    }
    if (strcmp (display_str, "") == 0
	|| strncmp (display_str, "unix", 4) == 0
	|| strncmp (display_str, "localhost", 9) == 0) {
	gethostname (local_hostname, sizeof(local_hostname));
	display_str = local_hostname;
    }
    memset (&hints, 0, sizeof(hints));
    hints.ai_flags    = AI_CANONNAME;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    error = getaddrinfo (display_str, NULL, &hints, &ai);
    if (error)
	ai = NULL;

    for (; (ret = XauReadAuth (f)) != NULL; XauDisposeAuth(ret)) {
	if (match_local_auth (ret, ai, display_str, disp) == 0) {
	    if (ai != NULL)
		freeaddrinfo (ai);
	    return ret;
	}
    }
    if (ai != NULL)
	freeaddrinfo (ai);
    return NULL;
}
Example #3
0
int
LoadAuthorization (void)
{
    FILE    *f;
    Xauth   *auth;
    int	    i;
    int	    count = 0;
#if !defined(WIN32) && !defined(__UNIXOS2__)
    char    *buf;
#endif

    ShouldLoadAuth = FALSE;
    if (!authorization_file)
	return 0;
#if !defined(WIN32) && !defined(__UNIXOS2__)
    buf = xalloc (strlen(authorization_file) + 5);
    if (!buf)
	return -1;
    sprintf (buf, "cat %s", authorization_file);
    f = Popen (buf, "r");
    xfree (buf);
#else
    f = fopen (authorization_file, "r");
#endif
    if (!f)
	return -1;

    while ((auth = XauReadAuth (f)) != 0) {
	for (i = 0; i < NUM_AUTHORIZATION; i++) {
	    if (protocols[i].name_length == auth->name_length &&
		memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 &&
		protocols[i].Add)
	    {
		++count;
		(*protocols[i].Add) (auth->data_length, auth->data,
					 FakeClientID(0));
	    }
	}
	XauDisposeAuth (auth);
    }

#if !defined(WIN32) && !defined(__UNIXOS2__)
    if (Pclose (f) != 0)
	return -1;
#else
    fclose (f);
#endif
    return count;
}
Example #4
0
void DM::GDMAuthenticate()
{
    FILE *fp;
    const char *dpy, *dnum, *dne;
    int dnl;
    Xauth *xau;

    dpy = DisplayString(QPaintDevice::x11AppDisplay());
    if(!dpy)
    {
        dpy = ::getenv("DISPLAY");
        if(!dpy)
            return;
    }
    dnum = strchr(dpy, ':') + 1;
    dne = strchr(dpy, '.');
    dnl = dne ? dne - dnum : strlen(dnum);

    /* XXX should do locking */
    if(!(fp = fopen(XauFileName(), "r")))
        return;

    while((xau = XauReadAuth(fp)))
    {
        if(xau->family == FamilyLocal && xau->number_length == dnl && !memcmp(xau->number, dnum, dnl) && xau->data_length == 16
           && xau->name_length == 18 && !memcmp(xau->name, "MIT-MAGIC-COOKIE-1", 18))
        {
            QString cmd("AUTH_LOCAL ");
            for(int i = 0; i < 16; i++)
                cmd += QString::number((uchar)xau->data[i], 16).rightJustify(2, '0');
            cmd += "\n";
            if(exec(cmd.latin1()))
            {
                XauDisposeAuth(xau);
                break;
            }
        }
        XauDisposeAuth(xau);
    }

    fclose(fp);
}
Example #5
0
static int
LoadAuthorization(void)
{
    FILE *f;
    Xauth *auth;
    int i;
    int count = 0;

    ShouldLoadAuth = FALSE;
    if (!authorization_file)
        return 0;

    errno = 0;
    f = Fopen(authorization_file, "r");
    if (!f) {
        LogMessageVerb(X_ERROR, 0,
                       "Failed to open authorization file \"%s\": %s\n",
                       authorization_file,
                       errno != 0 ? strerror(errno) : "Unknown error");
        return -1;
    }

    while ((auth = XauReadAuth(f)) != 0) {
        for (i = 0; i < NUM_AUTHORIZATION; i++) {
            if (protocols[i].name_length == auth->name_length &&
                memcmp(protocols[i].name, auth->name,
                       (int) auth->name_length) == 0 && protocols[i].Add) {
                ++count;
                (*protocols[i].Add) (auth->data_length, auth->data,
                                     FakeClientID(0));
            }
        }
        XauDisposeAuth(auth);
    }

    Fclose(f);
    return count;
}
Example #6
0
Xauth *
XauGetBestAuthByAddr (
#if NeedWidePrototypes
    unsigned int	family,
    unsigned int	address_length,
#else
    unsigned short	family,
    unsigned short	address_length,
#endif
    _Xconst char*	address,
#if NeedWidePrototypes
    unsigned int	number_length,
#else
    unsigned short	number_length,
#endif
    _Xconst char*	number,
    int			types_length,
    char**		types,
    _Xconst int*	type_lengths)
{
    FILE    *auth_file;
    char    *auth_name;
    Xauth   *entry;
    Xauth   *best;
    int	    best_type;
    int	    type;
#ifdef hpux
    char		*fully_qual_address;
    unsigned short	fully_qual_address_length;
#endif

    auth_name = XauFileName ();
    if (!auth_name)
	return NULL;
    if (access (auth_name, R_OK) != 0)		/* checks REAL id */
	return NULL;
    auth_file = fopen (auth_name, "rb");
    if (!auth_file)
	return NULL;

#ifdef hpux
    if (family == FamilyLocal) {
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
	_Xgethostbynameparams hparams;
#endif
	struct hostent *hostp;

	/* make sure we try fully-qualified hostname */
	if ((hostp = _XGethostbyname(address,hparams)) != NULL) {
	    fully_qual_address = hostp->h_name;
	    fully_qual_address_length = strlen(fully_qual_address);
	}
	else
	{
	    fully_qual_address = NULL;
	    fully_qual_address_length = 0;
	}
    }
#endif /* hpux */

    best = NULL;
    best_type = types_length;
    for (;;) {
	entry = XauReadAuth (auth_file);
	if (!entry)
	    break;
	/*
	 * Match when:
	 *   either family or entry->family are FamilyWild or
	 *    family and entry->family are the same and
	 *     address and entry->address are the same
	 *  and
	 *   either number or entry->number are empty or
	 *    number and entry->number are the same
	 *  and
	 *   either name or entry->name are empty or
	 *    name and entry->name are the same
	 */

	if ((family == FamilyWild || entry->family == FamilyWild ||
	     (entry->family == family &&
	     ((address_length == entry->address_length &&
	      binaryEqual (entry->address, address, (int)address_length))
#ifdef hpux
	     || (family == FamilyLocal &&
		fully_qual_address_length == entry->address_length &&
	     	binaryEqual (entry->address, fully_qual_address,
		    (int) fully_qual_address_length))
#endif
	    ))) &&
	    (number_length == 0 || entry->number_length == 0 ||
	     (number_length == entry->number_length &&
	      binaryEqual (entry->number, number, (int)number_length))))
	{
	    if (best_type == 0)
	    {
		best = entry;
		break;
	    }
	    for (type = 0; type < best_type; type++)
		if (type_lengths[type] == entry->name_length &&
		    !(strncmp (types[type], entry->name, entry->name_length)))
		{
		    break;
		}
	    if (type < best_type)
	    {
		if (best)
		    XauDisposeAuth (best);
		best = entry;
		best_type = type;
		if (type == 0)
		    break;
		continue;
	    }
	}
	XauDisposeAuth (entry);
    }
    (void) fclose (auth_file);
    return best;
}
Example #7
0
Xauth *
XauGetAuthByAddr (
#if NeedWidePrototypes
    unsigned int	family,
    unsigned int	address_length,
#else
    unsigned short	family,
    unsigned short	address_length,
#endif
    _Xconst char*	address,
#if NeedWidePrototypes
    unsigned int	number_length,
#else
    unsigned short	number_length,
#endif
    _Xconst char*	number,
#if NeedWidePrototypes
    unsigned int	name_length,
#else
    unsigned short	name_length,
#endif
    _Xconst char*	name)
{
    FILE    *auth_file;
    char    *auth_name;
    Xauth   *entry;

    auth_name = XauFileName ();
    if (!auth_name)
        return NULL;
    if (access (auth_name, R_OK) != 0)		/* checks REAL id */
        return NULL;
    auth_file = fopen (auth_name, "rb");
    if (!auth_file)
        return NULL;
    for (;;) {
        entry = XauReadAuth (auth_file);
        if (!entry)
            break;
        /*
         * Match when:
         *   either family or entry->family are FamilyWild or
         *    family and entry->family are the same and
         *     address and entry->address are the same
         *  and
         *   either number or entry->number are empty or
         *    number and entry->number are the same
         *  and
         *   either name or entry->name are empty or
         *    name and entry->name are the same
         */

        if ((family == FamilyWild || entry->family == FamilyWild ||
                (entry->family == family &&
                 address_length == entry->address_length &&
                 binaryEqual (entry->address, address, address_length))) &&
                (number_length == 0 || entry->number_length == 0 ||
                 (number_length == entry->number_length &&
                  binaryEqual (entry->number, number, number_length))) &&
                (name_length == 0 || entry->name_length == 0 ||
                 (entry->name_length == name_length &&
                  binaryEqual (entry->name, name, name_length))))
            break;
        XauDisposeAuth (entry);
    }
    (void) fclose (auth_file);
    return entry;
}
Example #8
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;
    }
}
Example #9
0
static gboolean
gdm_authenticate_connection (GdmProtocolData *data)
{
#define GDM_MIT_MAGIC_COOKIE_LEN 16

        const char *xau_path;
        FILE       *f;
        Xauth      *xau;
        char       *display_number;
        gboolean    retval;

        if (data->auth_cookie) {
                char *msg;
                char *response;

                msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s",
                                       data->auth_cookie);
                response = gdm_send_protocol_msg (data, msg);
                g_free (msg);
 
                if (response && !strcmp (response, "OK")) {
                        g_free (response);
                        return TRUE;
                } else {
                        g_free (response);
                        g_free (data->auth_cookie);
                        data->auth_cookie = NULL;
                }
        }

        if (!(xau_path = XauFileName ()))
                return FALSE;

        if (!(f = fopen (xau_path, "r")))
                return FALSE;

        retval = FALSE;
        display_number = get_display_number ();

        while ((xau = XauReadAuth (f))) {
                char  buffer[40]; /* 2*16 == 32, so 40 is enough */
                char *msg;
                char *response;
                int   i;

                if (xau->family != FamilyLocal ||
                    strncmp (xau->number, display_number, xau->number_length) ||
                    strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) ||
                    xau->data_length != GDM_MIT_MAGIC_COOKIE_LEN) {
                        XauDisposeAuth (xau);
                        continue;
                }
                
                for (i = 0; i < GDM_MIT_MAGIC_COOKIE_LEN; i++)
                        g_snprintf (buffer + 2*i, 3, "%02x", (guint)(guchar)xau->data[i]);
                
                XauDisposeAuth (xau);
                
                msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer);
                response = gdm_send_protocol_msg (data, msg);
                g_free (msg);
 
                if (response && !strcmp (response, "OK")) {
			data->auth_cookie = g_strdup (buffer);
                        g_free (response);
                        retval = TRUE;
                        break;
                }

                g_free (response);
        }

        g_free (display_number);
        
        fclose (f);

        return retval;

#undef GDM_MIT_MAGIC_COOKIE_LEN
}
/* 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 #11
0
Xauth *
XauGetBestAuthByAddr (
#if NeedWidePrototypes
    unsigned int	family,
    unsigned int	address_length,
#else
    unsigned short	family,
    unsigned short	address_length,
#endif
    _Xconst char*	address,
#if NeedWidePrototypes
    unsigned int	number_length,
#else
    unsigned short	number_length,
#endif
    _Xconst char*	number,
    int			types_length,
    char**		types,
    _Xconst int*	type_lengths)
{
    FILE    *auth_file;
    char    *auth_name;
    Xauth   *entry;
    Xauth   *best;
    int	    best_type;
    int	    type;

    auth_name = XauFileName ();
    if (!auth_name)
	return 0;
    if (access (auth_name, R_OK) != 0)		/* checks REAL id */
	return 0;
    auth_file = fopen (auth_name, "rb");
    if (!auth_file)
	return 0;


    best = 0;
    best_type = types_length;
    for (;;) {
	entry = XauReadAuth (auth_file);
	if (!entry)
	    break;
	/*
	 * Match when:
	 *   either family or entry->family are FamilyWild or
	 *    family and entry->family are the same and
	 *     address and entry->address are the same
	 *  and
	 *   either number or entry->number are empty or
	 *    number and entry->number are the same
	 *  and
	 *   either name or entry->name are empty or
	 *    name and entry->name are the same
	 */

	if ((family == FamilyWild || entry->family == FamilyWild ||
	     (entry->family == family &&
	     ((address_length == entry->address_length &&
	      binaryEqual (entry->address, address, (int)address_length))
	    ))) &&
	    (number_length == 0 || entry->number_length == 0 ||
	     (number_length == entry->number_length &&
	      binaryEqual (entry->number, number, (int)number_length))))
	{
	    if (best_type == 0)
	    {
		best = entry;
		break;
	    }
	    for (type = 0; type < best_type; type++)
		if (type_lengths[type] == entry->name_length &&
		    !(strncmp (types[type], entry->name, entry->name_length)))
		{
		    break;
		}
	    if (type < best_type)
	    {
		if (best)
		    XauDisposeAuth (best);
		best = entry;
		best_type = type;
		if (type == 0)
		    break;
		continue;
	    }
	}
	XauDisposeAuth (entry);
    }
    (void) fclose (auth_file);
    return best;
}