rpc2: RPCSEC_GSS privacy service (krb5p) - #109
Open
benjarvis wants to merge 1 commit into
Open
Conversation
benjarvis
force-pushed
the
rpcsec-gss-privacy
branch
from
June 20, 2026 19:46
bdf3490 to
13a8f1b
Compare
Implement the GSS privacy service (rpc_gss_svc_privacy, sec=krb5p) on top of
the existing krb5/krb5i RPCSEC_GSS layer. Call arguments arrive wrapped as
rpc_gss_priv_data { opaque databody_priv<> } where databody_priv is the
GSS-sealed token of XDR(seq_num) || XDR(proc_args); gss_unwrap recovers the
plaintext, the embedded seq is verified against the credential, and the inner
proc arguments are repointed for normal dispatch. Replies are wrapped
symmetrically: gss_wrap(seq_num || results) emitted as the single opaque of
rpc_gss_priv_data. EVPL_RPC2_GSS_SVC_PRIVACY is now accepted in the DATA path
rather than rejected with AUTH_TOOWEAK.
The GSS wrap/unwrap scratch buffers (the privacy databody_priv token, the
integrity databody, and the privacy reply plaintext) need to be contiguous for
the crypto calls. They previously came from the request's fixed 128 KiB dbuf
arena, so any wrapped call larger than the arena (e.g. a 256 KiB WRITE) failed.
Allocate them from the recycling iovec allocator (evpl_iovec_alloc, max_iovecs
== 1) instead: contiguous, sized to the message, and recycled rather than
malloc/free-churned on every data-path op. Add evpl_buffer_size() to expose
the allocator's single-buffer contiguous limit.
Bound each length before allocating: it must fit in the bytes actually received
(a raw wire u32 reaches ~4 GiB; the message is already capped at
EVPL_RPC2_MAX_REASM_LENGTH) and within one recycling buffer. The latter is also
a correctness fix -- evpl_iovec_alloc with max_iovecs == 1 cannot satisfy a
single-iovec request larger than buffer_size and would spin, so an oversized
GSS payload (the existing inner-args allocation included) is now rejected as
malformed rather than hanging the rpc2 thread. buffer_size (2 MiB default) sits
far above any NFS wsize/rsize.
benjarvis
force-pushed
the
rpcsec-gss-privacy
branch
from
June 20, 2026 21:21
13a8f1b to
7acb1b5
Compare
benjarvis
added a commit
to benjarvis/libevpl
that referenced
this pull request
Aug 11, 2026
…himera-nas#109) * Add REST API for user/share/export/bucket management with Swagger UI Implement comprehensive REST API endpoints for runtime management of users, NFS exports, SMB shares, and S3 buckets. Changes are in-memory only (no persistence). REST API: - GET/POST/DELETE /api/v1/users - User management - GET/POST/DELETE /api/v1/exports - NFS export management - GET/POST/DELETE /api/v1/shares - SMB share management - GET/POST/DELETE /api/v1/buckets - S3 bucket management - GET /api/docs - Embedded Swagger UI - GET /api/openapi.json - OpenAPI 3.0 specification Backend additions: - VFS user cache: builtin user iteration for pinned users - S3 bucket map: remove and iterate functions - SMB: share list/get/remove operations - NFS: export list/get/remove operations - Server-level wrapper functions for REST handlers Python SDK: - Extended chimera_admin.client with all new API methods - Added API endpoint tests * Fix Dockerfile pkg-config dependency and reuse lint - Add pkg-config to both Dockerfiles for REST CMake build - Break up SPDX strings in embed_files.py to avoid reuse detection * Update copyright headers to 2025-2026 * License Python admin SDK and OpenAPI spec under Apache-2.0 The admin SDK and OpenAPI specification are intended for broader use and are licensed under Apache-2.0. Only the C code in chimera remains LGPL-2.1-only. * Add HTTPS support to REST API with auto-generated certificates - Add rest_https_port config option (both HTTP and HTTPS can run simultaneously) - Add rest_ssl_cert and rest_ssl_key config options for custom certificates - Auto-generate self-signed certificate at startup if HTTPS enabled but no cert provided - Update Python SDK client with use_https parameter - Add HTTPS test fixtures and tests Config options: - rest_http_port: HTTP port (default: 0, disabled) - rest_https_port: HTTPS port (default: 0, disabled) - rest_ssl_cert: Path to SSL certificate file (optional) - rest_ssl_key: Path to SSL private key file (optional) When rest_https_port is set but no certificate is provided, a self-signed certificate is generated in /tmp/ at startup. * Add static API documentation with ReDoc - Add docs/api.html with ReDoc-based OpenAPI viewer - Move openapi.json to docs/ as single source of truth - Update CMake to embed spec from docs/openapi.json - Update docs/index.md with link to API reference - Add `make docs` target for documentation info * Fix Docker build by including docs/openapi.json The CMakeLists.txt for the REST module references docs/openapi.json for embedding into the build, but .dockerignore was excluding the entire docs/ directory. Update .dockerignore to exclude docs/* but explicitly include docs/openapi.json. * Remove redundant zero initialization in server config The config structure is calloc'd, so explicit initialization of metrics_port and rest_http_port to 0 is unnecessary.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the RPCSEC_GSS privacy service (krb5p) to the rpc2 GSS layer, completing
the set alongside the krb5/krb5i support merged in #108.
rpc_gss_priv_data { opaque databody_priv<> }, wheredatabody_privis the GSS-sealed token ofXDR(seq_num) || XDR(proc_args).evpl_rpc2_gss_unwrap_privacycalls theprovider's
unwrap(gss_unwrap), verifies the embedded seq against thecredential, and repoints the inner proc arguments for normal dispatch.
evpl_rpc2_gss_wrap_reply_privacyGSS-wrapsseq_num || resultsand emits it as the single opaque ofrpc_gss_priv_data.EVPL_RPC2_GSS_SVC_PRIVACYis now accepted in the DATA path instead of beingrejected with
AUTH_TOOWEAK.The crypto stays entirely behind the existing provider vtable (
wrap/unwrap),so libevpl remains Kerberos-free.
Latent fix: GSS unwrap scratch arena overflow
While testing krb5p against the real Linux kernel client, a 256 KiB
WRITEfailed to unwrap. Root cause: both the privacy
databody_privtoken and the(pre-existing) integrity
databodywere gathered into the request's fixed128 KiB dbuf arena (
xdr_dbuf_alloc_space), so any wrapped call larger thanthe arena returned NULL and failed. This fix
mallocs the gather scratch(bounded by the message size, not the arena) and frees it. The inner iovec
already uses
evpl_iovec_alloc, and the reply-wrap paths already useevpl_iovec_alloc/malloc, so large encrypted READ replies were neveraffected — and large krb5i writes are fixed by the same change.
Testing
Validated end-to-end in chimera (the consumer): pynfs 4.1
sec=krb5psmoke +per-export
sec=krb5ppolicy, and the real Linux kernel client mounting-o sec=krb5pacross four guest kernels (Ubuntu 22.04/24.04/26.04) driving amulti-block encrypted WRITE+READ. With the arena fix the unwrap failures (and
the client's context-reestablishment retries they triggered) are gone; krb5,
krb5i and krb5p all pass clean. rpc2's own transport ctests pass.