feat: full NFSv4.2 server and client in pure Go
Test / test (push) Successful in 2m4s
Release / gates (push) Successful in 2m5s
Release / build (amd64, freebsd) (push) Successful in 1m27s
Release / build (amd64, linux) (push) Successful in 1m22s
Release / build (amd64, netbsd) (push) Successful in 1m19s
Release / build (amd64, openbsd) (push) Successful in 1m20s
Release / build (arm64, darwin) (push) Successful in 1m21s
Release / build (arm64, freebsd) (push) Successful in 1m26s
Release / build (arm64, linux) (push) Successful in 1m25s
Release / build (arm64, netbsd) (push) Successful in 1m31s
Release / build (arm64, openbsd) (push) Successful in 1m27s
Release / build (loong64, linux) (push) Successful in 1m37s
Release / build (riscv64, linux) (push) Successful in 1m21s
Release / release (push) Successful in 40s
Test / test (push) Successful in 2m4s
Release / gates (push) Successful in 2m5s
Release / build (amd64, freebsd) (push) Successful in 1m27s
Release / build (amd64, linux) (push) Successful in 1m22s
Release / build (amd64, netbsd) (push) Successful in 1m19s
Release / build (amd64, openbsd) (push) Successful in 1m20s
Release / build (arm64, darwin) (push) Successful in 1m21s
Release / build (arm64, freebsd) (push) Successful in 1m26s
Release / build (arm64, linux) (push) Successful in 1m25s
Release / build (arm64, netbsd) (push) Successful in 1m31s
Release / build (arm64, openbsd) (push) Successful in 1m27s
Release / build (loong64, linux) (push) Successful in 1m37s
Release / build (riscv64, linux) (push) Successful in 1m21s
Release / release (push) Successful in 40s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// The RPCSEC_GSS credential of RFC 2203 as refined by RFC 5403: the
|
||||
// credential body, the context establishment procedures and result, and
|
||||
// the service levels none, integrity and privacy.
|
||||
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"sourcedock.dev/petrbalvin/nfs/internal/xdr"
|
||||
)
|
||||
|
||||
// The RPCSEC_GSS authentication flavor.
|
||||
const FlavorGSS = 6
|
||||
|
||||
// GSSVersion1 is the credential version of RFC 2203.
|
||||
const GSSVersion1 = 1
|
||||
|
||||
// Credential procedures of the gss_proc union.
|
||||
const (
|
||||
GSSProcData = 0
|
||||
GSSProcInit = 1
|
||||
GSSProcContinue = 2
|
||||
GSSProcDestroy = 3
|
||||
)
|
||||
|
||||
// Service levels of rpc_gss_svc_t.
|
||||
const (
|
||||
SvcNone = 1
|
||||
SvcIntegrity = 2
|
||||
SvcPrivacy = 3
|
||||
)
|
||||
|
||||
// A GSSCred is the decoded version one credential body: the version,
|
||||
// the procedure, the sequence number, the service and the context
|
||||
// handle, in the order RFC 2203 section 5.2.1 fixes for every
|
||||
// procedure.
|
||||
type GSSCred struct {
|
||||
Version uint32
|
||||
Proc uint32
|
||||
Seq uint32
|
||||
Service uint32
|
||||
Handle []byte
|
||||
}
|
||||
|
||||
// AppendGSSCred encodes the version one credential body. The context
|
||||
// token of the control procedures travels in the procedure arguments,
|
||||
// never in the credential.
|
||||
func AppendGSSCred(b []byte, proc, seq, service uint32, handle []byte) []byte {
|
||||
b = xdr.AppendUint32(b, GSSVersion1)
|
||||
b = xdr.AppendUint32(b, proc)
|
||||
b = xdr.AppendUint32(b, seq)
|
||||
b = xdr.AppendUint32(b, service)
|
||||
return xdr.AppendVarOpaque(b, handle)
|
||||
}
|
||||
|
||||
// DecodeGSSCred decodes the version one credential body.
|
||||
func DecodeGSSCred(body []byte) (GSSCred, error) {
|
||||
d := xdr.NewDecoder(body)
|
||||
var c GSSCred
|
||||
var err error
|
||||
if c.Version, err = d.Uint32(); err != nil {
|
||||
return c, err
|
||||
}
|
||||
if c.Version != GSSVersion1 {
|
||||
return c, ErrGSSCred
|
||||
}
|
||||
if c.Proc, err = d.Uint32(); err != nil {
|
||||
return c, err
|
||||
}
|
||||
switch c.Proc {
|
||||
case GSSProcData, GSSProcInit, GSSProcContinue, GSSProcDestroy:
|
||||
default:
|
||||
return c, ErrGSSCred
|
||||
}
|
||||
if c.Seq, err = d.Uint32(); err != nil {
|
||||
return c, err
|
||||
}
|
||||
if c.Service, err = d.Uint32(); err != nil {
|
||||
return c, err
|
||||
}
|
||||
c.Handle, err = d.VarOpaque()
|
||||
return c, err
|
||||
}
|
||||
|
||||
// ErrGSSCred marks a malformed version one credential: an unknown
|
||||
// procedure or a version other than one.
|
||||
var ErrGSSCred = &gssError{"malformed rpcsec gss version one credential"}
|
||||
|
||||
type gssError struct{ s string }
|
||||
|
||||
func (e *gssError) Error() string { return "rpc: " + e.s }
|
||||
|
||||
// AppendGSSInitRes encodes the RPCSEC_GSS_INIT result: the handle the
|
||||
// server assigns, the major and minor status, the sequence window and
|
||||
// the reply token.
|
||||
func AppendGSSInitRes(b []byte, handle []byte, major, minor, window uint32, token []byte) []byte {
|
||||
b = xdr.AppendVarOpaque(b, handle)
|
||||
b = xdr.AppendUint32(b, major)
|
||||
b = xdr.AppendUint32(b, minor)
|
||||
b = xdr.AppendUint32(b, window)
|
||||
return xdr.AppendVarOpaque(b, token)
|
||||
}
|
||||
|
||||
// DecodeGSSInitRes decodes the RPCSEC_GSS_INIT result.
|
||||
func DecodeGSSInitRes(payload []byte) (handle []byte, major, minor, window uint32, token []byte, err error) {
|
||||
d := xdr.NewDecoder(payload)
|
||||
if handle, err = d.VarOpaque(); err != nil {
|
||||
return
|
||||
}
|
||||
if major, err = d.Uint32(); err != nil {
|
||||
return
|
||||
}
|
||||
if minor, err = d.Uint32(); err != nil {
|
||||
return
|
||||
}
|
||||
if window, err = d.Uint32(); err != nil {
|
||||
return
|
||||
}
|
||||
token, err = d.VarOpaque()
|
||||
return
|
||||
}
|
||||
|
||||
// The AUTH_TLS authentication flavor of RFC 9289 and the STARTTLS
|
||||
// token the server answers the probe with.
|
||||
const (
|
||||
FlavorTLS = 7
|
||||
StarttlsToken = "STARTTLS"
|
||||
)
|
||||
Reference in New Issue
Block a user