tags 719979 + upstream
# regression
severity 719979 important
quit

Hi Guillem,

Guillem Jover wrote:

> Just noticed that git-daemon does not log the "Connection" lines any
> longer after the upgrade from squeeze to wheezy that I did some months
> ago, which makes the rest of the logging a bit useless.
>
> I run git-daemon from inetutils-inetd, but I've not tested it as a
> standalone server so I'm not sure if this might work there. I took a
> look at the git history and see f9c87be6b42dd0f8b31a4bb8c6a44326879fdd1a
> “daemon: get remote host address from root-process” as a possible
> suspect.

Yeah, this is broken.  The change you mention made git daemon rely on
the $REMOTE_ADDR envvar for logging in both --inetd mode and the
internal --serve mode.  In --serve mode the parent process populates
$REMOTE_ADDR using the address from listen().  That was supposed to
work around getpeername(), which was previously used, not being
available on Windows, by passing the address from the parent and it
works fine.

The change in the --inetd case was not intentional.  In --inetd mode
$REMOTE_ADDR is not being set, breaking logging (and breaking hooks
that might rely on REMOTE_ADDR).

How about something like this (untested)?

Signed-off-by: Jonathan Nieder <jrnie...@gmail.com>

diff --git i/daemon.c w/daemon.c
index 34916c5e..f975c680 100644
--- i/daemon.c
+++ w/daemon.c
@@ -669,6 +669,37 @@ static int addrcmp(const struct sockaddr_storage *s1,
        return 0;
 }
 
+static void addr_to_host_port(struct sockaddr *addr,
+                                       char *addrbuf, int addrbuflen,
+                                       char *portbuf, int portbuflen)
+{
+       assert(addrbuflen > 12);
+       strcpy(addrbuf, "REMOTE_ADDR=");
+
+       if (addr->sa_family == AF_INET) {
+               struct sockaddr_in *sin_addr = (void *) addr;
+               inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,
+                   addrbuflen - 12);
+               snprintf(portbuf, portbuflen, "REMOTE_PORT=%d",
+                   ntohs(sin_addr->sin_port));
+#ifndef NO_IPV6
+       } else if (addr->sa_family == AF_INET6) {
+               struct sockaddr_in6 *sin6_addr = (void *) addr;
+
+               char *buf = addrbuf + 12;
+               *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
+               inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,
+                   addrbuflen - 13);
+               strcat(buf, "]");
+
+               snprintf(portbuf, portbuflen, "REMOTE_PORT=%d",
+                   ntohs(sin6_addr->sin6_port));
+#endif
+       } else {
+               die("unexpected address family %d", (int) addr->sa_family);
+       }
+}
+
 static int max_connections = 32;
 
 static unsigned int live_children;
@@ -739,7 +770,7 @@ static char **cld_argv;
 static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
 {
        struct child_process cld = { NULL };
-       char addrbuf[300] = "REMOTE_ADDR=", portbuf[300];
+       char addrbuf[300], portbuf[300];
        char *env[] = { addrbuf, portbuf, NULL };
 
        if (max_connections && live_children >= max_connections) {
@@ -753,26 +784,8 @@ static void handle(int incoming, struct sockaddr *addr, 
socklen_t addrlen)
                }
        }
 
-       if (addr->sa_family == AF_INET) {
-               struct sockaddr_in *sin_addr = (void *) addr;
-               inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,
-                   sizeof(addrbuf) - 12);
-               snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
-                   ntohs(sin_addr->sin_port));
-#ifndef NO_IPV6
-       } else if (addr->sa_family == AF_INET6) {
-               struct sockaddr_in6 *sin6_addr = (void *) addr;
-
-               char *buf = addrbuf + 12;
-               *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
-               inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,
-                   sizeof(addrbuf) - 13);
-               strcat(buf, "]");
-
-               snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
-                   ntohs(sin6_addr->sin6_port));
-#endif
-       }
+       addr_to_host_port(addr, addrbuf, sizeof(addrbuf),
+                                       portbuf, sizeof(portbuf));
 
        cld.env = (const char **)env;
        cld.argv = (const char **)cld_argv;
@@ -1047,6 +1060,29 @@ static int service_loop(struct socketlist *socklist)
        }
 }
 
+#ifdef NO_GETPEERNAME
+static void get_remote_addr(void)
+{
+       /* nothing */
+}
+#else
+static void get_remote_addr(void)
+{
+       char hostenv[300], portenv[300];
+       struct sockaddr_storage ss;
+       struct sockaddr *peer = (struct sockaddr *)&ss;
+       socklen_t slen = sizeof(ss);
+
+       if (getpeername(0, peer, &slen))
+                 return;
+       addr_to_host_port(peer,
+                               hostenv, sizeof(hostenv),
+                               portenv, sizeof(portenv));
+       if (putenv(xstrdup(hostenv)) || putenv(xstrdup(portenv)))
+               die_errno("cannot put REMOTE_ADDR and REMOTE_PORT in 
environment");
+}
+#endif
+
 #ifdef NO_POSIX_GOODIES
 
 struct credentials;
@@ -1330,8 +1366,11 @@ int main(int argc, char **argv)
                        die_errno("failed to redirect stderr to /dev/null");
        }
 
-       if (inetd_mode || serve_mode)
+       if (inetd_mode || serve_mode) {
+               if (!getenv("REMOTE_ADDR"))
+                       get_remote_addr();
                return execute();
+       }
 
        if (detach)
                daemonize();


--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to