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:
parent
5e35aa383a
commit
865fbaa8ce
@ -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 */
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
61
unix/uxnet.c
61
unix/uxnet.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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,
|
||||||
|
20
x11fwd.c
20
x11fwd.c
@ -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 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user