From 223e3e2be7a30ab58804b9b741c9438b123a16fd Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 21 Oct 2012 15:52:25 +0100 Subject: [PATCH] linux.c, yaid.c: Correct policy application for proxied queries. The apparent remote address for a proxy connection is the gateway, but in fact the information is going to some remote server. Therefore, once we've identified a proxy connection, overwrite the remote address in the query with the true remote host. This means fixing up the query structure with the gateway address next time, so keep track of the connection remote address and restore it on each query. --- linux.c | 12 +++++++----- yaid.c | 4 +++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/linux.c b/linux.c index d7d8475..2c9a1d7 100644 --- a/linux.c +++ b/linux.c @@ -296,21 +296,23 @@ void identify(struct query *q) * query is our gateway then don't check the remote address in the * field (but do check the port number). */ - if (q->ao->sys->parseaddr(&p, &s[0].addr)) goto next_row; + if (q->ao->sys->parseaddr(&p, &s[i].addr)) goto next_row; if (*p != ':') break; p++; - s[0].port = strtoul(p, 0, 16); + s[i].port = strtoul(p, 0, 16); if ((i == R && gwp) ? - q->s[R].port != s[0].port : - !sockeq(q->ao, &q->s[i], &s[0])) + q->s[R].port != s[i].port : + !sockeq(q->ao, &q->s[i], &s[i])) goto next_row; } /* We got to the end, and everything matched. If we found a UID then - * we're done. + * we're done. If the apparent remote address is our gateway then copy + * the true one into the query structure. */ if (uid != -1) { q->resp = R_UID; q->u.uid = uid; + if (gwp) q->s[R].addr = s[i].addr; goto done; } next_row:; diff --git a/yaid.c b/yaid.c index 601aa51..a99604f 100644 --- a/yaid.c +++ b/yaid.c @@ -55,6 +55,7 @@ struct listen { struct client { int fd; /* The connection to the client */ selbuf b; /* Accumulate lines of input */ + union addr raddr; /* Remote address */ struct query q; /* The clients query and our reply */ struct sel_timer t; /* Timeout for idle or doomed conn */ struct listen *l; /* Back to the listener (and ops) */ @@ -656,6 +657,7 @@ static void client_line(char *line, size_t len, void *p) skipws(&q); if (*q) goto bad; /* Identify the connection. Act on the result. */ + c->q.s[R].addr = c->raddr; identify(&c->q); switch (c->q.resp) { @@ -822,7 +824,7 @@ static void accept_client(int fd, unsigned mode, void *p) c->q.ao = l->ao; /* Collect the local and remote addresses. */ - l->ao->sockaddr_to_addr(&ssr, &c->q.s[R].addr); + l->ao->sockaddr_to_addr(&ssr, &c->raddr); ssz = sizeof(ssl); if (getsockname(sk, (struct sockaddr *)&ssl, &ssz)) { logmsg(0, LOG_ERR, -- 2.11.0