From nobody Thu Jan 04 22:11:11 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T5glg2XGgz55NcR; Thu, 4 Jan 2024 22:11:11 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T5glg2679z4NPx; Thu, 4 Jan 2024 22:11:11 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704406271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=dzLv8V0cyandfFvJ9jdRVZEDeskwuAxbJFnxhR9CzaM=; b=Ua5OCc4612yqvPkr+yDZvRPVL7F9P1FBcMPvoVBj7xn8wn0TTMMRFfWEthWR+Qo6O555YM W3eYs1TSXNaRvdKM2oGNSN0pFDDOFV7Aioq3yrm3yEMr6vLAzZGXD59gXEVT3Btj8cOMh1 wnn5pk9o1bjiivh9UxIYKuMB7uaNYz97bEbsm80FkmmD93BXSQGTBon9jsci3RxWUeGIs7 zeIAs2eTBheXAWaa693Q3Ls3IYFUWdO6JiwyrPOLsxld8IxX/Yh3ADdB6a2he3k2Xe1tR+ 7vDajIG2/+nC4ZMBBmHOI4rU8DtNxzD8OaItphnQ3e+Uf83EPdTel/GuHyORHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704406271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=dzLv8V0cyandfFvJ9jdRVZEDeskwuAxbJFnxhR9CzaM=; b=jqNfSq5Bi0Rc/Oip8VJSqdthozthg1gUptpadCJJSxrda3zn3Y7CgZK2l21CV06AfUkp5/ a4Blxwb/gsJRP8g8esduv0zsOBlXcZZq+ST5PiCDrEQHolnDezJoxphJxQY2Eoaqd+Nmmt EDxf5Yj444dMAWXIMCSwBJIJJehz+pKxsWWWVdKvpngi1EJQR8zJZNOqOQQYxQWkFhvZx9 peXnQJtzuObIA5L6dSgQk/h3/sGMTUJjU54mr3/xb+JRXLD4qr9MTnmpGTiabC6d6mtMqx ZmO1kwSyk96kUqbpS3XHyjtenv1F9bGdoe7K7/dNStAs1boP5gx0MvfZYzkdNA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1704406271; a=rsa-sha256; cv=none; b=VtzDebvaQwqGCGioxONJCFeqCe6qwEVlTtQ3116tSsS0bnDlHh6ihJBe9/N/JIpDA/b+RY AjUbwMkJLtP/76qcq7f/inqprlO6S7kL6dL8RzckqXk/5Gxp13yoTwAQ/nC/y/uCHTRudB /xNMUSa1oHOvSRPVfAXR40kD9bG57j2RxOnSwJlieAIqBctl6dnjNLm7qdjGSEf7LCYdC4 N5AQt+r6ePDvnDJjNzkhPPw3bXIAql/B+MUiINoLYBkL5GhtGRmHiTNUYZhq18APTGpY3H mepRB0fPVFoEXz+IrS21OEFpb+tFhW0ibLOHue31NnIAiY7yAW71iZLHoEZVtA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T5glg1C41zXJV; Thu, 4 Jan 2024 22:11:11 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 404MBB4t002016; Thu, 4 Jan 2024 22:11:11 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 404MBBVJ002013; Thu, 4 Jan 2024 22:11:11 GMT (envelope-from git) Date: Thu, 4 Jan 2024 22:11:11 GMT Message-Id: <202401042211.404MBBVJ002013@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 66cacc141d37 - main - libpfctl: introduce pfctl_handle List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 66cacc141d372fdfa624a380bac6880ecf809994 Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=66cacc141d372fdfa624a380bac6880ecf809994 commit 66cacc141d372fdfa624a380bac6880ecf809994 Author: Kristof Provost AuthorDate: 2024-01-04 09:50:14 +0000 Commit: Kristof Provost CommitDate: 2024-01-04 22:10:24 +0000 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") --- lib/libpfctl/libpfctl.c | 58 ++++++++++++++++++++++++++++++++++++++----------- lib/libpfctl/libpfctl.h | 10 +++++++-- sbin/pfctl/pfctl.c | 12 ++++++---- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index f915072c4ea1..94949a5a7337 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -50,11 +50,17 @@ #include #include #include +#include #include #include #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 diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 7f3b1b600db7..f128e5340891 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -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]; diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 2702c701f9cc..217bf31b3301 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -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))