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)