123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /*
- * ux_x11.c: fetch local auth data for X forwarding.
- */
- #include <ctype.h>
- #include <unistd.h>
- #include <assert.h>
- #include "putty.h"
- #include "ssh.h"
- 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);
- }
|