Hi,

This diff replaces a system(3) call to insert an address into a pf
table with ioctl(DIOCADDADDRS) which allows removal of "proc exec"
from the pledge promises. Updated patch-sshlockout.c follows.

Please share suggestions/feedback.

Index: sshlockout.c
--- sshlockout.c.orig
+++ sshlockout.c
@@ -49,7 +49,14 @@
  */
 
 #include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
 #include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -81,11 +88,13 @@ struct args {
 #define MAXHIST                100
 #define SSHLIMIT       5               /* per hour */
 #define MAX_TABLE_NAME 20              /* PF table name limit */
+#define PF_DEVICE      "/dev/pf"
 
 static iphist_t *hist_base;
 static iphist_t **hist_tail = &hist_base;
 static iphist_t *hist_hash[HSIZE];
 static int hist_count = 0;
+static int dev;
 
 static struct args args;
 
@@ -97,6 +106,8 @@ static void delete_iph(iphist_t *ip);
 static
 void
 block_ip(const char *ips) {
+       struct pfioc_table io;
+       struct pfr_addr addr;
        char buf[128];
        int r = 0;
 
@@ -113,7 +124,27 @@ block_ip(const char *ips) {
        }
 
        if (r > 0 && (int)strlen(buf) == r) {
-               system(buf);
+               memset(&io, 0, sizeof(io));
+               strlcpy(io.pfrio_table.pfrt_name, args.arg1,
+                   sizeof(io.pfrio_table.pfrt_name));
+               io.pfrio_esize = sizeof(addr);
+               io.pfrio_buffer = &addr;
+               io.pfrio_size = 1;
+
+               memset(&addr, 0, sizeof(addr));
+               if (inet_pton(AF_INET, ips, &addr.pfra_ip4addr) == 1) {
+                       addr.pfra_af = AF_INET;
+                       addr.pfra_net = 32;
+               } else if (inet_pton(AF_INET6, ips, &addr.pfra_ip6addr) == 1) {
+                       addr.pfra_af = AF_INET6;
+                       addr.pfra_net = 128;
+               } else {
+                       syslog(LOG_ERR, "sshlockout: invalid ip: %s", ips);
+                       return;
+               }
+
+               if (ioctl(dev, DIOCRADDADDRS, &io) == -1)
+                       syslog(LOG_ERR, "sshlockout: ioctl(DIOCRADDADDRS): %m");
        }
        else {
                syslog(LOG_ERR, "sshlockout: invalid command");
@@ -198,6 +229,16 @@ main(int ac, char **av)
        syslog(LOG_ERR, "sshlockout starting up");
        freopen("/dev/null", "w", stdout);
        freopen("/dev/null", "w", stderr);
+
+       if ((dev = open(PF_DEVICE, O_RDWR)) == -1) {
+               syslog(LOG_ERR, "sshlockout: open(" PF_DEVICE "): %m");
+               return(1);
+       }
+
+       if (pledge("stdio", NULL) == -1) {
+               syslog(LOG_ERR, "sshlockout: pledge: %m");
+               return(1);
+       }
 
        while (fgets(buf, sizeof(buf), stdin) != NULL) {
                if (strstr(buf, "sshd") == NULL)

Reply via email to