hostfuncs

package
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package hostfuncs provides pure Go implementations of host function logic. These implementations have NO WASM runtime dependencies (no wazero/wasmtime). They can be used by any WASM plugin host, not just Reglet.

The implementations are designed to be thin wrappers that consuming applications (like Reglet) can call from their WASM host function handlers. The SDK handles the core logic; the host handles wire format encoding/decoding and memory management.

Package hostfuncs provides pure Go implementations of host function logic. These implementations have NO WASM runtime dependencies (no wazero/wasmtime). They can be used by any WASM plugin host, not just Reglet.

Index

Constants

View Source
const DefaultMaxOutputSize = 10 * 1024 * 1024

DefaultMaxOutputSize is the default limit for stdout/stderr from exec commands (10MB). Prevents excessive memory usage from long-running commands with verbose output.

View Source
const DefaultMaxRequestSize = 1 * 1024 * 1024

DefaultMaxRequestSize limits the size of incoming requests (1MB). This prevents malicious WASM modules from triggering OOM by claiming huge request sizes.

Variables

This section is empty.

Functions

func CapabilityPluginNameFromContext added in v0.2.2

func CapabilityPluginNameFromContext(ctx context.Context) (string, bool)

CapabilityPluginNameFromContext retrieves the plugin name from the context.

func DetectExecutionType added in v0.2.2

func DetectExecutionType(command string, args []string) executionType

DetectExecutionType determines if the command is dangerous and what type.

func GetExecutionTypeDescription added in v0.2.2

func GetExecutionTypeDescription(command string, args []string) string

GetExecutionTypeDescription returns a human-readable description of the execution type.

func IsAlwaysBlockedEnv added in v0.2.2

func IsAlwaysBlockedEnv(upperKey string) bool

IsAlwaysBlockedEnv checks if an environment variable key is always blocked.

func IsDangerousExecution added in v0.2.2

func IsDangerousExecution(command string, args []string) bool

IsDangerousExecution returns true if the command represents a potentially dangerous execution. This is useful for capability checking when shell/interpreter execution is detected.

func IsKnownInterpreter added in v0.2.2

func IsKnownInterpreter(command string) bool

IsKnownInterpreter detects if a command is a known scripting interpreter.

func IsShellExecution added in v0.2.2

func IsShellExecution(command string) bool

IsShellExecution detects if a command is a shell invocation. Common shells: sh, bash, dash, zsh, ksh, csh, tcsh, fish.

func SanitizeEnv added in v0.2.2

func SanitizeEnv(ctx context.Context, env []string, pluginName string, capGetter CapabilityGetter) []string

SanitizeEnv filters environment variables according to security tiers. Tier 1 (always blocked): Variables like LD_PRELOAD that are never allowed. Tier 2 (capability-gated): Variables like PATH that require exec:env:<VAR> capability. Returns the sanitized environment slice.

func WithCapabilityPluginName added in v0.2.2

func WithCapabilityPluginName(ctx context.Context, name string) context.Context

WithCapabilityPluginName adds the plugin name to the context.

Types

type BoundedBuffer added in v0.2.2

type BoundedBuffer struct {
	Truncated bool
	// contains filtered or unexported fields
}

BoundedBuffer is a bytes.Buffer wrapper that limits the size of written data. It implements io.Writer and can be used with exec.Cmd's Stdout/Stderr.

func NewBoundedBuffer added in v0.2.2

func NewBoundedBuffer(limit int) *BoundedBuffer

NewBoundedBuffer creates a new BoundedBuffer with the specified limit.

func (*BoundedBuffer) Bytes added in v0.2.2

func (b *BoundedBuffer) Bytes() []byte

Bytes returns the buffer contents as a byte slice.

func (*BoundedBuffer) Len added in v0.2.2

func (b *BoundedBuffer) Len() int

Len returns the current length of the buffer.

func (*BoundedBuffer) Reset added in v0.2.2

func (b *BoundedBuffer) Reset()

Reset resets the buffer and clears the Truncated flag.

func (*BoundedBuffer) String added in v0.2.2

func (b *BoundedBuffer) String() string

String returns the buffer contents as a string.

func (*BoundedBuffer) Write added in v0.2.2

func (b *BoundedBuffer) Write(p []byte) (n int, err error)

Write implements io.Writer. It writes data up to the limit and then silently discards any additional data. The Truncated field is set to true if any data was discarded.

type ByteHandler

type ByteHandler func(context.Context, []byte) ([]byte, error)

ByteHandler is a function that accepts raw bytes (JSON) and returns raw bytes (JSON). This is the common interface that WASM runtimes can easily use.

func NewJSONHandler

func NewJSONHandler[Req any, Resp any](fn HostFunc[Req, Resp]) ByteHandler

NewJSONHandler wraps a typed HostFunc into a ByteHandler. It handles the JSON unmarshalling of the request and marshaling of the response.

For infrastructure failures (malformed JSON, serialization errors), the handler returns a structured ErrorResponse JSON instead of a Go error. This ensures plugins always receive valid JSON and prevents WASM runtime traps.

Usage:

execHandler := hostfuncs.NewJSONHandler(func(ctx context.Context, req hostfuncs.ExecCommandRequest) hostfuncs.ExecCommandResponse {
    return hostfuncs.PerformExecCommand(ctx, req)
})

// In WASM runtime handler:
reqBytes := readMemory(ptr, len)
respBytes, err := execHandler(ctx, reqBytes)
writeMemory(respBytes)

type CapabilityChecker added in v0.2.2

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

CapabilityChecker checks if operations are allowed based on granted capabilities. It uses the SDK's typed Policy for capability enforcement.

func NewCapabilityChecker added in v0.2.2

func NewCapabilityChecker(caps map[string]*entities.GrantSet, opts ...CapabilityCheckerOption) *CapabilityChecker

NewCapabilityChecker creates a new capability checker with the given capabilities. The cwd is obtained at construction time to avoid side-effects during capability checks.

func (*CapabilityChecker) AllowsPrivateNetwork added in v0.2.2

func (c *CapabilityChecker) AllowsPrivateNetwork(pluginName string) bool

AllowsPrivateNetwork checks if the plugin is allowed to access private network addresses.

func (*CapabilityChecker) Check added in v0.2.2

func (c *CapabilityChecker) Check(pluginName, kind, pattern string) error

Check verifies if a requested capability is granted for a specific plugin. This method parses the WASM protocol pattern format used by plugins:

  • network: "outbound:<port>" or "outbound:<host>"
  • fs: "read:<path>" or "write:<path>"
  • env: "<variable>"
  • exec: "<command>"

func (*CapabilityChecker) CheckEnvironment added in v0.2.2

func (c *CapabilityChecker) CheckEnvironment(pluginName string, req entities.EnvironmentRequest) error

CheckEnvironment performs typed environment capability check.

func (*CapabilityChecker) CheckExec added in v0.2.2

func (c *CapabilityChecker) CheckExec(pluginName string, req entities.ExecCapabilityRequest) error

CheckExec performs typed exec capability check.

func (*CapabilityChecker) CheckFileSystem added in v0.2.2

func (c *CapabilityChecker) CheckFileSystem(pluginName string, req entities.FileSystemRequest) error

CheckFileSystem performs typed filesystem capability check.

func (*CapabilityChecker) CheckNetwork added in v0.2.2

func (c *CapabilityChecker) CheckNetwork(pluginName string, req entities.NetworkRequest) error

CheckNetwork performs typed network capability check.

func (*CapabilityChecker) CheckNetworkConnection added in v0.2.5

func (c *CapabilityChecker) CheckNetworkConnection(pluginName, host string, port int) error

CheckNetworkConnection checks if a specific network connection (host:port) is allowed. It uses EvaluateNetwork (silent) first to avoid logspam, and only checks loudly if denied.

func (*CapabilityChecker) ToCapabilityGetter added in v0.2.2

func (c *CapabilityChecker) ToCapabilityGetter(pluginName string) CapabilityGetter

ToCapabilityGetter returns a CapabilityGetter function that uses this checker. This allows integration with the exec security features.

type CapabilityCheckerOption added in v0.2.2

type CapabilityCheckerOption func(*capabilityCheckerConfig)

CapabilityCheckerOption configures a CapabilityChecker.

func WithCapabilitySymlinkResolution added in v0.2.2

func WithCapabilitySymlinkResolution(enabled bool) CapabilityCheckerOption

WithCapabilitySymlinkResolution enables or disables symlink resolution.

func WithCapabilityWorkingDirectory added in v0.2.2

func WithCapabilityWorkingDirectory(cwd string) CapabilityCheckerOption

WithCapabilityWorkingDirectory sets the working directory for path resolution.

type CapabilityGetter added in v0.2.2

type CapabilityGetter func(pluginName, capability string) bool

CapabilityGetter is a function that checks if a specific capability is granted. It takes a plugin name and capability pattern (e.g., "env:PATH") and returns true if allowed.

type DNSError

type DNSError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

DNSError represents a DNS lookup error.

func (*DNSError) Error

func (e *DNSError) Error() string

Error implements the error interface.

type DNSLookupRequest

type DNSLookupRequest struct {
	// Hostname is the domain name to resolve.
	Hostname string `json:"hostname"`

	// RecordType is the DNS record type (A, AAAA, CNAME, MX, TXT, NS).
	RecordType string `json:"type"`

	// Nameserver is the optional custom nameserver address (e.g., "8.8.8.8:53").
	// If empty, the system default resolver is used.
	Nameserver string `json:"nameserver,omitempty"`

	// Timeout is the query timeout in milliseconds. Default is 5000 (5s).
	Timeout int `json:"timeout_ms,omitempty"`
}

DNSLookupRequest contains parameters for a DNS lookup operation.

type DNSLookupResponse

type DNSLookupResponse struct {
	// Error contains error information if the lookup failed.
	Error *DNSError `json:"error,omitempty"`

	// Records contains the resolved records (IP addresses, strings, etc.).
	Records []string `json:"records,omitempty"`

	// MXRecords contains MX-specific records with preference values.
	MXRecords []MXRecord `json:"mx_records,omitempty"`
}

DNSLookupResponse contains the result of a DNS lookup operation.

func PerformDNSLookup

func PerformDNSLookup(ctx context.Context, req DNSLookupRequest, opts ...DNSOption) DNSLookupResponse

PerformDNSLookup performs a DNS lookup for the given request. This is a pure Go implementation with no WASM runtime dependencies.

Example usage from a WASM host:

func handleDNSLookup(req hostfuncs.DNSLookupRequest) hostfuncs.DNSLookupResponse {
    return hostfuncs.PerformDNSLookup(ctx, req)
}

type DNSOption

type DNSOption func(*dnsConfig)

DNSOption is a functional option for configuring DNS lookup behavior.

func WithDNSLookupTimeout

func WithDNSLookupTimeout(d time.Duration) DNSOption

WithDNSLookupTimeout sets the DNS query timeout.

func WithDNSNameserver

func WithDNSNameserver(ns string) DNSOption

WithDNSNameserver sets a custom nameserver for the lookup.

type ErrorResponse

type ErrorResponse struct {
	// Error is a machine-readable error type identifier (e.g., "VALIDATION_ERROR", "INTERNAL_ERROR").
	Error string `json:"error"`

	// Message is a human-readable error description.
	Message string `json:"message"`

	// Code is a numeric error code (e.g., 400, 500).
	Code int `json:"code"`
}

ErrorResponse represents a structured error that can be returned as JSON to plugins. This ensures plugins receive consistent, parseable errors instead of causing WASM traps.

func NewInternalError

func NewInternalError(message string) ErrorResponse

NewInternalError creates an error response for unexpected failures.

func NewNotFoundError

func NewNotFoundError(name string) ErrorResponse

NewNotFoundError creates an error response for unknown handler names.

func NewPanicError

func NewPanicError(panicValue any) ErrorResponse

NewPanicError creates an error response for recovered panics.

func NewValidationError

func NewValidationError(message string) ErrorResponse

NewValidationError creates an error response for bad input (e.g., malformed JSON).

func (ErrorResponse) ToJSON

func (e ErrorResponse) ToJSON() []byte

ToJSON serializes the ErrorResponse to JSON bytes. Returns nil if serialization fails (which should never happen for this simple type).

type ExecCommandRequest

type ExecCommandRequest struct {
	// Command is the command to execute.
	Command string `json:"command"`

	// Args contains command arguments.
	Args []string `json:"args"`

	// Dir is the working directory.
	Dir string `json:"dir,omitempty"`

	// Env contains environment variables (KEY=VALUE).
	Env []string `json:"env,omitempty"`

	// Timeout is the execution timeout in milliseconds. Default is 30000 (30s).
	Timeout int `json:"timeout_ms,omitempty"`
}

ExecCommandRequest contains parameters for a command execution.

type ExecCommandResponse

type ExecCommandResponse struct {
	// Error contains error information if execution failed to start.
	Error *ExecError `json:"error,omitempty"`

	// Stdout is the standard output.
	Stdout string `json:"stdout"`

	// Stderr is the standard error.
	Stderr string `json:"stderr"`

	// DurationMs is the execution duration in milliseconds.
	DurationMs int64 `json:"duration_ms,omitempty"`

	// ExitCode is the exit code.
	ExitCode int `json:"exit_code"`

	// IsTimeout indicates if the command timed out.
	IsTimeout bool `json:"is_timeout,omitempty"`

	// StdoutTruncated indicates if stdout was truncated due to size limits.
	StdoutTruncated bool `json:"stdout_truncated,omitempty"`

	// StderrTruncated indicates if stderr was truncated due to size limits.
	StderrTruncated bool `json:"stderr_truncated,omitempty"`
}

ExecCommandResponse contains the result of a command execution.

func PerformExecCommand

func PerformExecCommand(ctx context.Context, req ExecCommandRequest, opts ...ExecOption) ExecCommandResponse

PerformExecCommand executes a command on the host. This is a pure Go implementation with no WASM runtime dependencies.

Security features can be enabled via options:

  • WithEnvSanitization: blocks dangerous environment variables
  • WithIsolatedEnv: prevents host environment leakage
  • WithMaxOutputSize: limits output to prevent OOM

func PerformSecureExecCommand added in v0.2.2

func PerformSecureExecCommand(ctx context.Context, req ExecCommandRequest, pluginName string, capGetter CapabilityGetter, opts ...ExecOption) ExecCommandResponse

PerformSecureExecCommand executes a command with full security features enabled. This is a convenience function that enables all security features:

  • Environment sanitization
  • Isolated environment (no host env leakage)
  • Output size limiting

Use this for executing commands from untrusted sources (e.g., WASM plugins).

type ExecError

type ExecError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

ExecError represents an execution error.

func (*ExecError) Error

func (e *ExecError) Error() string

Error implements the error interface.

type ExecOption

type ExecOption func(*execConfig)

ExecOption is a functional option for configuring execution behavior.

func WithEnvSanitization added in v0.2.2

func WithEnvSanitization(pluginName string, capGetter CapabilityGetter) ExecOption

WithEnvSanitization enables environment variable sanitization. This blocks dangerous environment variables like LD_PRELOAD and requires explicit capabilities for sensitive variables like PATH.

func WithExecTimeout

func WithExecTimeout(d time.Duration) ExecOption

WithExecTimeout sets the execution timeout.

func WithIsolatedEnv added in v0.2.2

func WithIsolatedEnv() ExecOption

WithIsolatedEnv ensures the command runs with only explicitly provided environment variables, preventing host environment leakage.

func WithMaxOutputSize added in v0.2.2

func WithMaxOutputSize(size int) ExecOption

WithMaxOutputSize sets the maximum output size for stdout/stderr. If output exceeds this size, it will be truncated.

type HTTPError

type HTTPError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

HTTPError represents an HTTP request error.

func (*HTTPError) Error

func (e *HTTPError) Error() string

Error implements the error interface.

type HTTPOption

type HTTPOption func(*httpConfig)

HTTPOption is a functional option for configuring HTTP request behavior.

func WithHTTPFollowRedirects

func WithHTTPFollowRedirects(follow bool) HTTPOption

WithHTTPFollowRedirects controls whether to follow redirects.

func WithHTTPMaxBodySize

func WithHTTPMaxBodySize(size int64) HTTPOption

WithHTTPMaxBodySize sets the maximum response body size.

func WithHTTPMaxRedirects

func WithHTTPMaxRedirects(n int) HTTPOption

WithHTTPMaxRedirects sets the maximum number of redirects to follow.

func WithHTTPRequestTimeout

func WithHTTPRequestTimeout(d time.Duration) HTTPOption

WithHTTPRequestTimeout sets the HTTP request timeout.

func WithHTTPSSRFProtection added in v0.2.2

func WithHTTPSSRFProtection(allowPrivate bool) HTTPOption

WithHTTPSSRFProtection enables DNS pinning and SSRF protection. When enabled, each request resolves DNS once, validates the IP, and connects directly to that IP (preventing DNS rebinding attacks). Private/reserved IPs are blocked unless allowPrivate is true.

type HTTPRequest

type HTTPRequest struct {
	// Headers contains request headers.
	Headers map[string]string `json:"headers,omitempty"`

	// FollowRedirects controls whether to follow redirects. Default is true.
	FollowRedirects *bool `json:"follow_redirects,omitempty"`

	// Method is the HTTP method (GET, POST, PUT, DELETE, etc.).
	Method string `json:"method"`

	// URL is the target URL.
	URL string `json:"url"`

	// Body is the request body (for POST, PUT, etc.).
	Body []byte `json:"body,omitempty"`

	// Timeout is the request timeout in milliseconds. Default is 30000 (30s).
	Timeout int `json:"timeout_ms,omitempty"`

	// MaxRedirects is the maximum number of redirects to follow. Default is 10.
	MaxRedirects int `json:"max_redirects,omitempty"`
}

HTTPRequest contains parameters for an HTTP request.

type HTTPResponse

type HTTPResponse struct {
	// Headers contains response headers.
	Headers map[string][]string `json:"headers,omitempty"`

	// Error contains error information if the request failed.
	Error *HTTPError `json:"error,omitempty"`

	// Body is the response body.
	Body []byte `json:"body,omitempty"`

	// StatusCode is the HTTP status code.
	StatusCode int `json:"status_code"`

	// LatencyMs is the request latency in milliseconds.
	LatencyMs int64 `json:"latency_ms,omitempty"`

	// BodyTruncated indicates if the body was truncated due to size limits.
	BodyTruncated bool `json:"body_truncated,omitempty"`

	// Proto is the protocol version (e.g. "HTTP/1.1").
	Proto string `json:"proto,omitempty"`
}

HTTPResponse contains the result of an HTTP request.

func PerformHTTPRequest

func PerformHTTPRequest(ctx context.Context, req HTTPRequest, opts ...HTTPOption) HTTPResponse

PerformHTTPRequest performs an HTTP request. This is a pure Go implementation with no WASM runtime dependencies.

Example usage from a WASM host:

func handleHTTPRequest(req hostfuncs.HTTPRequest) hostfuncs.HTTPResponse {
    return hostfuncs.PerformHTTPRequest(ctx, req)
}

type HandlerRegistry

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

HandlerRegistry is an immutable collection of named host functions. Once created via NewRegistry, handlers cannot be added or removed. This ensures thread safety and lock-free lookups during execution.

func NewRegistry

func NewRegistry(opts ...RegistryOption) (*HandlerRegistry, error)

NewRegistry creates an immutable HandlerRegistry with the given options. Returns an error if any handler name is registered twice.

Example usage:

registry, err := NewRegistry(
    WithMiddleware(PanicRecoveryMiddleware()),
    WithBundle(AllBundles()),
    WithHandler("custom", customHandler),
)

func (*HandlerRegistry) Has

func (r *HandlerRegistry) Has(name string) bool

Has returns true if a handler with the given name is registered.

func (*HandlerRegistry) Invoke

func (r *HandlerRegistry) Invoke(ctx context.Context, name string, payload []byte) ([]byte, error)

Invoke dispatches a host function call by name. Returns the JSON response bytes, or an ErrorResponse JSON if the handler is not found.

func (*HandlerRegistry) Names

func (r *HandlerRegistry) Names() []string

Names returns a sorted list of all registered handler names.

type HostContext

type HostContext interface {
	context.Context

	// FunctionName returns the name of the host function being invoked.
	FunctionName() string

	// SetValue stores a request-scoped value. Unlike context.WithValue,
	// this mutates the existing HostContext for performance.
	SetValue(key, value any)

	// GetValue retrieves a request-scoped value set by SetValue.
	GetValue(key any) (value any, ok bool)
}

HostContext wraps a standard context.Context with host function-specific helpers. It provides access to the invoked function name and allows middleware to store request-scoped values without polluting the standard context.

func HostContextFrom

func HostContextFrom(ctx context.Context, funcName string) HostContext

HostContextFrom extracts a HostContext from a context.Context. If the context is already a HostContext, it is returned directly. Otherwise, a new HostContext is created wrapping the given context.

func NewHostContext

func NewHostContext(ctx context.Context, funcName string) HostContext

NewHostContext creates a new HostContext wrapping the given context.

type HostFunc

type HostFunc[Req any, Resp any] func(context.Context, Req) Resp

HostFunc is a generic function signature for host functions. It accepts a context and a typed request, and returns a typed response.

type HostFuncBundle

type HostFuncBundle interface {
	// Handlers returns a map of handler names to ByteHandler functions.
	Handlers() map[string]ByteHandler
}

HostFuncBundle is a pre-configured set of related host functions. Bundles allow registering multiple handlers at once for common use cases.

func AllBundles

func AllBundles() HostFuncBundle

AllBundles returns a bundle containing all built-in host functions. Includes: dns_lookup, tcp_connect, http_request, exec_command, smtp_send, ssrf_check.

func ExecBundle

func ExecBundle() HostFuncBundle

ExecBundle returns a bundle with command execution host functions: exec_command.

func NetfilterBundle

func NetfilterBundle() HostFuncBundle

NetfilterBundle returns a bundle with network security host functions: ssrf_check.

func NetworkBundle

func NetworkBundle() HostFuncBundle

NetworkBundle returns a bundle with network-related host functions: dns_lookup, tcp_connect, http_request.

func SMTPBundle

func SMTPBundle() HostFuncBundle

SMTPBundle returns a bundle with email-related host functions: smtp_connect.

type MXRecord

type MXRecord struct {
	Host string `json:"host"`
	Pref uint16 `json:"pref"`
}

MXRecord represents a DNS MX record.

type Middleware

type Middleware func(next ByteHandler) ByteHandler

Middleware is a function that wraps a ByteHandler to add cross-cutting behavior. Middleware executes in FIFO order (first registered wraps first, onion model).

Example usage:

loggingMiddleware := func(next ByteHandler) ByteHandler {
    return func(ctx context.Context, payload []byte) ([]byte, error) {
        log.Printf("invoking handler...")
        return next(ctx, payload)
    }
}

func LoggingMiddleware

func LoggingMiddleware(logFn func(format string, args ...any)) Middleware

LoggingMiddleware returns a middleware that logs host function invocations. This is provided as an example; production code should use a structured logger.

func PanicRecoveryMiddleware

func PanicRecoveryMiddleware() Middleware

PanicRecoveryMiddleware returns a middleware that catches panics and converts them to structured ErrorResponse JSON instead of crashing the host.

type NetfilterOption

type NetfilterOption func(*netfilterConfig)

NetfilterOption is a functional option for configuring netfilter behavior.

func WithAllowedPorts

func WithAllowedPorts(ports ...int) NetfilterOption

WithAllowedPorts restricts connections to specific ports.

func WithAllowlist

func WithAllowlist(addresses ...string) NetfilterOption

WithAllowlist sets explicitly allowed addresses or CIDRs. Allowed addresses bypass all other checks.

func WithBlockLinkLocal

func WithBlockLinkLocal(block bool) NetfilterOption

WithBlockLinkLocal enables/disables blocking of link-local addresses.

func WithBlockLocalhost

func WithBlockLocalhost(block bool) NetfilterOption

WithBlockLocalhost enables/disables blocking of localhost/loopback.

func WithBlockPrivate

func WithBlockPrivate(block bool) NetfilterOption

WithBlockPrivate enables/disables blocking of RFC 1918 private addresses.

func WithBlockedPorts

func WithBlockedPorts(ports ...int) NetfilterOption

WithBlockedPorts blocks specific ports.

func WithBlocklist

func WithBlocklist(addresses ...string) NetfilterOption

WithBlocklist sets explicitly blocked addresses or CIDRs. Blocklist is checked before other rules.

func WithResolveDNS

func WithResolveDNS(resolve bool) NetfilterOption

WithResolveDNS enables/disables DNS resolution before checking.

type NetfilterResult

type NetfilterResult struct {
	// Reason provides the reason if the address was blocked.
	Reason string `json:"reason,omitempty"`

	// ResolvedIP is the resolved IP address if DNS resolution was performed.
	ResolvedIP string `json:"resolved_ip,omitempty"`

	// Allowed indicates whether the address is allowed.
	Allowed bool `json:"allowed"`
}

NetfilterResult represents the result of an address validation.

func ValidateAddress

func ValidateAddress(address string, opts ...NetfilterOption) NetfilterResult

ValidateAddress validates whether an address is allowed for outbound connections. This is the primary SSRF protection mechanism.

SECURITY CRITICAL: This function MUST be called before any outbound network connection.

Example usage:

result := hostfuncs.ValidateAddress("example.com:443")
if !result.Allowed {
    return fmt.Errorf("blocked: %s", result.Reason)
}

type RegistryOption

type RegistryOption func(*registryBuilder)

RegistryOption is a functional option for configuring a HandlerRegistry.

func WithBundle

func WithBundle(bundle HostFuncBundle) RegistryOption

WithBundle registers all handlers from a bundle.

func WithByteHandler

func WithByteHandler(name string, handler ByteHandler) RegistryOption

WithByteHandler registers a raw ByteHandler with the given name. Use WithHandler for type-safe registration with automatic JSON handling.

func WithHandler

func WithHandler[Req any, Resp any](name string, fn HostFunc[Req, Resp]) RegistryOption

WithHandler registers a typed host function with automatic JSON handling. The handler will be wrapped with NewJSONHandler for JSON serialization.

Example usage:

WithHandler("custom_func", func(ctx context.Context, req MyRequest) MyResponse {
    return MyResponse{Result: req.Input}
})

func WithMiddleware

func WithMiddleware(mw ...Middleware) RegistryOption

WithMiddleware adds middleware to the registry. Middleware executes in FIFO order (first added wraps first).

type SMTPConnectRequest

type SMTPConnectRequest struct {
	// Host is the SMTP server hostname.
	Host string `json:"host"`

	// Port is the SMTP server port (typically 25, 465, or 587).
	Port int `json:"port"`

	// UseTLS indicates whether to use implicit TLS (port 465).
	UseTLS bool `json:"use_tls,omitempty"`

	// UseSTARTTLS indicates whether to upgrade to TLS via STARTTLS (port 587).
	UseSTARTTLS bool `json:"use_starttls,omitempty"`

	// Timeout is the connection timeout in milliseconds. Default is 30000 (30s).
	Timeout int `json:"timeout_ms,omitempty"`
}

SMTPConnectRequest contains parameters for an SMTP connection test.

type SMTPConnectResponse

type SMTPConnectResponse struct {
	// Error contains error information if the connection failed.
	Error *SMTPError `json:"error,omitempty"`

	// Banner is the SMTP server banner (greeting message).
	Banner string `json:"banner,omitempty"`

	// TLSVersion is the TLS version if TLS is used.
	TLSVersion string `json:"tls_version,omitempty"`

	// TLSCipherSuite is the cipher suite used for TLS.
	TLSCipherSuite string `json:"tls_cipher_suite,omitempty"`

	// TLSServerName is the server name used for TLS (SNI).
	TLSServerName string `json:"tls_server_name,omitempty"`

	// LatencyMs is the connection latency in milliseconds.
	LatencyMs int64 `json:"latency_ms,omitempty"`

	// Connected indicates whether the connection was successful.
	Connected bool `json:"connected"`
}

SMTPConnectResponse contains the result of an SMTP connection test.

func PerformSMTPConnect

func PerformSMTPConnect(ctx context.Context, req SMTPConnectRequest, opts ...SMTPOption) SMTPConnectResponse

PerformSMTPConnect tests SMTP connectivity to the specified server. This is a pure Go implementation with no WASM runtime dependencies.

Example usage from a WASM host:

func handleSMTPConnect(req hostfuncs.SMTPConnectRequest) hostfuncs.SMTPConnectResponse {
    return hostfuncs.PerformSMTPConnect(ctx, req)
}

type SMTPError

type SMTPError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

SMTPError represents an SMTP connection error.

func (*SMTPError) Error

func (e *SMTPError) Error() string

Error implements the error interface.

type SMTPOption

type SMTPOption func(*smtpConfig)

SMTPOption is a functional option for configuring SMTP connection behavior.

func WithSMTPSSRFProtection added in v0.2.2

func WithSMTPSSRFProtection(allowPrivate bool) SMTPOption

WithSMTPSSRFProtection enables SSRF protection. When enabled, private/reserved IPs are blocked unless allowPrivate is true. DNS is resolved once and the resolved IP is used for the connection (prevents DNS rebinding).

func WithSMTPTLSConfig

func WithSMTPTLSConfig(cfg *tls.Config) SMTPOption

WithSMTPTLSConfig sets custom TLS configuration.

func WithSMTPTimeout

func WithSMTPTimeout(d time.Duration) SMTPOption

WithSMTPTimeout sets the SMTP connection timeout.

type SSRFCheckRequest

type SSRFCheckRequest struct {
	// Address is the target address to validate (host:port format).
	Address string `json:"address"`
}

SSRFCheckRequest is the request type for SSRF validation.

type SSRFCheckResponse

type SSRFCheckResponse struct {
	// Reason explains why the address was blocked (if not allowed).
	Reason string `json:"reason,omitempty"`

	// ResolvedIP is the resolved IP address if DNS resolution was performed.
	ResolvedIP string `json:"resolved_ip,omitempty"`

	// Allowed indicates whether the address is safe for outbound connections.
	Allowed bool `json:"allowed"`
}

SSRFCheckResponse is the response type for SSRF validation.

type TCPConnectRequest

type TCPConnectRequest struct {
	// TLSConfig is an optional custom TLS configuration.
	// This field is not marshaled to JSON and is intended for internal use
	// or when calling PerformTCPConnect directly from Go code.
	TLSConfig *tls.Config `json:"-"`

	// Host is the target hostname or IP address.
	Host string `json:"host"`

	// Port is the target port number.
	Port int `json:"port"`

	// Timeout is the connection timeout in milliseconds. Default is 5000 (5s).
	Timeout int `json:"timeout_ms,omitempty"`

	// UseTLS indicates whether to use TLS for the connection.
	UseTLS bool `json:"use_tls,omitempty"`
}

TCPConnectRequest contains parameters for a TCP connection test.

type TCPConnectResponse

type TCPConnectResponse struct {
	// Error contains error information if the connection failed.
	Error *TCPError `json:"error,omitempty"`

	// RemoteAddr is the resolved remote address if connected.
	RemoteAddr string `json:"remote_addr,omitempty"`

	// TLSVersion is the TLS version used (e.g. "TLS 1.2").
	TLSVersion string `json:"tls_version,omitempty"`

	// TLSCipherSuite is the cipher suite used.
	TLSCipherSuite string `json:"tls_cipher_suite,omitempty"`

	// TLSServerName is the server name from the TLS handshake.
	TLSServerName string `json:"tls_server_name,omitempty"`

	// TLSCertSubject is the subject of the peer certificate.
	TLSCertSubject string `json:"tls_cert_subject,omitempty"`

	// TLSCertIssuer is the issuer of the peer certificate.
	TLSCertIssuer string `json:"tls_cert_issuer,omitempty"`

	// TLSCertExpiry is the expiration time of the peer certificate.
	TLSCertExpiry string `json:"tls_cert_expiry,omitempty"`
	// LatencyMs is the connection latency in milliseconds.
	LatencyMs int64 `json:"latency_ms,omitempty"`
	// Connected indicates whether the connection was successful.
	Connected bool `json:"connected"`
}

TCPConnectResponse contains the result of a TCP connection test.

func PerformTCPConnect

func PerformTCPConnect(ctx context.Context, req TCPConnectRequest, opts ...TCPOption) TCPConnectResponse

PerformTCPConnect tests TCP connectivity to the specified host and port. This is a pure Go implementation with no WASM runtime dependencies.

Example usage from a WASM host:

func handleTCPConnect(req hostfuncs.TCPConnectRequest) hostfuncs.TCPConnectResponse {
    return hostfuncs.PerformTCPConnect(ctx, req)
}

type TCPError

type TCPError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

TCPError represents a TCP connection error.

func (*TCPError) Error

func (e *TCPError) Error() string

Error implements the error interface.

type TCPOption

type TCPOption func(*tcpConfig)

TCPOption is a functional option for configuring TCP connection behavior.

func WithTCPSSRFProtection added in v0.2.2

func WithTCPSSRFProtection(allowPrivate bool) TCPOption

WithTCPSSRFProtection enables SSRF protection. When enabled, private/reserved IPs are blocked unless allowPrivate is true. DNS is resolved once and the resolved IP is used for the connection (prevents DNS rebinding).

func WithTCPTimeout

func WithTCPTimeout(d time.Duration) TCPOption

WithTCPTimeout sets the TCP connection timeout.

Jump to

Keyboard shortcuts

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