Ejemplo n.º 1
0
void fs_x11(void) {
#ifdef HAVE_X11
	int display = x11_display();
	if (display <= 0)
		return;

	char *x11file;
	if (asprintf(&x11file, "/tmp/.X11-unix/X%d", display) == -1)
		errExit("asprintf");
	struct stat s;
	if (stat(x11file, &s) == -1)
		return;

	// keep a copy of real /tmp/.X11-unix directory in WHITELIST_TMP_DIR
	int rv = mkdir(RUN_WHITELIST_X11_DIR, 1777);
	if (rv == -1)
		errExit("mkdir");
	if (chown(RUN_WHITELIST_X11_DIR, 0, 0) < 0)
		errExit("chown");
	if (chmod(RUN_WHITELIST_X11_DIR, 1777) < 0)
		errExit("chmod");

	if (mount("/tmp/.X11-unix", RUN_WHITELIST_X11_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
		errExit("mount bind");

	// mount tmpfs on /tmp/.X11-unix
	if (arg_debug || arg_debug_whitelists)
		printf("Mounting tmpfs on /tmp/.X11-unix directory\n");
	if (mount("tmpfs", "/tmp/.X11-unix", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=1777,gid=0") < 0)
		errExit("mounting tmpfs on /tmp");
	fs_logger("tmpfs /tmp/.X11-unix");

	// create an empty file
	FILE *fp = fopen(x11file, "w");
	if (!fp) {
		fprintf(stderr, "Error: cannot create empty file in x11 directory\n");
		exit(1);
	}
	// set file properties
	SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
	fclose(fp);

	// mount
	char *wx11file;
	if (asprintf(&wx11file, "%s/X%d", RUN_WHITELIST_X11_DIR, display) == -1)
		errExit("asprintf");
	if (mount(wx11file, x11file, NULL, MS_BIND|MS_REC, NULL) < 0)
		errExit("mount bind");
	 fs_logger2("whitelist", x11file);

	free(x11file);
	free(wx11file);
	
	// block access to RUN_WHITELIST_X11_DIR
	 if (mount(RUN_RO_DIR, RUN_WHITELIST_X11_DIR, "none", MS_BIND, "mode=400,gid=0") == -1)
	 	errExit("mount");
	 fs_logger2("blacklist", RUN_WHITELIST_X11_DIR);
#endif
}
Ejemplo n.º 2
0
void platform_get_x11_auth(char *display, int *protocol,
                           unsigned char *data, int *datalen)
{
    FILE *fp;
    char *command;
    int maxsize = *datalen;
    char *localbuf;
    int proto = -1;

    display = x11_display(display);
    /*
     * Normally we should run `xauth list DISPLAYNAME'. However,
     * there's an oddity when the display is local: the display
     * `localhost:0' (or `:0') should become just `:0'.
     */
    if (!strncmp(display, "localhost:", 10)
	|| !strncmp(display, "unix:", 5))
	command = dupprintf("xauth list %s 2>/dev/null",
			    strchr(display, ':'));
    else
	command = dupprintf("xauth list %s 2>/dev/null", display);
    sfree(display);
    fp = popen(command, "r");
    sfree(command);

    if (!fp)
        return;                        /* assume no auth */

    localbuf = snewn(maxsize, char);

    while (1) {
        /*
         * Read a line from stdin, and attempt to parse it into a
         * display name (ignored), auth protocol, and auth string.
         */
        int c, i, hexdigit;
        char protoname[64];

        /* Skip the display name. */
        while (c = getc(fp), c != EOF && c != '\n' && !isspace(c));
        if (c == EOF) break;
        if (c == '\n') continue;

        /* Skip white space. */
        while (c != EOF && c != '\n' && isspace(c))
            c = getc(fp);
        if (c == EOF) break;
        if (c == '\n') continue;

        /* Read the auth protocol name, and see if it matches any we
         * know about. */
        i = 0;
        while (c != EOF && c != '\n' && !isspace(c)) {
            if (i < lenof(protoname)-1) protoname[i++] = c;
            c = getc(fp);
        }
        protoname[i] = '\0';

        for (i = X11_NO_AUTH; ++i < X11_NAUTHS ;) {
            if (!strcmp(protoname, x11_authnames[i]))
                break;
        }
        if (i >= X11_NAUTHS || i <= proto) {
            /* Unrecognised protocol name, or a worse one than we already have.
	     * Skip this line. */
            while (c != EOF && c != '\n')
                c = getc(fp);
            if (c == EOF) break;
        }
        proto = i;

        /* Skip white space. */
        while (c != EOF && c != '\n' && isspace(c))
            c = getc(fp);
        if (c == EOF) break;
        if (c == '\n') continue;

        /*
         * Now grab pairs of hex digits and shove them into `data'.
         */
        i = 0;
        hexdigit = -1;
        while (c != EOF && c != '\n') {
            int hexval = -1;
            if (c >= 'A' && c <= 'F')
                hexval = c + 10 - 'A';
            if (c >= 'a' && c <= 'f')
                hexval = c + 10 - 'a';
            if (c >= '0' && c <= '9')
                hexval = c - '0';
            if (hexval >= 0) {
                if (hexdigit >= 0) {
                    hexdigit = (hexdigit << 4) + hexval;
                    if (i < maxsize)
                        localbuf[i++] = hexdigit;
                    hexdigit = -1;
                } else
                    hexdigit = hexval;
            }
            c = getc(fp);
        }

        *datalen = i;
        *protocol = proto;
	memcpy(data, localbuf, i);

	/* Nonetheless, continue looping round; we might find a better one. */
    }
    pclose(fp);
    sfree(localbuf);
}