Re: idea to block some scanners

2014-06-30 Thread Leclerc, Sebastien
> De : mxb [mailto:m...@alumni.chalmers.se], 30 juin 2014 03:26
> Could you please, post updated version to the list?

Sure!

--- /dev/null   Mon Jun 30 07:57:57 2014
+++ tarpitd.c   Fri Jun 27 14:01:35 2014
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 2014 Sebastien Leclerc. All rights reserved.
+ * Copyright (c) 2002-2007 Bob Beck. All rights reserved.
+ * Copyright (c) 2002 Theo de Raadt. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+struct con {
+   int fd;
+   int af;
+   struct sockaddr_storage ss;
+   void *ia;
+   char addr[32];
+   char caddr[32];
+   char cport[6];
+   time_t r;
+   time_t s;
+   char ibuf[8192];
+   char *ip;
+   int il;
+} *con;
+
+void usage(void);
+void initcon(struct con *, int, struct sockaddr *);
+void closecon(struct con *);
+void handler(struct con *);
+void getcaddr(struct con *);
+int  blockhost(char *);
+int  blocklistener(void);
+
+struct syslog_data sdata = SYSLOG_DATA_INIT;
+struct passwd *pw;
+
+time_t t;
+
+#define MAXCON 800
+int maxfiles;
+int maxcon = MAXCON;
+int clients;
+int debug;
+int window = 0;
+int autoblock = 1;
+int pipel[2] = { -1, -1 };
+pid_t pidl = -1;
+#define MAXIDLETIME 30
+#define MAXTIME 120
+#define PATH_PFCTL "/sbin/pfctl"
+
+void
+usage(void)
+{
+   extern char *__progname;
+
+   fprintf(stderr,
+   "usage: %s [-d] [-c maxcon] [-l address] "
+   "[-p port] [-w window]\n",
+   __progname);
+
+   exit(1);
+}
+
+int
+blockhost(char *ip)
+{
+   switch(fork()) {
+   case -1:
+   syslog_r(LOG_WARNING, &sdata, "child cannot fork (%m)");
+   return (-1);
+   case 0:
+   /* child */
+   if (-1 == execl(PATH_PFCTL, "pfctl", "-q", "-t", "badguys", 
"-T", "add", ip, NULL)) {
+   syslog_r(LOG_WARNING, &sdata, "cannot exec pfctl (%m)");
+   return (-2);
+   }
+   }
+
+   /* parent */
+   return (0);
+}
+
+int blocklistener(void)
+{
+   int ret = 0;
+   ssize_t len;
+   size_t lsize = 0;
+   char *buf = NULL;
+   FILE *pf;
+
+   fcntl(pipel[0], F_SETFD, FD_CLOEXEC);
+
+   pf = fdopen(pipel[0], "r");
+   if (pf == NULL) {
+   syslog_r(LOG_WARNING, &sdata, "cannot open pipe (%m)");
+   close(pipel[0]);
+   return(-1);
+   }
+
+   while (-1 != (len = getline(&buf, &lsize, pf))) {
+   buf[len - 1] = '\0';
+   blockhost(buf);
+   memset(buf, 0, sizeof buf);
+   }
+
+   if (ferror(pf)) {
+   syslog_r(LOG_ERR, &sdata, "child listener aborted (%m)");
+   ret = 2;
+   }
+   else if (feof(pf)) {
+   syslog_r(LOG_INFO, &sdata, "child listener terminated 
normally.");
+   }
+
+   fclose(pf);
+   return(ret);
+}
+
+void
+getcaddr(struct con *cp)
+{
+   struct sockaddr_storage spamd_end;
+   struct sockaddr *sep = (struct sockaddr *) &spamd_end;
+   socklen_t len = sizeof(struct sockaddr_storage);
+   int error;
+
+   cp->caddr[0] = '\0';
+   cp->cport[0] = '\0';
+   if (getsockname(cp->fd, sep, &len) == -1)
+   return;
+   error = getnameinfo(sep, sep->sa_len, cp->caddr, sizeof(cp->caddr),
+   cp->cport, sizeof(cp->cport), NI_NUMERICHOST | NI_NUMERICSERV);
+   if (error) {
+   syslog_r(LOG_WARNING, &sdata, "cannot get original destination 
address.");
+   cp->caddr[0] = '\0';
+   cp->cport[0] = '\0';
+   }
+}
+
+void
+initcon(struct con *cp, int fd, struct sockaddr *sa)
+{
+   socklen_t len = sa->sa_len;
+   time_t tt;
+   int error;
+
+   time(&tt);
+   bzero(cp, sizeof(struct con));
+   cp->fd = fd;
+   if (len > sizeof(cp->ss))
+   errx(1, "sockaddr size");
+   if (sa->sa_family != AF_INET)
+   errx(1, "not supported yet");
+   memcpy(&cp->ss, sa, sa->sa_len)

Re: idea to block some scanners

2014-06-30 Thread mxb

Could you please, post updated version to the list?

//mxb

On 27 jun 2014, at 20:09, Leclerc, Sebastien 
 wrote:

>> Stuart Henderson , 2014-06-27 11:00 
>> 
>>> +/* Stolen from ftp-proxy */
>> 
>> Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several
>> releases, it has switched to the much easier-to-use divert-to / 
>> getsockname().
> 
> And also :
> 
>> Henning Brauer , 2014-06-27 14:07
>> no
>> 
>> DIOCNATLOOK is stupid. I'll celebrate the day when I can kill it.
>> Please look at less ancient ftp-proxy/*-proxy code for inspiration.
> 
> Way simpler, indeed!
> Thank you
> 
> 
> --- tarpitd.c.bak   Fri Jun 27 13:25:06 2014
> +++ tarpitd.c   Fri Jun 27 14:01:35 2014
> @@ -56,21 +56,11 @@ struct con {
>int il;
> } *con;
> 
> -/* From netinet/in.h, but only _KERNEL_ gets them. */
> -#define satosin(sa)((struct sockaddr_in *)(sa))
> -#define satosin6(sa)   ((struct sockaddr_in6 *)(sa))
> -int server_lookup4(struct sockaddr_in *, struct sockaddr_in *,
> -struct sockaddr_in *);
> -int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *,
> -struct sockaddr_in6 *);
> -
> void usage(void);
> void initcon(struct con *, int, struct sockaddr *);
> void closecon(struct con *);
> void handler(struct con *);
> void getcaddr(struct con *);
> -int  server_lookup(struct sockaddr *, struct sockaddr *,
> -struct sockaddr *);
> int  blockhost(char *);
> int  blocklistener(void);
> 
> @@ -84,7 +74,6 @@ int maxfiles;
> int maxcon = MAXCON;
> int clients;
> int debug;
> -int pfdev;
> int window = 0;
> int autoblock = 1;
> int pipel[2] = { -1, -1 };
> @@ -160,90 +149,11 @@ int blocklistener(void)
>return(ret);
> }
> 
> -/* Stolen from ftp-proxy */
> -int
> -server_lookup(struct sockaddr *client, struct sockaddr *proxy,
> -struct sockaddr *server)
> -{
> -   if (client->sa_family == AF_INET)
> -   return (server_lookup4(satosin(client), satosin(proxy),
> -   satosin(server)));
> -
> -   if (client->sa_family == AF_INET6)
> -   return (server_lookup6(satosin6(client), satosin6(proxy),
> -   satosin6(server)));
> -
> -   errno = EPROTONOSUPPORT;
> -   return (-1);
> -}
> -
> -int
> -server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy,
> -struct sockaddr_in *server)
> -{
> -   struct pfioc_natlook pnl;
> -
> -   memset(&pnl, 0, sizeof pnl);
> -   pnl.direction = PF_OUT;
> -   pnl.af = AF_INET;
> -   pnl.proto = IPPROTO_TCP;
> -   memcpy(&pnl.saddr.v4, &client->sin_addr.s_addr, sizeof pnl.saddr.v4);
> -   memcpy(&pnl.daddr.v4, &proxy->sin_addr.s_addr, sizeof pnl.daddr.v4);
> -   pnl.sport = client->sin_port;
> -   pnl.dport = proxy->sin_port;
> -
> -   if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1)
> -   return (-1);
> -
> -   memset(server, 0, sizeof(struct sockaddr_in));
> -   server->sin_len = sizeof(struct sockaddr_in);
> -   server->sin_family = AF_INET;
> -   memcpy(&server->sin_addr.s_addr, &pnl.rdaddr.v4,
> -   sizeof server->sin_addr.s_addr);
> -   server->sin_port = pnl.rdport;
> -
> -   return (0);
> -}
> -
> -int
> -server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy,
> -struct sockaddr_in6 *server)
> -{
> -   struct pfioc_natlook pnl;
> -
> -   memset(&pnl, 0, sizeof pnl);
> -   pnl.direction = PF_OUT;
> -   pnl.af = AF_INET6;
> -   pnl.proto = IPPROTO_TCP;
> -   memcpy(&pnl.saddr.v6, &client->sin6_addr.s6_addr, sizeof 
> pnl.saddr.v6);
> -   memcpy(&pnl.daddr.v6, &proxy->sin6_addr.s6_addr, sizeof pnl.daddr.v6);
> -   pnl.sport = client->sin6_port;
> -   pnl.dport = proxy->sin6_port;
> -
> -   if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1)
> -   return (-1);
> -
> -   memset(server, 0, sizeof(struct sockaddr_in6));
> -   server->sin6_len = sizeof(struct sockaddr_in6);
> -   server->sin6_family = AF_INET6;
> -   memcpy(&server->sin6_addr.s6_addr, &pnl.rdaddr.v6,
> -   sizeof server->sin6_addr);
> -   server->sin6_port = pnl.rdport;
> -
> -   return (0);
> -}
> -
> -/*
> - * Get address client connected to, by doing a DIOCNATLOOK call.
> - * Uses server_lookup code from ftp-proxy.
> - */
> void
> getcaddr(struct con *cp)
> {
>struct sockaddr_storage spamd_end;
>struct sockaddr *sep = (struct sockaddr *) &spamd_end;
> -   struct sockaddr_storage original_destination;
> -   struct sockaddr *odp = (struct sockaddr *) &original_destination;
>socklen_t len = sizeof(struct sockaddr_storage);
>int error;
> 
> @@ -251,9 +161,7 @@ getcaddr(struct con *cp)
>cp->cport[0] = '\0';
>if (getsockname(cp->fd, sep, &len) == -1)
>return;
> -   if (server_lookup((struct sockaddr *)&cp->ss, sep, odp) != 0)
> -   return;
> 

Re: idea to block some scanners

2014-06-27 Thread Leclerc, Sebastien
> Stuart Henderson , 2014-06-27 11:00 
>
> > +/* Stolen from ftp-proxy */
> 
> Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several
> releases, it has switched to the much easier-to-use divert-to / getsockname().

And also :

> Henning Brauer , 2014-06-27 14:07
> no
> 
> DIOCNATLOOK is stupid. I'll celebrate the day when I can kill it.
> Please look at less ancient ftp-proxy/*-proxy code for inspiration.

Way simpler, indeed!
Thank you


--- tarpitd.c.bak   Fri Jun 27 13:25:06 2014
+++ tarpitd.c   Fri Jun 27 14:01:35 2014
@@ -56,21 +56,11 @@ struct con {
int il;
 } *con;

-/* From netinet/in.h, but only _KERNEL_ gets them. */
-#define satosin(sa)((struct sockaddr_in *)(sa))
-#define satosin6(sa)   ((struct sockaddr_in6 *)(sa))
-int server_lookup4(struct sockaddr_in *, struct sockaddr_in *,
-struct sockaddr_in *);
-int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *,
-struct sockaddr_in6 *);
-
 void usage(void);
 void initcon(struct con *, int, struct sockaddr *);
 void closecon(struct con *);
 void handler(struct con *);
 void getcaddr(struct con *);
-int  server_lookup(struct sockaddr *, struct sockaddr *,
-struct sockaddr *);
 int  blockhost(char *);
 int  blocklistener(void);

@@ -84,7 +74,6 @@ int maxfiles;
 int maxcon = MAXCON;
 int clients;
 int debug;
-int pfdev;
 int window = 0;
 int autoblock = 1;
 int pipel[2] = { -1, -1 };
@@ -160,90 +149,11 @@ int blocklistener(void)
return(ret);
 }

-/* Stolen from ftp-proxy */
-int
-server_lookup(struct sockaddr *client, struct sockaddr *proxy,
-struct sockaddr *server)
-{
-   if (client->sa_family == AF_INET)
-   return (server_lookup4(satosin(client), satosin(proxy),
-   satosin(server)));
-
-   if (client->sa_family == AF_INET6)
-   return (server_lookup6(satosin6(client), satosin6(proxy),
-   satosin6(server)));
-
-   errno = EPROTONOSUPPORT;
-   return (-1);
-}
-
-int
-server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy,
-struct sockaddr_in *server)
-{
-   struct pfioc_natlook pnl;
-
-   memset(&pnl, 0, sizeof pnl);
-   pnl.direction = PF_OUT;
-   pnl.af = AF_INET;
-   pnl.proto = IPPROTO_TCP;
-   memcpy(&pnl.saddr.v4, &client->sin_addr.s_addr, sizeof pnl.saddr.v4);
-   memcpy(&pnl.daddr.v4, &proxy->sin_addr.s_addr, sizeof pnl.daddr.v4);
-   pnl.sport = client->sin_port;
-   pnl.dport = proxy->sin_port;
-
-   if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1)
-   return (-1);
-
-   memset(server, 0, sizeof(struct sockaddr_in));
-   server->sin_len = sizeof(struct sockaddr_in);
-   server->sin_family = AF_INET;
-   memcpy(&server->sin_addr.s_addr, &pnl.rdaddr.v4,
-   sizeof server->sin_addr.s_addr);
-   server->sin_port = pnl.rdport;
-
-   return (0);
-}
-
-int
-server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy,
-struct sockaddr_in6 *server)
-{
-   struct pfioc_natlook pnl;
-
-   memset(&pnl, 0, sizeof pnl);
-   pnl.direction = PF_OUT;
-   pnl.af = AF_INET6;
-   pnl.proto = IPPROTO_TCP;
-   memcpy(&pnl.saddr.v6, &client->sin6_addr.s6_addr, sizeof pnl.saddr.v6);
-   memcpy(&pnl.daddr.v6, &proxy->sin6_addr.s6_addr, sizeof pnl.daddr.v6);
-   pnl.sport = client->sin6_port;
-   pnl.dport = proxy->sin6_port;
-
-   if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1)
-   return (-1);
-
-   memset(server, 0, sizeof(struct sockaddr_in6));
-   server->sin6_len = sizeof(struct sockaddr_in6);
-   server->sin6_family = AF_INET6;
-   memcpy(&server->sin6_addr.s6_addr, &pnl.rdaddr.v6,
-   sizeof server->sin6_addr);
-   server->sin6_port = pnl.rdport;
-
-   return (0);
-}
-
-/*
- * Get address client connected to, by doing a DIOCNATLOOK call.
- * Uses server_lookup code from ftp-proxy.
- */
 void
 getcaddr(struct con *cp)
 {
struct sockaddr_storage spamd_end;
struct sockaddr *sep = (struct sockaddr *) &spamd_end;
-   struct sockaddr_storage original_destination;
-   struct sockaddr *odp = (struct sockaddr *) &original_destination;
socklen_t len = sizeof(struct sockaddr_storage);
int error;

@@ -251,9 +161,7 @@ getcaddr(struct con *cp)
cp->cport[0] = '\0';
if (getsockname(cp->fd, sep, &len) == -1)
return;
-   if (server_lookup((struct sockaddr *)&cp->ss, sep, odp) != 0)
-   return;
-   error = getnameinfo(odp, odp->sa_len, cp->caddr, sizeof(cp->caddr),
+   error = getnameinfo(sep, sep->sa_len, cp->caddr, sizeof(cp->caddr),
cp->cport, sizeof(cp->cport), NI_NUMERICHOST | NI_NUMERICSERV);
if (error) {
syslog_r(LOG_WARNING, &sdata, "cannot get original destination 
address.");
@@ -489,12 +397,6 @@ main(int argc, char *

Re: idea to block some scanners

2014-06-27 Thread Henning Brauer
* Leclerc, Sebastien  [2014-06-27 16:40]:
> +   if (ioctl(pfdev, DIOCNATLOOK, &pnl) == -1)

no

DIOCNATLOOK is stupid. I'll celebrate the day when I can kill it.
Please look at less ancient ftp-proxy/*-proxy code for inspiration.

-- 
Henning Brauer, h...@bsws.de, henn...@openbsd.org
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/



Re: idea to block some scanners

2014-06-27 Thread Leclerc, Sebastien
> DeĀ : Stuart Henderson [mailto:st...@openbsd.org]
> 
> On 2014/06/27 09:58, Leclerc, Sebastien wrote:
> > Hi,
> >
> > Would this piece of code be useful to someone else than me?
> 
> Not sure about base, but it may make sense to add to ports.

I'm not familiar with the creation of a port, but I'm willing to learn it when 
I'll have some spare time.

> 
> > +/* Stolen from ftp-proxy */
> 
> Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several
> releases, it has switched to the much easier-to-use divert-to / getsockname().


You're right, it is from spamd(8) source code, and the comment was copied 
verbatim.



Re: idea to block some scanners

2014-06-27 Thread Stuart Henderson
On 2014/06/27 09:58, Leclerc, Sebastien wrote:
> Hi,
> 
> Would this piece of code be useful to someone else than me?

Not sure about base, but it may make sense to add to ports.

> +/* Stolen from ftp-proxy */

Old version of ftp-proxy I guess. It hasn't used DIOCNATLOOK for several
releases, it has switched to the much easier-to-use divert-to / getsockname().



idea to block some scanners

2014-06-27 Thread Leclerc, Sebastien
Hi,

Would this piece of code be useful to someone else than me?

It works with pf's divert-to to block some scanners. It's basically a
stripped-down spamd(8), that listens to every TCP connection that is
diverted to it, and sends the received data to the great bitbucket in
the sky, one byte per second. It also adds the client's IP to a pf table,
which can be used to block future connections from the same host.

I'm a sysadmin, not a programmer, so comments are welcome!

Sebastien Leclerc

--- /dev/null   Fri Jun 27 09:37:50 2014
+++ tarpitd.c   Wed Jun 18 15:29:48 2014
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2014 Sebastien Leclerc. All rights reserved.
+ * Copyright (c) 2002-2007 Bob Beck. All rights reserved.
+ * Copyright (c) 2002 Theo de Raadt. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+struct con {
+   int fd;
+   int af;
+   struct sockaddr_storage ss;
+   void *ia;
+   char addr[32];
+   char caddr[32];
+   char cport[6];
+   time_t r;
+   time_t s;
+   char ibuf[8192];
+   char *ip;
+   int il;
+} *con;
+
+/* From netinet/in.h, but only _KERNEL_ gets them. */
+#define satosin(sa)((struct sockaddr_in *)(sa))
+#define satosin6(sa)   ((struct sockaddr_in6 *)(sa))
+int server_lookup4(struct sockaddr_in *, struct sockaddr_in *,
+struct sockaddr_in *);
+int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *,
+struct sockaddr_in6 *);
+
+void usage(void);
+void initcon(struct con *, int, struct sockaddr *);
+void closecon(struct con *);
+void handler(struct con *);
+void getcaddr(struct con *);
+int  server_lookup(struct sockaddr *, struct sockaddr *,
+struct sockaddr *);
+int  blockhost(char *);
+int  blocklistener(void);
+
+struct syslog_data sdata = SYSLOG_DATA_INIT;
+struct passwd *pw;
+
+time_t t;
+
+#define MAXCON 800
+int maxfiles;
+int maxcon = MAXCON;
+int clients;
+int debug;
+int pfdev;
+int window = 0;
+int autoblock = 1;
+int pipel[2] = { -1, -1 };
+pid_t pidl = -1;
+#define MAXIDLETIME 30
+#define MAXTIME 120
+#define PATH_PFCTL "/sbin/pfctl"
+
+void
+usage(void)
+{
+   extern char *__progname;
+
+   fprintf(stderr,
+   "usage: %s [-d] [-c maxcon] [-l address] "
+   "[-p port] [-w window]\n",
+   __progname);
+
+   exit(1);
+}
+
+int
+blockhost(char *ip)
+{
+   switch(fork()) {
+   case -1:
+   syslog_r(LOG_WARNING, &sdata, "child cannot fork (%m)");
+   return (-1);
+   case 0:
+   /* child */
+   if (-1 == execl(PATH_PFCTL, "pfctl", "-q", "-t", "badguys", 
"-T", "add", ip, NULL)) {
+   syslog_r(LOG_WARNING, &sdata, "cannot exec pfctl (%m)");
+   return (-2);
+   }
+   }
+
+   /* parent */
+   return (0);
+}
+
+int blocklistener(void)
+{
+   int ret = 0;
+   ssize_t len;
+   size_t lsize = 0;
+   char *buf = NULL;
+   FILE *pf;
+
+   fcntl(pipel[0], F_SETFD, FD_CLOEXEC);
+
+   pf = fdopen(pipel[0], "r");
+   if (pf == NULL) {
+   syslog_r(LOG_WARNING, &sdata, "cannot open pipe (%m)");
+   close(pipel[0]);
+   return(-1);
+   }
+
+   while (-1 != (len = getline(&buf, &lsize, pf))) {
+   buf[len - 1] = '\0';
+   blockhost(buf);
+   memset(buf, 0, sizeof buf);
+   }
+
+   if (ferror(pf)) {
+   syslog_r(LOG_ERR, &sdata, "child listener aborted (%m)");
+   ret = 2;
+   }
+   else if (feof(pf)) {
+   syslog_r(LOG_INFO, &sdata, "child listener terminated 
normally.");
+   }
+
+   fclose(pf);
+   return(ret);
+}
+
+/* Stolen from ftp-proxy */
+int
+server_lookup(struct sockaddr *client, struct sockaddr *proxy,
+struct sockaddr *server)
+{
+   if (client->sa_family == AF_INET)
+   return (server_lookup4(satosin(client), satosin(proxy),
+   satosin(server)));
+
+   if (clien