git: 59c3b1a0f7ef - main - security/gssproxy: Add new Port

From: Jochen Neumeister <joneum_at_FreeBSD.org>
Date: Tue, 21 Jul 2026 22:48:55 UTC
The branch main has been updated by joneum:

URL: https://cgit.FreeBSD.org/ports/commit/?id=59c3b1a0f7ef2d7f077410d0d21b8a2e2abe5d73

commit 59c3b1a0f7ef2d7f077410d0d21b8a2e2abe5d73
Author:     Jochen Neumeister <joneum@FreeBSD.org>
AuthorDate: 2026-07-21 22:44:26 +0000
Commit:     Jochen Neumeister <joneum@FreeBSD.org>
CommitDate: 2026-07-21 22:48:24 +0000

    security/gssproxy: Add new Port
    
    GSS Proxy allows processes to perform GSSAPI operations, such as
    Kerberos authentication, through a privileged daemon. This separates
    credential handling from the application and lets services access
    keytabs and credential caches without holding the privileges directly.
    
    WWW: https://github.com/gssapi/gssproxy
    
    Sponsored by:   Netzkommune GmbH
    
    Required for: FreeIPA server port
---
 security/Makefile                                  |   1 +
 security/gssproxy/Makefile                         |  68 ++++++++++++
 security/gssproxy/distinfo                         |   3 +
 security/gssproxy/files/gssproxy.in                |  43 ++++++++
 security/gssproxy/files/patch-Makefile.am          |  11 ++
 security/gssproxy/files/patch-conf__macros.m4      |  11 ++
 security/gssproxy/files/patch-configure.ac         |  52 +++++++++
 .../files/patch-examples_24-nfs-server.conf.in     |  12 +++
 .../gssproxy/files/patch-examples_80-httpd.conf.in |  11 ++
 security/gssproxy/files/patch-external_dinglibs.m4 |  25 +++++
 security/gssproxy/files/patch-external_platform.m4 |  36 +++++++
 .../gssproxy/files/patch-src_client_gpm__common.c  |  21 ++++
 security/gssproxy/files/patch-src_gp__creds.c      |  29 ++++++
 security/gssproxy/files/patch-src_gp__creds.h      |  26 +++++
 security/gssproxy/files/patch-src_gp__init.c       |  24 +++++
 security/gssproxy/files/patch-src_gp__mgmt.c       |  13 +++
 security/gssproxy/files/patch-src_gp__socket.c     | 116 +++++++++++++++++++++
 .../gssproxy/files/patch-tests_interposetest.c     |  10 ++
 security/gssproxy/pkg-descr                        |   6 ++
 security/gssproxy/pkg-plist                        |  14 +++
 20 files changed, 532 insertions(+)

diff --git a/security/Makefile b/security/Makefile
index 56d8e3bfde86..1fd82791606b 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -215,6 +215,7 @@
     SUBDIR += gsa
     SUBDIR += gsad
     SUBDIR += gsasl
+    SUBDIR += gssproxy
     SUBDIR += gstreamer1-plugins-dtls
     SUBDIR += gtkpasman
     SUBDIR += gvm
diff --git a/security/gssproxy/Makefile b/security/gssproxy/Makefile
new file mode 100644
index 000000000000..37d8ba061304
--- /dev/null
+++ b/security/gssproxy/Makefile
@@ -0,0 +1,68 @@
+PORTNAME=	gssproxy
+DISTVERSION=	0.9.2
+CATEGORIES=	security
+MASTER_SITES=	https://github.com/gssapi/gssproxy/releases/download/v${DISTVERSION}/
+
+MAINTAINER=	joneum@FreeBSD.org
+COMMENT=	GSSAPI proxy daemon and interposer mechanism
+WWW=		https://github.com/gssapi/gssproxy
+
+LICENSE=	MIT
+LICENSE_FILE=	${WRKSRC}/COPYING
+
+BUILD_DEPENDS=	docbook-xsl>0:textproc/docbook-xsl \
+		xmllint:textproc/libxml2 \
+		xsltproc:textproc/libxslt
+
+LIB_DEPENDS=	libepoll-shim.so:devel/libepoll-shim \
+		libgssrpc.so.4:security/krb5 \
+		libini_config.so:devel/ding-libs \
+		libpopt.so:devel/popt \
+		libverto.so.0:security/krb5
+
+USES=		autoreconf gettext-runtime gmake gssapi:mit libtool localbase \
+		pkgconfig
+
+USE_RC_SUBR=	gssproxy
+
+GNU_CONFIGURE=	yes
+CONFIGURE_ARGS=	--disable-static \
+		--with-cc-path=/var/db/gssproxy/clients \
+		--with-gpstate-path=/var/db/gssproxy \
+		--with-gssconf-path=${PREFIX}/etc/gss/mech.d \
+		--with-initscript=none \
+		--with-log-path=/var/log/gssproxy \
+		--with-manpages \
+		--with-pid-file=/var/run/gssproxy.pid \
+		--with-pubconf-path=${PREFIX}/etc/gssproxy \
+		--with-socket-name=/var/run/gssproxy.sock \
+		--with-xml-catalog-path=${LOCALBASE}/share/xml/catalog \
+		--without-cap \
+		--without-selinux
+CONFIGURE_ENV=	ac_cv_func_verto_cleanup=no
+
+INSTALL_TARGET=	install-strip
+
+CPPFLAGS+=	-I${LOCALBASE}/include/libepoll-shim
+LIBS+=		-lepoll-shim -lintl
+
+post-install:
+	${RM} ${STAGEDIR}${PREFIX}/lib/gssproxy/proxymech.la
+	${RM} -r ${STAGEDIR}${DOCSDIR}
+	${MV} ${STAGEDIR}${PREFIX}/etc/gss/mech.d/proxymech.conf \
+		${STAGEDIR}${PREFIX}/etc/gss/mech.d/proxymech.conf.sample
+	${MKDIR} ${STAGEDIR}${PREFIX}/etc/gssproxy
+	${INSTALL_DATA} ${WRKSRC}/examples/gssproxy.conf \
+		${STAGEDIR}${PREFIX}/etc/gssproxy/gssproxy.conf.sample
+	${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
+	${INSTALL_DATA} ${WRKSRC}/examples/24-nfs-server.conf \
+		${STAGEDIR}${EXAMPLESDIR}/24-nfs-server.conf
+	${INSTALL_DATA} ${WRKSRC}/examples/80-httpd.conf \
+		${STAGEDIR}${EXAMPLESDIR}/80-httpd.conf
+	${INSTALL_DATA} ${WRKSRC}/examples/99-network-fs-clients.conf \
+		${STAGEDIR}${EXAMPLESDIR}/99-network-fs-clients.conf
+	${MKDIR} ${STAGEDIR}/var/db/gssproxy/clients
+	${MKDIR} ${STAGEDIR}/var/db/gssproxy/rcache
+	${MKDIR} ${STAGEDIR}/var/log/gssproxy
+
+.include <bsd.port.mk>
diff --git a/security/gssproxy/distinfo b/security/gssproxy/distinfo
new file mode 100644
index 000000000000..92ad6838094b
--- /dev/null
+++ b/security/gssproxy/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1784625660
+SHA256 (gssproxy-0.9.2.tar.gz) = 1fe43ea1b03d19e0f1eda3c82ba5bd8bba04e9bc7e629c117dad094d0a6fc1de
+SIZE (gssproxy-0.9.2.tar.gz) = 586240
diff --git a/security/gssproxy/files/gssproxy.in b/security/gssproxy/files/gssproxy.in
new file mode 100644
index 000000000000..76297aa0a8b5
--- /dev/null
+++ b/security/gssproxy/files/gssproxy.in
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# PROVIDE: gssproxy
+# REQUIRE: DAEMON
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="gssproxy"
+rcvar="gssproxy_enable"
+
+load_rc_config "${name}"
+
+: ${gssproxy_enable:=NO}
+: ${gssproxy_config:=%%PREFIX%%/etc/gssproxy/gssproxy.conf}
+: ${gssproxy_configdir:=%%PREFIX%%/etc/gssproxy}
+: ${gssproxy_flags:=}
+
+command="%%PREFIX%%/sbin/gssproxy"
+pidfile="/var/run/gssproxy.pid"
+required_files="${gssproxy_config}"
+command_args="-D -c ${gssproxy_config} -C ${gssproxy_configdir}"
+gssproxy_env="KRB5RCACHEDIR=/var/db/gssproxy/rcache"
+
+extra_commands="reload"
+start_precmd="gssproxy_prestart"
+stop_postcmd="gssproxy_poststop"
+
+gssproxy_prestart()
+{
+/usr/bin/install -d -m 0755 /var/db/gssproxy
+/usr/bin/install -d -m 0700 /var/db/gssproxy/clients
+/usr/bin/install -d -m 0700 /var/db/gssproxy/rcache
+/usr/bin/install -d -m 0755 /var/log/gssproxy
+/bin/rm -f "${pidfile}" /var/run/gssproxy.sock
+}
+
+gssproxy_poststop()
+{
+/bin/rm -f "${pidfile}" /var/run/gssproxy.sock
+}
+
+run_rc_command "$1"
diff --git a/security/gssproxy/files/patch-Makefile.am b/security/gssproxy/files/patch-Makefile.am
new file mode 100644
index 000000000000..a0757a4156df
--- /dev/null
+++ b/security/gssproxy/files/patch-Makefile.am
@@ -0,0 +1,11 @@
+--- Makefile.am.orig	2026-07-21 10:54:51 UTC
++++ Makefile.am
+@@ -283,6 +283,8 @@ edit_cmd = $(SED) \
+ 
+ edit_cmd = $(SED) \
+     -e 's|@sbindir[@]|$(sbindir)|g' \
++    -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
++    -e 's|@socketname[@]|$(socketname)|g' \
+     -e 's|@localstatedir[@]|$(localstatedir)|g' \
+     -e 's|@libdir[@]|$(libdir)|g' \
+     -e 's|@gpclidir[@]|$(gpclidir)|g'
diff --git a/security/gssproxy/files/patch-conf__macros.m4 b/security/gssproxy/files/patch-conf__macros.m4
new file mode 100644
index 000000000000..da10ff50aac5
--- /dev/null
+++ b/security/gssproxy/files/patch-conf__macros.m4
@@ -0,0 +1,11 @@
+--- conf_macros.m4.orig	2026-07-21 10:43:49 UTC
++++ conf_macros.m4
+@@ -248,7 +248,7 @@ AC_DEFUN([WITH_GPSTATE_PATH],
+     gpstatedir="${localstatedir}/lib/gssproxy"
+     if test x"$with_gpstate_path" != x; then
+         config_gpstatepath=$with_gpstate_path
+-        gpstatepath=$with_gpstate_path
++        gpstatedir=$with_gpstate_path
+     fi
+     AC_SUBST(gpstatedir)
+     AC_DEFINE_UNQUOTED(GPSTATE_PATH, "$config_gpstatepath", [Where to store ccache files for gssproxy])
diff --git a/security/gssproxy/files/patch-configure.ac b/security/gssproxy/files/patch-configure.ac
new file mode 100644
index 000000000000..87f75a8647a3
--- /dev/null
+++ b/security/gssproxy/files/patch-configure.ac
@@ -0,0 +1,52 @@
+--- configure.ac.orig	2022-07-26 10:17:29 UTC
++++ configure.ac
+@@ -82,7 +82,7 @@ LIBS="$PTHREAD_LIBS $LIBS"
+ AX_PTHREAD(,[AC_MSG_ERROR([Could not find Pthreads support])])
+ 
+ LIBS="$PTHREAD_LIBS $LIBS"
+-LIBS="$PTHREAD_CFLAGS $CFLAGS"
++CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
+ CC="$PTHREAD_CC"
+ 
+ AC_CHECK_HEADERS([gssapi/gssapi.h],,[AC_MSG_ERROR([Could not find GSSAPI headers])])
+@@ -135,15 +135,31 @@ if test x$only_gss_module != xyes; then
+ if test x$only_gss_module != xyes; then
+     WITH_POPT
+ 
+-    PKG_CHECK_MODULES([VERTO], [libverto >= 0.2.2],
+-      [
+-        AC_CHECK_LIB(verto, verto_free,,
+-            AC_MSG_ERROR(["Error: libverto is not found or lacks verto_free"]))
+-        AC_CHECK_FUNCS(verto_cleanup,,
+-            AC_MSG_WARN(["Warning: libverto lacks verto_cleanup function"]))
+-      ], [
+-        AC_MSG_ERROR([Could not find VERTO headers])
+-      ])
++    case "$host_os" in
++    freebsd*)
++        AC_CHECK_HEADERS([verto.h], [],
++                         [AC_MSG_ERROR([Could not find VERTO headers])])
++        VERTO_CFLAGS=""
++        VERTO_LIBS="-lverto"
++        AC_CHECK_LIB([verto], [verto_free], [],
++                     [AC_MSG_ERROR([Error: libverto is not found or lacks verto_free])])
++        AC_CHECK_FUNCS([verto_cleanup], [],
++                       [AC_MSG_WARN([Warning: libverto lacks verto_cleanup function])])
++        AC_SUBST([VERTO_CFLAGS])
++        AC_SUBST([VERTO_LIBS])
++        ;;
++    *)
++        PKG_CHECK_MODULES([VERTO], [libverto >= 0.2.2],
++          [
++            AC_CHECK_LIB(verto, verto_free,,
++                AC_MSG_ERROR(["Error: libverto is not found or lacks verto_free"]))
++            AC_CHECK_FUNCS(verto_cleanup,,
++                AC_MSG_WARN(["Warning: libverto lacks verto_cleanup function"]))
++          ], [
++            AC_MSG_ERROR([Could not find VERTO headers])
++          ])
++        ;;
++    esac
+ 
+ 
+     WITH_LIBINI_CONFIG
diff --git a/security/gssproxy/files/patch-examples_24-nfs-server.conf.in b/security/gssproxy/files/patch-examples_24-nfs-server.conf.in
new file mode 100644
index 000000000000..e5c498e95c97
--- /dev/null
+++ b/security/gssproxy/files/patch-examples_24-nfs-server.conf.in
@@ -0,0 +1,12 @@
+--- examples/24-nfs-server.conf.in.orig	2026-07-21 10:54:51 UTC
++++ examples/24-nfs-server.conf.in
+@@ -1,7 +1,8 @@
+ [service/nfs-server]
+   mechs = krb5
+-  socket = /run/gssproxy.sock
++  socket = @socketname@
+   cred_store = keytab:/etc/krb5.keytab
+   trusted = yes
++  # This option has no effect on FreeBSD.
+   kernel_nfsd = yes
+   euid = 0
diff --git a/security/gssproxy/files/patch-examples_80-httpd.conf.in b/security/gssproxy/files/patch-examples_80-httpd.conf.in
new file mode 100644
index 000000000000..bff02d99b2f0
--- /dev/null
+++ b/security/gssproxy/files/patch-examples_80-httpd.conf.in
@@ -0,0 +1,11 @@
+--- examples/80-httpd.conf.in.orig	2026-07-21 10:54:51 UTC
++++ examples/80-httpd.conf.in
+@@ -1,5 +1,5 @@
+ [service/HTTP]
+   mechs = krb5
+-  cred_store = keytab:/etc/gssproxy/http.keytab
+-  cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_%U
+-  euid = apache
++  cred_store = keytab:@sysconfdir@/gssproxy/http.keytab
++  cred_store = ccache:@gpclidir@/krb5cc_%U
++  euid = www
diff --git a/security/gssproxy/files/patch-external_dinglibs.m4 b/security/gssproxy/files/patch-external_dinglibs.m4
new file mode 100644
index 000000000000..93cb6491dd45
--- /dev/null
+++ b/security/gssproxy/files/patch-external_dinglibs.m4
@@ -0,0 +1,25 @@
+--- external/dinglibs.m4.orig	2022-07-26 10:17:29 UTC
++++ external/dinglibs.m4
+@@ -19,20 +19,19 @@ AC_DEFUN([WITH_REF_ARRAY], [
+ 
+ AC_DEFUN([WITH_REF_ARRAY], [
+ 
+-AC_CHECK_LIB(ref_array, ref_array_destroy, [],
++AC_CHECK_LIB(ini_config, ref_array_destroy, [],
+              [AC_MSG_ERROR([library must support ref_array_destroy])],
+              [$INI_CONFIG_LIBS])
+ 
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+ /* See: https://pagure.io/SSSD/ding-libs/pull-request/3172 */
+-#include <linux/limits.h>
++#include <limits.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdint.h>
+ #include <ini_configobj.h>
+-#include <ini_config.h>
+ 
+ static int write_to_file(char *path, char *text)
+ {
diff --git a/security/gssproxy/files/patch-external_platform.m4 b/security/gssproxy/files/patch-external_platform.m4
new file mode 100644
index 000000000000..d893758b7dc1
--- /dev/null
+++ b/security/gssproxy/files/patch-external_platform.m4
@@ -0,0 +1,36 @@
+--- external/platform.m4.orig	2026-07-21 17:32:14 UTC
++++ external/platform.m4
+@@ -36,13 +36,24 @@ AM_CONDITIONAL([HAVE_GENTOO], [test x"$osname" = xgent
+ AM_CONDITIONAL([HAVE_DEBIAN], [test x"$osname" = xdebian])
+ AM_CONDITIONAL([HAVE_GENTOO], [test x"$osname" = xgentoo])
+ 
+-AC_CHECK_MEMBERS([struct ucred.pid, struct ucred.uid, struct ucred.gid], , ,
+-                 [[#include <sys/socket.h>]])
++case "$host_os" in
++freebsd*)
++    AC_CHECK_MEMBERS([struct xucred.cr_pid, struct xucred.cr_uid,
++                      struct xucred.cr_gid], [],
++                     [AC_MSG_ERROR([struct xucred is not available])],
++                     [[#include <sys/types.h>
++#include <sys/ucred.h>]])
++    ;;
++*)
++    AC_CHECK_MEMBERS([struct ucred.pid, struct ucred.uid, struct ucred.gid], , ,
++                     [[#include <sys/socket.h>]])
+ 
+-if test x"$ac_cv_member_struct_ucred_pid" = xyes -a \
+-        x"$ac_cv_member_struct_ucred_uid" = xyes -a \
+-        x"$ac_cv_member_struct_ucred_gid" = xyes ; then
+-    AC_DEFINE([HAVE_UCRED], [1], [Define if struct ucred is available])
+-else
+-    AC_MSG_ERROR([struct ucred is not available])
+-fi
++    if test x"$ac_cv_member_struct_ucred_pid" = xyes -a \
++            x"$ac_cv_member_struct_ucred_uid" = xyes -a \
++            x"$ac_cv_member_struct_ucred_gid" = xyes ; then
++        AC_DEFINE([HAVE_UCRED], [1], [Define if struct ucred is available])
++    else
++        AC_MSG_ERROR([struct ucred is not available])
++    fi
++    ;;
++esac
diff --git a/security/gssproxy/files/patch-src_client_gpm__common.c b/security/gssproxy/files/patch-src_client_gpm__common.c
new file mode 100644
index 000000000000..6d0620447904
--- /dev/null
+++ b/security/gssproxy/files/patch-src_client_gpm__common.c
@@ -0,0 +1,21 @@
+--- src/client/gpm_common.c.orig	2022-07-26 10:17:29 UTC
++++ src/client/gpm_common.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gssapi_gpm.h"
+ #include <sys/types.h>
++#include <sys/socket.h>
+ #include <sys/un.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+@@ -11,6 +12,10 @@
+ #include <fcntl.h>
+ #include <sys/random.h>
+ #include <sys/timerfd.h>
++
++#ifndef EBADFD
++#define EBADFD EBADF
++#endif
+ 
+ #define FRAGMENT_BIT (1 << 31)
+ 
diff --git a/security/gssproxy/files/patch-src_gp__creds.c b/security/gssproxy/files/patch-src_gp__creds.c
new file mode 100644
index 000000000000..ad69a58a0125
--- /dev/null
+++ b/security/gssproxy/files/patch-src_gp__creds.c
@@ -0,0 +1,29 @@
+--- src/gp_creds.c.orig	2026-07-21 10:43:49 UTC
++++ src/gp_creds.c
+@@ -3,7 +3,11 @@
+ #include "config.h"
+ #include <stdio.h>
+ #include <sys/socket.h>
++#ifdef __FreeBSD__
++#include <pthread_np.h>
++#else
+ #include <sys/syscall.h>
++#endif
+ #include <sys/types.h>
+ #include <errno.h>
+ #include <string.h>
+@@ -267,10 +271,14 @@ static int ensure_segregated_ccache(struct gp_call_ctx
+         return ENOMEM;
+     }
+ 
++#ifdef __FreeBSD__
++    tid = pthread_getthreadid_np();
++#else
+     do {
+         errno = 0;
+         tid = syscall(SYS_gettid);
+     } while (tid == -1 && errno == EINTR);
++#endif
+ 
+     ret = asprintf(&buf, "MEMORY:internal_%d", tid);
+     if (ret == -1) {
diff --git a/security/gssproxy/files/patch-src_gp__creds.h b/security/gssproxy/files/patch-src_gp__creds.h
new file mode 100644
index 000000000000..4c934b2359cf
--- /dev/null
+++ b/security/gssproxy/files/patch-src_gp__creds.h
@@ -0,0 +1,26 @@
+--- src/gp_creds.h.orig	2026-07-21 10:43:49 UTC
++++ src/gp_creds.h
+@@ -7,15 +7,22 @@
+ #include <stdint.h>
+ #include <stdbool.h>
+ #include <errno.h>
++#include <sys/types.h>
+ #include <gssapi/gssapi.h>
+ 
+ #define CRED_TYPE_NONE 0x00
+ #define CRED_TYPE_UNIX 0x01
+ #define CRED_TYPE_SELINUX 0x02
+ 
++struct gp_unix_cred {
++    pid_t pid;
++    uid_t uid;
++    gid_t gid;
++};
++
+ struct gp_creds {
+     int type;
+-    struct ucred ucred;
++    struct gp_unix_cred ucred;
+ };
+ 
+ #endif /* _GP_CREDS_H_ */
diff --git a/security/gssproxy/files/patch-src_gp__init.c b/security/gssproxy/files/patch-src_gp__init.c
new file mode 100644
index 000000000000..534d36951538
--- /dev/null
+++ b/security/gssproxy/files/patch-src_gp__init.c
@@ -0,0 +1,24 @@
+--- src/gp_init.c.orig	2026-07-21 10:43:49 UTC
++++ src/gp_init.c
+@@ -376,6 +376,7 @@ int init_event_fini(struct gssproxy_ctx *gpctx)
+     return 0;
+ }
+ 
++#ifndef __FreeBSD__
+ static int try_init_proc_nfsd(void)
+ {
+     char buf[] = "1";
+@@ -476,6 +477,13 @@ out:
+     }
+     return 0;
+ }
++
++#else
++int init_proc_nfsd(struct gssproxy_ctx *gpctx UNUSED)
++{
++    return 0;
++}
++#endif
+ 
+ void write_pid(void)
+ {
diff --git a/security/gssproxy/files/patch-src_gp__mgmt.c b/security/gssproxy/files/patch-src_gp__mgmt.c
new file mode 100644
index 000000000000..a0d2a6b9bad2
--- /dev/null
+++ b/security/gssproxy/files/patch-src_gp__mgmt.c
@@ -0,0 +1,13 @@
+--- src/gp_mgmt.c.orig	2026-07-21 10:43:49 UTC
++++ src/gp_mgmt.c
+@@ -270,9 +270,8 @@ done:
+ 
+ done:
+     if (ret) {
+-        char errstr[128]; /* reasonable error str length */
+         GPDEBUGN(3, "%s: Failed to set up krb5 tracing thread: [%s](%d)\n",
+-                    __func__, strerror_r(ret, errstr, 128), ret);
++                    __func__, gp_strerror(ret), ret);
+         free_k5tracer();
+     }
+     return;
diff --git a/security/gssproxy/files/patch-src_gp__socket.c b/security/gssproxy/files/patch-src_gp__socket.c
new file mode 100644
index 000000000000..6376111fd67d
--- /dev/null
+++ b/security/gssproxy/files/patch-src_gp__socket.c
@@ -0,0 +1,116 @@
+--- src/gp_socket.c.orig	2026-07-21 10:43:49 UTC
++++ src/gp_socket.c
+@@ -14,6 +14,11 @@
+ #include <sys/socket.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
++#ifdef __FreeBSD__
++#include <limits.h>
++#include <sys/sysctl.h>
++#include <sys/ucred.h>
++#endif
+ #include <sys/uio.h>
+ #include <sys/un.h>
+ #include <unistd.h>
+@@ -309,17 +314,48 @@ static int get_peercred(int fd, struct gp_conn *conn)
+     socklen_t len;
+     int ret;
+ 
+-    len = sizeof(struct ucred);
+-    ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &conn->creds.ucred, &len);
+-    if (ret == -1) {
+-        ret = errno;
+-        GPDEBUG("Failed to get SO_PEERCRED options! (%d:%s)\n",
+-                ret, gp_strerror(ret));
+-        return ret;
++#ifdef __FreeBSD__
++    {
++        struct xucred xucred;
++
++        len = sizeof(xucred);
++        ret = getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED, &xucred, &len);
++        if (ret == -1) {
++            ret = errno;
++            GPDEBUG("Failed to get LOCAL_PEERCRED options! (%d:%s)\n",
++                    ret, gp_strerror(ret));
++            return ret;
++        }
++        if (len != sizeof(xucred) ||
++            xucred.cr_version != XUCRED_VERSION) {
++            return EIO;
++        }
++
++        conn->creds.ucred.pid = xucred.cr_pid;
++        conn->creds.ucred.uid = xucred.cr_uid;
++        conn->creds.ucred.gid = xucred.cr_gid;
+     }
+-    if (len != sizeof(struct ucred)) {
+-        return EIO;
++#else
++    {
++        struct ucred ucred;
++
++        len = sizeof(ucred);
++        ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len);
++        if (ret == -1) {
++            ret = errno;
++            GPDEBUG("Failed to get SO_PEERCRED options! (%d:%s)\n",
++                    ret, gp_strerror(ret));
++            return ret;
++        }
++        if (len != sizeof(ucred)) {
++            return EIO;
++        }
++
++        conn->creds.ucred.pid = ucred.pid;
++        conn->creds.ucred.uid = ucred.uid;
++        conn->creds.ucred.gid = ucred.gid;
+     }
++#endif
+ 
+     conn->creds.type |= CRED_TYPE_UNIX;
+ 
+@@ -338,8 +374,34 @@ static int get_peercred(int fd, struct gp_conn *conn)
+     return 0;
+ }
+ 
++#ifdef __FreeBSD__
+ static char *get_program(pid_t pid)
+ {
++    int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid };
++    char path[PATH_MAX];
++    size_t len = sizeof(path);
++    int e;
++
++    if (sysctl(mib, 4, path, &len, NULL, 0) == -1) {
++        e = errno;
++        if (e == ESRCH || e == ENOENT) {
++            return NULL;
++        }
++        GPERROR("Unable to read program path: %d (%s)",
++                e, gp_strerror(e));
++        return NULL;
++    }
++
++    if (len == 0) {
++        return NULL;
++    }
++
++    path[sizeof(path) - 1] = 0;
++    return strdup(path);
++}
++#else
++static char *get_program(pid_t pid)
++{
+     char procfile[21];
+     char *program;
+     int ret, e;
+@@ -377,6 +439,8 @@ static char *get_program(pid_t pid)
+             e, strerror(e));
+     return NULL;
+ }
++
++#endif
+ 
+ static void gp_socket_read(verto_ctx *vctx, verto_ev *ev);
+ 
diff --git a/security/gssproxy/files/patch-tests_interposetest.c b/security/gssproxy/files/patch-tests_interposetest.c
new file mode 100644
index 000000000000..80514eb2cf25
--- /dev/null
+++ b/security/gssproxy/files/patch-tests_interposetest.c
@@ -0,0 +1,10 @@
+--- tests/interposetest.c.orig	2022-07-26 10:17:29 UTC
++++ tests/interposetest.c
+@@ -3,6 +3,7 @@
+ #include "config.h"
+ #include <stdlib.h>
+ #include <unistd.h>
++#include <signal.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
diff --git a/security/gssproxy/pkg-descr b/security/gssproxy/pkg-descr
new file mode 100644
index 000000000000..7522b79aae34
--- /dev/null
+++ b/security/gssproxy/pkg-descr
@@ -0,0 +1,6 @@
+GSSProxy provides a privileged GSS-API proxy daemon. Applications can use
+the proxy to perform GSS-API operations without direct access to service
+credentials and keytab files.
+
+The package also provides a GSS-API interposer mechanism for redirecting
+credential operations to the proxy daemon.
diff --git a/security/gssproxy/pkg-plist b/security/gssproxy/pkg-plist
new file mode 100644
index 000000000000..040c5648ad3c
--- /dev/null
+++ b/security/gssproxy/pkg-plist
@@ -0,0 +1,14 @@
+@sample etc/gss/mech.d/proxymech.conf.sample
+@sample etc/gssproxy/gssproxy.conf.sample
+lib/gssproxy/proxymech.so
+sbin/gssproxy
+%%EXAMPLESDIR%%/24-nfs-server.conf
+%%EXAMPLESDIR%%/80-httpd.conf
+%%EXAMPLESDIR%%/99-network-fs-clients.conf
+share/man/man5/gssproxy.conf.5.gz
+share/man/man8/gssproxy-mech.8.gz
+share/man/man8/gssproxy.8.gz
+@dir(root,wheel,0700) /var/db/gssproxy/clients
+@dir(root,wheel,0700) /var/db/gssproxy/rcache
+@dir(root,wheel,0755) /var/db/gssproxy
+@dir(root,wheel,0755) /var/log/gssproxy