identity

package
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package identity implements RFC 3325 P-Asserted-Identity (PAI) and Privacy header processing for both outbound (UAC) and inbound (UAS) signaling paths.

Why a dedicated package:

  • The same parser is needed in pkg/sip/server (extract PAI from inbound INVITE) and pkg/sip/outbound (emit PAI on outbound INVITE), and a future pkg/sip/identity8224 extension (STIR/SHAKEN) wants to chain off the same trust-domain config.
  • PAI semantics differ from From/Contact in two non-obvious ways: (1) it carries an *asserted* (carrier-validated) identity, not the UAS-claimed one, and (2) by RFC 3325 §4 it MUST be stripped at trust-domain boundaries unless an explicit relationship exists. Centralising the validation keeps that boundary rule in one place.

Out of scope here: signing the assertion (that's RFC 8224 Identity, batch 3B). PAI is the unsigned, hop-by-hop "trust us, we validated the caller" header — only safe within a trust domain.

Index

Constants

View Source
const (
	PrivacyNone     = ""        // no Privacy header
	PrivacyID       = "id"      // hide PAI identity (RFC 3325 §7)
	PrivacyNoChange = "none"    // explicit opt-out (RFC 3323)
	PrivacyHeader   = "header"  // strip Via/Contact for privacy
	PrivacyUser     = "user"    // anonymize From
	PrivacySession  = "session" // anonymize SDP
	PrivacyCritical = "critical"
)

PrivacyToken values defined by RFC 3323 / RFC 3325. We expose the subset we actually emit / consume; "header" / "session" / "user" / "critical" are accepted on input but treated like "id" for the purpose of UI redaction.

Variables

This section is empty.

Functions

func FormatPrivacyHeader

func FormatPrivacyHeader(tokens []string) string

FormatPrivacyHeader renders a Privacy header value from a token list. Empty / nil input returns "" (caller should omit the header entirely).

func ParsePrivacy

func ParsePrivacy(raw string) []string

ParsePrivacy parses the `Privacy:` header value (RFC 3323 §4.2). The header carries a semicolon-separated token list; we lowercase and return them in declaration order. Empty input → nil slice.

func PeerIsTrusted

func PeerIsTrusted(remoteAddr *net.UDPAddr) bool

PeerIsTrusted reports whether an inbound signaling peer is in the trust domain. Empty allow-list => trust any peer (dev mode).

We match on host alone (port stripped) because operators almost always rotate SBC ports while keeping the host stable. If you need strict host:port matching, configure with explicit ports — we still compare those exactly when the env value carries a port.

func PrivacyRequestsID

func PrivacyRequestsID(tokens []string) bool

PrivacyRequestsID reports whether the parsed Privacy tokens ask us to suppress identity at egress. RFC 3325 §7 says any of {id, header, user} implies "hide PAI"; `none` overrides.

func SetTrustDomainsForTest

func SetTrustDomainsForTest(list []string)

SetTrustDomainsForTest is used by unit tests to override the env without touching process state. Pass nil to revert to env-driven.

Types

type Asserted

type Asserted struct {
	// URI is the bare URI without angle brackets ("sip:+8613800138000@trust.example"
	// or "tel:+8613800138000"). Empty means the header was absent or
	// stripped by the trust-domain filter.
	URI string
	// DisplayName is the optional unquoted display-name. Empty when the
	// header had no display-name part.
	DisplayName string
	// Scheme is "sip" / "sips" / "tel" for quick predicate checks; lower
	// case, never empty when URI != "".
	Scheme string
}

Asserted is one parsed P-Asserted-Identity row. RFC 3325 allows two rows max: one sip:/sips: URI and one tel: URI. We keep them in URI / DisplayName form because that's what downstream business code wants to log / display / persist.

func ParsePAI

func ParsePAI(raw string) []Asserted

ParsePAI parses one or more P-Asserted-Identity header values. RFC 3325 §3 allows at most two: one sip:/sips: and one tel:. We tolerate extras gracefully (return what we parsed; ignore the rest) instead of failing loud — better to surface a partial identity than reject the call.

Multi-line input ("\r\n" separator) is the form we get from the stack.Message GetHeader implementation when peers fold PAI.

func (Asserted) FormatHeader

func (a Asserted) FormatHeader() string

FormatHeader renders one PAI row in wire format. Display-names are wrapped in quotes per RFC 3261 (RFC 3325 does not relax the BNF). Use FormatPAIDisplayName from the outbound package if you need MIME encoded-word support for non-ASCII display names; PAI is *operator to operator* and almost always ASCII, so we keep this minimal.

func (Asserted) IsEmpty

func (a Asserted) IsEmpty() bool

IsEmpty reports whether the parsed value is meaningful.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL