1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 09:58:01 +00:00

Overhaul of client-side XDM-AUTHORIZATION-1:

* Make sk_getxdmdata() return an arbitrary string rather than two integers.
  This better matches the spec, even if the current version always returns
  six bytes
* On Unix, for PF_UNIX sockets, return a counter rather than a constant along
  with the PID.  This should allow multiple clients to connect within one
  second, and is what Xlib does.
* On Unix, interpret AF_INET6 addresses like Xlib does, returning the
  embedded IPv4 address for v4-mapped addresses, and six bytes of zeroes
  otherwise.  The latter is silly, but if I'm going to do anything more sane
  I need to check that X servers won't reject it.

[originally from svn r5219]
This commit is contained in:
Ben Harris 2005-01-28 11:39:45 +00:00
parent 5e35aa383a
commit 865fbaa8ce
5 changed files with 62 additions and 29 deletions

View File

@ -48,9 +48,9 @@ struct FontSpec {
/* /*
* sk_getxdmdata() does not exist under the Mac (SGT: I have no * sk_getxdmdata() does not exist under the Mac (SGT: I have no
* idea whatsoever how to write it, and furthermore I'm unconvinced * idea whatsoever how to write it, and furthermore I'm unconvinced
* it's necessary), so it's a macro which always returns FALSE. * it's necessary), so it's a macro which always returns NULL.
*/ */
#define sk_getxdmdata(socket, ip, port) (0) #define sk_getxdmdata(socket, lenp) (NULL)
/* To make it compile */ /* To make it compile */

View File

@ -126,7 +126,7 @@ int init_ucs(struct unicode_data *ucsdata, char *line_codepage,
/* /*
* Spare function exported directly from uxnet.c. * Spare function exported directly from uxnet.c.
*/ */
int sk_getxdmdata(void *sock, unsigned long *ip, int *port); void *sk_getxdmdata(void *sock, int *lenp);
/* /*
* General helpful Unix stuff: more helpful version of the FD_SET * General helpful Unix stuff: more helpful version of the FD_SET

View File

@ -811,42 +811,73 @@ static void sk_tcp_close(Socket sock)
sfree(s); sfree(s);
} }
int sk_getxdmdata(void *sock, unsigned long *ip, int *port) #define PUT_32BIT_MSB_FIRST(cp, value) ( \
(cp)[0] = (char)((value) >> 24), \
(cp)[1] = (char)((value) >> 16), \
(cp)[2] = (char)((value) >> 8), \
(cp)[3] = (char)(value) )
#define PUT_16BIT_MSB_FIRST(cp, value) ( \
(cp)[0] = (char)((value) >> 8), \
(cp)[1] = (char)(value) )
void *sk_getxdmdata(void *sock, int *lenp)
{ {
Actual_Socket s = (Actual_Socket) sock; Actual_Socket s = (Actual_Socket) sock;
#ifdef NO_IPV6
struct sockaddr_in addr; struct sockaddr_in addr;
#else
struct sockaddr_storage addr;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
#endif
struct sockaddr *sa = (struct sockaddr *)&addr;
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
socklen_t addrlen; socklen_t addrlen;
char *buf;
static unsigned int unix_addr = 0xFFFFFFFF;
/* /*
* We must check that this socket really _is_ an Actual_Socket. * We must check that this socket really _is_ an Actual_Socket.
*/ */
if (s->fn != &tcp_fn_table) if (s->fn != &tcp_fn_table)
return 0; /* failure */ return NULL; /* failure */
addrlen = sizeof(addr); addrlen = sizeof(addr);
if (getsockname(s->s, (struct sockaddr *)&addr, &addrlen) < 0) if (getsockname(s->s, sa, &addrlen) < 0)
return 0; return NULL;
switch(addr.sin_family) { switch(sa->sa_family) {
case AF_INET: case AF_INET:
*ip = ntohl(addr.sin_addr.s_addr); *lenp = 6;
*port = ntohs(addr.sin_port); buf = snewn(*lenp, char);
PUT_32BIT_MSB_FIRST(buf, ntohl(sin->sin_addr.s_addr));
PUT_16BIT_MSB_FIRST(buf+4, ntohs(sin->sin_port));
break; break;
#ifndef NO_IPV6
case AF_INET6:
*lenp = 6;
buf = snewn(*lenp, char);
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
memcpy(buf, sin6->sin6_addr.s6_addr + 12, 4);
PUT_16BIT_MSB_FIRST(buf+4, ntohs(sin6->sin6_port));
} else
/* This is stupid, but it's what XLib does. */
memset(buf, 0, 6);
break;
#endif
case AF_UNIX: case AF_UNIX:
/* *lenp = 6;
* For a Unix socket, we return 0xFFFFFFFF for the IP address and buf = snewn(*lenp, char);
* our current pid for the port. Bizarre, but such is life. PUT_32BIT_MSB_FIRST(buf, unix_addr--);
*/ PUT_16BIT_MSB_FIRST(buf+4, getpid());
*ip = ntohl(0xFFFFFFFF);
*port = getpid();
break; break;
/* XXX IPV6 */ /* XXX IPV6 */
default: default:
return 0; return NULL;
} }
return 1; return buf;
} }
/* /*

View File

@ -117,11 +117,11 @@ GLOBAL void *logctx;
/* /*
* sk_getxdmdata() does not exist under Windows (not that I * sk_getxdmdata() does not exist under Windows (not that I
* couldn't write it if I wanted to, but I haven't bothered), so * couldn't write it if I wanted to, but I haven't bothered), so
* it's a macro which always returns FALSE. With any luck this will * it's a macro which always returns NULL. With any luck this will
* cause the compiler to notice it can optimise away the * cause the compiler to notice it can optimise away the
* implementation of XDM-AUTHORIZATION-1 in x11fwd.c :-) * implementation of XDM-AUTHORIZATION-1 in x11fwd.c :-)
*/ */
#define sk_getxdmdata(socket, ip, port) (0) #define sk_getxdmdata(socket, lenp) (NULL)
/* /*
* File-selector filter strings used in the config box. On Windows, * File-selector filter strings used in the config box. On Windows,

View File

@ -481,9 +481,9 @@ int x11_send(Socket s, char *data, int len)
char realauthdata[64]; char realauthdata[64];
int realauthlen = 0; int realauthlen = 0;
int authstrlen = strlen(x11_authnames[pr->auth->realproto]); int authstrlen = strlen(x11_authnames[pr->auth->realproto]);
unsigned long ip; int buflen;
int port;
static const char zeroes[4] = { 0,0,0,0 }; static const char zeroes[4] = { 0,0,0,0 };
void *buf;
if (pr->auth->realproto == X11_MIT) { if (pr->auth->realproto == X11_MIT) {
assert(pr->auth->reallen <= lenof(realauthdata)); assert(pr->auth->reallen <= lenof(realauthdata));
@ -491,17 +491,19 @@ int x11_send(Socket s, char *data, int len)
memcpy(realauthdata, pr->auth->realdata, realauthlen); memcpy(realauthdata, pr->auth->realdata, realauthlen);
} else if (pr->auth->realproto == X11_XDM && } else if (pr->auth->realproto == X11_XDM &&
pr->auth->reallen == 16 && pr->auth->reallen == 16 &&
sk_getxdmdata(s, &ip, &port)) { (buf = sk_getxdmdata(s, &buflen))) {
time_t t; time_t t;
realauthlen = 24; realauthlen = (buflen+12+7) & ~7;
memset(realauthdata, 0, 24); assert(realauthlen <= lenof(realauthdata));
memset(realauthdata, 0, realauthlen);
memcpy(realauthdata, pr->auth->realdata, 8); memcpy(realauthdata, pr->auth->realdata, 8);
PUT_32BIT_MSB_FIRST(realauthdata+8, ip); memcpy(realauthdata+8, buf, buflen);
PUT_16BIT_MSB_FIRST(realauthdata+12, port);
t = time(NULL); t = time(NULL);
PUT_32BIT_MSB_FIRST(realauthdata+14, t); PUT_32BIT_MSB_FIRST(realauthdata+8+buflen, t);
des_encrypt_xdmauth(pr->auth->realdata+9, des_encrypt_xdmauth(pr->auth->realdata+9,
(unsigned char *)realauthdata, 24); (unsigned char *)realauthdata,
realauthlen);
sfree(buf);
} }
/* implement other auth methods here if required */ /* implement other auth methods here if required */