mirror of
https://git.FreeBSD.org/src.git
synced 2024-10-18 02:19:39 +00:00
libpfctl: introduce pfctl_handle
Consumers of libpfctl can (and in future, should) open a handle. This handle is an opaque object which contains the /dev/pf file descriptor and a netlink handle. This means that libpfctl users can open the handle as root, then drop privileges and still access pf. Already add the handle to pfctl_startstop() and pfctl_get_creatorids() as these are new in main, and not present on stable branches. Other calls will have handle-enabled alternatives implemented in subsequent commits. Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
parent
32df0124f4
commit
66cacc141d
@ -50,11 +50,17 @@
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libpfctl.h"
|
||||
|
||||
struct pfctl_handle {
|
||||
int fd;
|
||||
struct snl_state ss;
|
||||
};
|
||||
|
||||
const char* PFCTL_SYNCOOKIES_MODE_NAMES[] = {
|
||||
"never",
|
||||
"always",
|
||||
@ -64,6 +70,38 @@ const char* PFCTL_SYNCOOKIES_MODE_NAMES[] = {
|
||||
static int _pfctl_clear_states(int , const struct pfctl_kill *,
|
||||
unsigned int *, uint64_t);
|
||||
|
||||
struct pfctl_handle *
|
||||
pfctl_open(const char *pf_device)
|
||||
{
|
||||
struct pfctl_handle *h;
|
||||
|
||||
h = calloc(1, sizeof(struct pfctl_handle));
|
||||
h->fd = -1;
|
||||
|
||||
h->fd = open(pf_device, O_RDWR);
|
||||
if (h->fd < 0)
|
||||
goto error;
|
||||
|
||||
if (!snl_init(&h->ss, NETLINK_GENERIC))
|
||||
goto error;
|
||||
|
||||
return (h);
|
||||
error:
|
||||
close(h->fd);
|
||||
snl_free(&h->ss);
|
||||
free(h);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
pfctl_close(struct pfctl_handle *h)
|
||||
{
|
||||
close(h->fd);
|
||||
snl_free(&h->ss);
|
||||
free(h);
|
||||
}
|
||||
|
||||
static int
|
||||
pfctl_do_ioctl(int dev, uint cmd, size_t size, nvlist_t **nvl)
|
||||
{
|
||||
@ -183,21 +221,19 @@ pf_nvuint_64_array(const nvlist_t *nvl, const char *name, size_t maxelems,
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_startstop(int start)
|
||||
pfctl_startstop(struct pfctl_handle *h, int start)
|
||||
{
|
||||
struct snl_state ss = {};
|
||||
struct snl_errmsg_data e = {};
|
||||
struct snl_writer nw;
|
||||
struct nlmsghdr *hdr;
|
||||
uint32_t seq_id;
|
||||
int family_id;
|
||||
|
||||
snl_init(&ss, NETLINK_GENERIC);
|
||||
family_id = snl_get_genl_family(&ss, PFNL_FAMILY_NAME);
|
||||
family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
|
||||
if (family_id == 0)
|
||||
return (ENOTSUP);
|
||||
|
||||
snl_init_writer(&ss, &nw);
|
||||
snl_init_writer(&h->ss, &nw);
|
||||
hdr = snl_create_genl_msg_request(&nw, family_id,
|
||||
start ? PFNL_CMD_START : PFNL_CMD_STOP);
|
||||
|
||||
@ -206,9 +242,9 @@ pfctl_startstop(int start)
|
||||
return (ENOMEM);
|
||||
seq_id = hdr->nlmsg_seq;
|
||||
|
||||
snl_send_message(&ss, hdr);
|
||||
snl_send_message(&h->ss, hdr);
|
||||
|
||||
while ((hdr = snl_read_reply_multi(&ss, seq_id, &e)) != NULL) {
|
||||
while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
|
||||
}
|
||||
|
||||
return (e.error);
|
||||
@ -1288,17 +1324,13 @@ pfctl_get_creators_nl(struct snl_state *ss, uint32_t *creators, size_t *len)
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_get_creatorids(uint32_t *creators, size_t *len)
|
||||
pfctl_get_creatorids(struct pfctl_handle *h, uint32_t *creators, size_t *len)
|
||||
{
|
||||
struct snl_state ss = {};
|
||||
int error;
|
||||
|
||||
snl_init(&ss, NETLINK_GENERIC);
|
||||
error = pfctl_get_creators_nl(&ss, creators, len);
|
||||
snl_free(&ss);
|
||||
error = pfctl_get_creators_nl(&h->ss, creators, len);
|
||||
|
||||
return (error);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -385,7 +385,13 @@ struct pfctl_syncookies {
|
||||
uint32_t halfopen_states;
|
||||
};
|
||||
|
||||
int pfctl_startstop(int start);
|
||||
#define PF_DEVICE "/dev/pf"
|
||||
|
||||
struct pfctl_handle;
|
||||
struct pfctl_handle *pfctl_open(const char *pf_device);
|
||||
void pfctl_close(struct pfctl_handle *);
|
||||
|
||||
int pfctl_startstop(struct pfctl_handle *h, int start);
|
||||
struct pfctl_status* pfctl_get_status(int dev);
|
||||
uint64_t pfctl_status_counter(struct pfctl_status *status, int id);
|
||||
uint64_t pfctl_status_lcounter(struct pfctl_status *status, int id);
|
||||
@ -416,7 +422,7 @@ int pfctl_add_rule(int dev, const struct pfctl_rule *r,
|
||||
const char *anchor, const char *anchor_call, uint32_t ticket,
|
||||
uint32_t pool_ticket);
|
||||
int pfctl_set_keepcounters(int dev, bool keep);
|
||||
int pfctl_get_creatorids(uint32_t *creators, size_t *len);
|
||||
int pfctl_get_creatorids(struct pfctl_handle *h, uint32_t *creators, size_t *len);
|
||||
|
||||
struct pfctl_state_filter {
|
||||
char ifname[IFNAMSIZ];
|
||||
|
@ -132,7 +132,7 @@ static const char *showopt;
|
||||
static const char *debugopt;
|
||||
static char *anchoropt;
|
||||
static const char *optiopt = NULL;
|
||||
static const char *pf_device = "/dev/pf";
|
||||
static const char *pf_device = PF_DEVICE;
|
||||
static char *ifaceopt;
|
||||
static char *tableopt;
|
||||
static const char *tblcmdopt;
|
||||
@ -144,6 +144,7 @@ int loadopt;
|
||||
int altqsupport;
|
||||
|
||||
int dev = -1;
|
||||
struct pfctl_handle *pfh = NULL;
|
||||
static int first_title = 1;
|
||||
static int labels = 0;
|
||||
|
||||
@ -312,7 +313,7 @@ pfctl_enable(int dev, int opts)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = pfctl_startstop(1)) != 0) {
|
||||
if ((ret = pfctl_startstop(pfh, 1)) != 0) {
|
||||
if (ret == EEXIST)
|
||||
errx(1, "pf already enabled");
|
||||
else if (ret == ESRCH)
|
||||
@ -335,7 +336,7 @@ pfctl_disable(int dev, int opts)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = pfctl_startstop(0)) != 0) {
|
||||
if ((ret = pfctl_startstop(pfh, 0)) != 0) {
|
||||
if (ret == ENOENT)
|
||||
errx(1, "pf not enabled");
|
||||
else
|
||||
@ -1665,7 +1666,7 @@ pfctl_show_creators(int opts)
|
||||
uint32_t creators[16];
|
||||
size_t count = nitems(creators);
|
||||
|
||||
ret = pfctl_get_creatorids(creators, &count);
|
||||
ret = pfctl_get_creatorids(pfh, creators, &count);
|
||||
if (ret != 0)
|
||||
errx(ret, "Failed to retrieve creators");
|
||||
|
||||
@ -3079,6 +3080,9 @@ main(int argc, char *argv[])
|
||||
altqsupport = 1;
|
||||
#endif
|
||||
}
|
||||
pfh = pfctl_open(pf_device);
|
||||
if (pfh == NULL)
|
||||
err(1, "Failed to open netlink");
|
||||
|
||||
if (opts & PF_OPT_DISABLE)
|
||||
if (pfctl_disable(dev, opts))
|
||||
|
Loading…
Reference in New Issue
Block a user