2021-02-26 00:10:12 +01:00
|
|
|
#include <err.h>
|
2021-03-10 22:34:50 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2021-02-26 00:10:12 +01:00
|
|
|
#include <netdb.h>
|
2021-03-10 22:34:50 +01:00
|
|
|
#include <netinet/in.h>
|
2021-02-28 10:54:36 +01:00
|
|
|
#include <syslog.h>
|
2022-09-17 16:52:03 +02:00
|
|
|
#include <sys/wait.h>
|
2021-03-10 22:34:50 +01:00
|
|
|
#include <unistd.h>
|
2021-02-26 00:10:12 +01:00
|
|
|
|
2021-03-10 22:34:50 +01:00
|
|
|
#include <sys/socket.h>
|
|
|
|
|
2022-08-22 14:50:40 +02:00
|
|
|
#define DEFAULT_TABLE "iblocked"
|
2022-08-22 14:50:27 +02:00
|
|
|
#define TABLE_LEN 32 /* see PF_TABLE_NAME_SIZE in net/pfvar.h */
|
2021-03-10 22:34:50 +01:00
|
|
|
|
|
|
|
int main(int argc, char *argv[]){
|
2022-08-22 14:55:25 +02:00
|
|
|
struct sockaddr_storage sock = {0};
|
2021-03-10 22:34:50 +01:00
|
|
|
socklen_t slen = sizeof(sock);
|
|
|
|
char ip[INET6_ADDRSTRLEN] = {'\0'}; /* INET6_ADDRSTRLEN > INET_ADDRSTRLEN */
|
|
|
|
char table[TABLE_LEN] = DEFAULT_TABLE;
|
2022-08-22 14:55:25 +02:00
|
|
|
int status = 0;
|
2022-09-17 16:52:03 +02:00
|
|
|
pid_t id;
|
2021-03-10 22:34:50 +01:00
|
|
|
|
2021-03-20 11:42:00 +01:00
|
|
|
if (unveil("/usr/bin/doas", "rx") != 0)
|
2021-03-10 22:34:50 +01:00
|
|
|
err(1, "unveil");
|
2022-09-17 16:52:03 +02:00
|
|
|
if (pledge("exec inet proc stdio", NULL) != 0)
|
2021-03-10 22:34:50 +01:00
|
|
|
err(1, "pledge");
|
|
|
|
|
|
|
|
/* configuration */
|
2022-08-22 14:55:45 +02:00
|
|
|
if (argc == 2)
|
2022-08-22 14:55:25 +02:00
|
|
|
if (strlcpy(table, argv[1], TABLE_LEN) >= sizeof(table))
|
2021-03-10 22:34:50 +01:00
|
|
|
errx(1, "table name is too long");
|
2021-02-26 00:10:12 +01:00
|
|
|
|
2021-03-10 22:34:50 +01:00
|
|
|
/* get socket structure */
|
2022-08-22 14:56:21 +02:00
|
|
|
if (getpeername(STDIN_FILENO, (struct sockaddr *)&sock, &slen))
|
2021-03-10 22:34:50 +01:00
|
|
|
err(1, "getpeername");
|
|
|
|
|
|
|
|
/* get ip */
|
|
|
|
status = getnameinfo((struct sockaddr *)&sock, slen, ip, sizeof(ip),
|
|
|
|
NULL, 0, NI_NUMERICHOST);
|
|
|
|
|
2022-08-22 14:56:21 +02:00
|
|
|
if (status != 0) {
|
2021-03-10 22:34:50 +01:00
|
|
|
syslog(LOG_DAEMON, "getnameinfo error");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
syslog(LOG_DAEMON, "blocking %s", ip);
|
2022-08-22 14:56:21 +02:00
|
|
|
switch (sock.ss_family) {
|
2022-08-22 14:56:35 +02:00
|
|
|
case AF_INET: /* FALLTHROUGH */
|
2021-03-10 22:34:50 +01:00
|
|
|
case AF_INET6:
|
2022-09-17 16:52:03 +02:00
|
|
|
id = fork();
|
|
|
|
|
|
|
|
// child process
|
|
|
|
if (id == 0) {
|
|
|
|
execl("/usr/bin/doas", "doas", "/sbin/pfctl", "-t", table, "-T", "add", ip, NULL);
|
|
|
|
} else { // parent process
|
|
|
|
wait(NULL);
|
|
|
|
}
|
|
|
|
execl("/usr/bin/doas", "doas", "/sbin/pfctl", "-k", ip, NULL);
|
2021-03-10 22:34:50 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
exit(2);
|
|
|
|
}
|
2021-02-26 00:10:12 +01:00
|
|
|
}
|
|
|
|
|