authclient

package
v1.99.0 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2026 License: GPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package authclient is the Go client for the yarilo-auth master protocol. It opens a single mTLS TCP connection to the master listener (the second socket yarilo-auth exposes — see internal/auth/protocol/master.go), drains the handshake, and provides typed methods for the wire commands the protocol surfaces today:

One Client owns one TCP conn. Commands within a Client serialise behind a mutex — multiple goroutines may call methods concurrently and the wire-side ordering is enforced internally. Callers that need higher throughput open additional Clients; this package does not ship a pool today.

Consumers wire authclient at startup with the configured master address and the internal mTLS material. The current production consumer is yarilo-backend-api (Phase AUTH-1 follow-up); future consumers — yarilo-admin's userdb subcommand, the standalone smoketest — will Dial the same address.

Index

Constants

This section is empty.

Variables

View Source
var ErrClosed = errors.New("authclient: client closed")

ErrClosed signals that a Client has had Close called or its connection terminated; subsequent calls return this so callers can re-Dial deterministically rather than hanging on the dead reader.

View Source
var ErrNotImplemented = errors.New("authclient: PASS not implemented (Phase AUTH-2)")

ErrNotImplemented is returned by Client.PassdbLookup until Phase AUTH-2 ships Passdb.LookupCredentials and the master-protocol PASS handler stops returning the corresponding `FAIL reason=PASS not implemented` line. Callers can use errors.Is to gate fall-through behaviour cleanly.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client speaks the yarilo-auth master protocol over a single TCP (optionally mTLS-wrapped) connection. Methods are safe to call from multiple goroutines: a mutex enforces one in-flight request at a time on the underlying conn, mirroring the server-side per-connection serial-processing guarantee.

Construct with Dial / DialContext. Always call Client.Close on shutdown so the FIN propagates promptly to the server side and the goroutine watching that conn there returns.

func Dial

func Dial(addr string, tlsCfg *tls.Config) (*Client, error)

Dial opens a connection to the yarilo-auth master listener at addr and consumes the protocol handshake. When tlsCfg is non-nil the connection is wrapped in TLS — yarilo's standard deployment supplies an mTLS config built from the internal CA + the consumer's client cert.

The handshake's VERSION line is validated: only major version 1 is accepted today. Future major bumps surface as a typed error so callers can fail fast rather than speak stale dialect.

func DialContext

func DialContext(ctx context.Context, addr string, tlsCfg *tls.Config) (*Client, error)

DialContext is Dial with a context-aware dial. The context bounds the TCP + TLS handshake; once the handshake is consumed the context has no further effect on the returned Client.

func (*Client) CacheFlush

func (c *Client) CacheFlush(ctx context.Context, masks []string) (uint32, error)

CacheFlush invokes the master-protocol CACHE-FLUSH verb. Empty masks slice triggers a full flush; otherwise each mask is sent as an additional tab-separated argument and yarilo-auth evicts every entry whose stored username matches any mask (glob syntax: `*` = any run, `?` = one char).

Returns the count of evicted entries reported by the server. Used by `yarilo-admin auth cache flush [mask…]`.

func (*Client) Close

func (c *Client) Close() error

Close releases the underlying connection. Idempotent — calling Close twice returns nil the second time. After Close every other method on this Client returns ErrClosed.

func (*Client) IssueSession added in v1.57.0

func (c *Client) IssueSession(ctx context.Context, username, sid, ip string) (string, error)

IssueSession sends a SESSION command to the master listener and returns the one-time token bound to username. The token is scoped to the "lmtp" service and must be consumed by a VERIFY call on the client listener within the token TTL.

sid is the anvil session ID already registered for this delivery; ip is the originating MTA address (both are recorded in the audit log but do not affect token validity).

func (*Client) IterateUsers

func (c *Client) IterateUsers(ctx context.Context) ([]string, error)

IterateUsers runs a LIST and collects every streamed username until the server emits the DONE marker. Backends that do not support enumeration return a FAIL line; this method surfaces that as a typed error (compare its message against the wire reason if needed).

func (*Client) PassdbLookup

func (c *Client) PassdbLookup(ctx context.Context, username string) (*protocol.UserInfo, error)

PassdbLookup runs a PASS lookup. The master-protocol handler for PASS returns `FAIL reason=PASS not implemented` until Phase AUTH-2 ships Passdb.LookupCredentials; this method therefore always returns ErrNotImplemented. The full method exists in PR 3 so consumers can ship the typed call surface unchanged when AUTH-2 flips the implementation on.

func (*Client) Userdb

func (c *Client) Userdb(ctx context.Context, username string) (*protocol.UserInfo, error)

Userdb runs a USER lookup for username. Returns:

  • (ui, nil) — backend hit; ui populated from the wire fields
  • (nil, nil) — backend miss (master responded NOTFOUND)
  • (nil, err) — wire / parse / backend error

Mirrors the protocol.Userdb contract so callers chaining Client.Userdb with other Userdb implementations see the same "not found is nil/nil" semantics.

Jump to

Keyboard shortcuts

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