summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2011-06-17 13:43:38 -0400
committerAdam Jackson <ajax@redhat.com>2012-01-06 13:29:53 -0500
commit78fa121f4097d29458e5453c13473595df06e26e (patch)
treefa00c3b07a69c0c2e246b7dd00034eb865d957d8
parent49d38b75c8f3276cfce33ffe6b8c4fbeb1081b96 (diff)
dix: Extend initial connection handshake for forwarding proxies
Forwarding proxies like sshd will appear to be local, even though they aren't really. This leads to weird behaviour for extensions that truly require running under the same OS services as the client, like MIT-SHM and DRI2. Add two new legal values for the initial connection's byteOrder field, 'r' and 'R'. These act like 'l' and 'B' respectively, but have the side effect of forcing the client to be treated as non-local. Forwarding proxies should attempt to munge the first packet of the connection accordingly; older servers will reject connections thusly munged, so the proxy should fall back to passthrough if the munged connection attempt fails. Reviewed-by: Daniel Stone <daniel@fooishbar.org> Signed-off-by: Adam Jackson <ajax@redhat.com>
-rw-r--r--dix/dispatch.c12
-rw-r--r--os/connection.c10
2 files changed, 14 insertions, 8 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 048dff652..554462328 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3578,12 +3578,14 @@ ProcInitialConnection(ClientPtr client)
REQUEST(xReq);
xConnClientPrefix *prefix;
int whichbyte = 1;
+ char order;
prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
- if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ order = prefix->byteOrder;
+ if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
return client->noClientException = -1;
- if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
- (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+ if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r')))
{
client->swapped = TRUE;
SwapConnClientPrefix(prefix);
@@ -3595,6 +3597,10 @@ ProcInitialConnection(ClientPtr client)
{
swaps(&stuff->length);
}
+ if (order == 'r' || order == 'R')
+ {
+ client->local = FALSE;
+ }
ResetCurrentRequest(client);
return Success;
}
diff --git a/os/connection.c b/os/connection.c
index 575cfb80f..f25106bd7 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -880,7 +880,7 @@ ErrorConnMax(XtransConnInfo trans_conn)
xConnSetupPrefix csp;
char pad[3];
struct iovec iov[3];
- char byteOrder = 0;
+ char order = 0;
int whichbyte = 1;
struct timeval waittime;
fd_set mask;
@@ -893,16 +893,16 @@ ErrorConnMax(XtransConnInfo trans_conn)
FD_SET(fd, &mask);
(void)Select(fd + 1, &mask, NULL, NULL, &waittime);
/* try to read the byte-order of the connection */
- (void)_XSERVTransRead(trans_conn, &byteOrder, 1);
- if ((byteOrder == 'l') || (byteOrder == 'B'))
+ (void)_XSERVTransRead(trans_conn, &order, 1);
+ if (order == 'l' || order == 'B' || order == 'r' || order == 'R')
{
csp.success = xFalse;
csp.lengthReason = sizeof(NOROOM) - 1;
csp.length = (sizeof(NOROOM) + 2) >> 2;
csp.majorVersion = X_PROTOCOL;
csp.minorVersion = X_PROTOCOL_REVISION;
- if (((*(char *) &whichbyte) && (byteOrder == 'B')) ||
- (!(*(char *) &whichbyte) && (byteOrder == 'l')))
+ if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r')))
{
swaps(&csp.majorVersion);
swaps(&csp.minorVersion);