chiark / gitweb /
linux.c, yaid.c: Correct policy application for proxied queries.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 21 Oct 2012 14:52:25 +0000 (15:52 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 24 Oct 2012 09:24:32 +0000 (10:24 +0100)
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
yaid.c

diff --git a/linux.c b/linux.c
index d7d8475e63e3b45ad9887eee5b7974edce304d9f..2c9a1d7d7c21cdd039ccd2500dccb8a4ed51b8e9 100644 (file)
--- 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 601aa5187451fee8872c6b67b51076bbcf4417d6..a99604f4a139b14fde94079f66b0d5dd2ff0d77a 100644 (file)
--- 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,