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)