smb

package
v0.0.94 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2025 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Overview

Package smb provides SMB penetration testing functionality including secdump operations This file contains utility functions adapted from github.com/jfjallid/go-secdump

Original copyright notice: MIT License Copyright (c) 2023 Jonas Fjällid

Index

Constants

View Source
const (
	RegNone                     = 0
	RegSZ                       = 1
	RegExpandSZ                 = 2
	RegBinary                   = 3
	RegDword                    = 4
	RegDwordLittleEndian        = 4
	RegDwordBigEndian           = 5
	RegLink                     = 6
	RegMultiSZ                  = 7
	RegResourceList             = 8
	RegFullResourceDescriptor   = 9
	RegResourceRequirementsList = 10
	RegQword                    = 11
	RegQwordLittleEndian        = 11
)

Registry data type constants

View Source
const (
	WinUnknown      byte = 0x00
	WinXP           byte = 0x05
	WinVista        byte = 0x06
	Win7            byte = 0x07
	Win8            byte = 0x08
	Win81           byte = 0x09
	Win10           byte = 0x0A
	Win11           byte = 0x0B
	WinServer2003   byte = 0x10
	WinServer2008   byte = 0x11
	WinServer2008R2 byte = 0x12
	WinServer2012   byte = 0x13
	WinServer2012R2 byte = 0x14
	WinServer2016   byte = 0x15
	WinServer2019   byte = 0x16
	WinServer2022   byte = 0x17
)

Windows OS version constants (byte values for crypto operations)

Variables

View Source
var (
	S1         = []byte("!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\x00")
	S2         = []byte("0123456789012345678901234567890123456789\x00")
	S3         = []byte("NTPASSWORD\x00")
	BootKey    []byte
	LSAKey     []byte
	NLKMKey    []byte
	VistaStyle bool
)

Global variables for cryptographic operations

View Source
var (
	DefaultOutputPollInterval = 500 * time.Millisecond
	DefaultOutputPollTimeout  = 60 * time.Second
)

Functions

func BackupRegistryKey added in v0.0.51

func BackupRegistryKey(rc *RegistryConnection, key *RegistryKey) ([]byte, error)

BackupRegistryKey creates a backup of a registry key and its subkeys

func BytesToHex added in v0.0.51

func BytesToHex(data []byte) string

BytesToHex converts bytes to hex string

func BytesToUint32LE added in v0.0.51

func BytesToUint32LE(data []byte) uint32

BytesToUint32LE converts little-endian bytes to uint32

func BytesToUint64LE added in v0.0.51

func BytesToUint64LE(data []byte) uint64

BytesToUint64LE converts little-endian bytes to uint64

func CalcMachineAESKeys added in v0.0.51

func CalcMachineAESKeys(hostname, domain string, hexPass []byte) ([]byte, []byte, error)

CalcMachineAESKeys calculates AES keys for machine account (go-secdump compatible)

func CalculateNTHash added in v0.0.51

func CalculateNTHash(password string) string

CalculateNTHash calculates NT hash from password

func CheckRegistryKeyAccess added in v0.0.51

func CheckRegistryKeyAccess(rc *RegistryConnection, key *RegistryKey, accessMask uint32) (bool, error)

CheckRegistryKeyAccess checks if we have specific access to a registry key

func CleanupString added in v0.0.51

func CleanupString(s string) string

CleanupString removes null bytes and trims whitespace

func CompareBytes added in v0.0.51

func CompareBytes(a, b []byte) bool

CompareBytes compares two byte slices

func DecryptAES added in v0.0.51

func DecryptAES(key, ciphertext, iv []byte) ([]byte, error)

DecryptAES decrypts data using AES with CBC mode (go-secdump compatible)

func DecryptAESHash added in v0.0.51

func DecryptAESHash(data, iv, syskey []byte, rid uint32) ([]byte, error)

DecryptAESHash decrypts AES-encrypted NT hash using go-secdump's exact implementation

func DecryptAESSysKey added in v0.0.51

func DecryptAESSysKey(bootKey, encSysKey, sysKeyIV []byte) ([]byte, error)

DecryptAESSysKey decrypts system key using AES

func DecryptDES added in v0.0.51

func DecryptDES(key, ciphertext []byte) ([]byte, error)

DecryptDES decrypts data using DES

func DecryptRC4 added in v0.0.51

func DecryptRC4(key, ciphertext []byte) ([]byte, error)

DecryptRC4 decrypts data using RC4

func DecryptRC4Hash added in v0.0.51

func DecryptRC4Hash(data, syskey []byte, rid uint32) ([]byte, error)

DecryptRC4Hash decrypts RC4-encrypted NT hash using go-secdump's exact implementation

func DecryptRC4SysKey added in v0.0.51

func DecryptRC4SysKey(bootKey, encSysKey, sysKeyIV []byte) ([]byte, error)

DecryptRC4SysKey decrypts system key using RC4

func DumpLSASecrets added in v0.0.51

func DumpLSASecrets(ctx context.Context, rpccon *msrrp.RPCCon, hKey []byte, modifyDacl bool) ([]*smbfern.LsaSecret, []string, error)

DumpLSASecrets performs LSA secrets dumping from registry

func DumpSAM added in v0.0.51

func DumpSAM(ctx context.Context, rpccon *msrrp.RPCCon, hKey []byte, modifyDacl bool) ([]*smbfern.SamSecret, []string, error)

DumpSAM performs SAM dumping from registry

func EncryptAES added in v0.0.51

func EncryptAES(key, plaintext, iv []byte) ([]byte, error)

EncryptAES encrypts data using AES with CBC mode

func EncryptDES added in v0.0.51

func EncryptDES(key, plaintext []byte) ([]byte, error)

EncryptDES encrypts data using DES

func EncryptRC4 added in v0.0.51

func EncryptRC4(key, plaintext []byte) ([]byte, error)

EncryptRC4 encrypts data using RC4

func ExtractStringFromRegistryData added in v0.0.51

func ExtractStringFromRegistryData(data []byte, dataType uint32) (string, error)

ExtractStringFromRegistryData extracts a string from registry data based on type

func ExtractUserRID added in v0.0.51

func ExtractUserRID(keyName string) (uint32, error)

ExtractUserRID extracts RID from registry key name

func GetBootKey added in v0.0.51

func GetBootKey(rpccon *msrrp.RPCCon, base []byte) ([]byte, error)

GetBootKey extracts the system boot key from registry

func GetCachedHashes added in v0.0.51

func GetCachedHashes(rpccon *msrrp.RPCCon, base []byte, modifyDacl bool) (result []string, err error)

func GetHostnameAndDomain added in v0.0.51

func GetHostnameAndDomain(rpccon *msrrp.RPCCon, base []byte) (hostname, domain string, err error)

func GetLSASecretKey added in v0.0.51

func GetLSASecretKey(rpccon *msrrp.RPCCon, base []byte, modifyDacl bool) (result []byte, err error)

func GetNetBIOSDomain added in v0.0.51

func GetNetBIOSDomain(rpccon *msrrp.RPCCon, base []byte) (string, error)

GetNetBIOSDomain retrieves the NetBIOS domain name from registry

func GetOSVersion added in v0.0.51

func GetOSVersion(currentBuild int, currentVersion float64, server bool) byte

GetOSVersion determines Windows OS version byte constant from build and version info

func GetOSVersionBuild added in v0.0.51

func GetOSVersionBuild(rpccon *msrrp.RPCCon, base []byte) (build int, version float64, server bool, err error)

GetOSVersionBuild determines Windows OS version and build

func GetRegistryHiveHandle added in v0.0.51

func GetRegistryHiveHandle(hive string) (interface{}, error)

GetRegistryHiveHandle gets a handle to a registry hive

func GetRegistryKeySecurityDescriptor added in v0.0.51

func GetRegistryKeySecurityDescriptor(rc *RegistryConnection, key *RegistryKey) ([]byte, error)

GetRegistryKeySecurityDescriptor retrieves security information for a registry key

func GetSysKey added in v0.0.51

func GetSysKey(rpccon *msrrp.RPCCon, base []byte, modifyDacl bool) ([]byte, error)

GetSysKey extracts the system key from SAM registry

func HexToBytes added in v0.0.51

func HexToBytes(hexStr string) ([]byte, error)

HexToBytes converts hex string to bytes

func IsPrintableString added in v0.0.51

func IsPrintableString(data []byte) bool

IsPrintableString checks if a byte array represents a printable string

func IsValidNTHash added in v0.0.51

func IsValidNTHash(hash string) bool

IsValidNTHash checks if a hash looks like a valid NT hash

func IsValidRegistryKeyName added in v0.0.51

func IsValidRegistryKeyName(name string) bool

IsValidRegistryKeyName checks if a string is a valid registry key name

func IsValidRegistryValueName added in v0.0.51

func IsValidRegistryValueName(name string) bool

IsValidRegistryValueName checks if a string is a valid registry value name

func IsWin10After1607 added in v0.0.51

func IsWin10After1607(build int, version float64) (bool, error)

IsWin10After1607 checks if Windows version is Windows 10 Anniversary Update or later

func MD5Hash added in v0.0.51

func MD5Hash(data []byte) []byte

MD5Hash calculates MD5 hash

func MapProtocolVersionToEnum added in v0.0.51

func MapProtocolVersionToEnum(version string) (commonprotocolfern.SmbVersion, bool)

MapProtocolVersionToEnum maps protocol version strings to Fern enum values This function is shared between enumerate and pentest modules

func NormalizeRegistryPath added in v0.0.51

func NormalizeRegistryPath(path string) string

NormalizeRegistryPath normalizes a registry key path

func PBKDF2Derive added in v0.0.51

func PBKDF2Derive(password, salt []byte, iterations, keyLength int, hashFunc func() hash.Hash) []byte

PBKDF2Derive derives a key using PBKDF2

func PadPKCS7 added in v0.0.51

func PadPKCS7(data []byte, blockSize int) []byte

PadPKCS7 adds PKCS#7 padding to data

func ParseRegistryValue added in v0.0.51

func ParseRegistryValue(data []byte) ([]byte, error)

ParseRegistryValue parses a registry value from raw bytes

func ROL added in v0.0.51

func ROL(value uint32, shift uint) uint32

ROL performs rotate left operation

func ROR added in v0.0.51

func ROR(value uint32, shift uint) uint32

ROR performs rotate right operation

func RestoreRegistryKey added in v0.0.51

func RestoreRegistryKey(rc *RegistryConnection, keyPath string, backupData []byte) error

RestoreRegistryKey restores a registry key from backup data

func SHA1Hash added in v0.0.51

func SHA1Hash(data []byte) []byte

SHA1Hash calculates SHA-1 hash

func SHA256 added in v0.0.51

func SHA256(key, value []byte, rounds int) []byte

SHA256 performs SHA-256 hash with multiple rounds

func SHA256Hash added in v0.0.51

func SHA256Hash(data []byte) []byte

SHA256Hash calculates SHA-256 hash

func SplitRegistryPath added in v0.0.51

func SplitRegistryPath(path string) (hive, key string)

SplitRegistryPath splits a registry path into hive and key components

func StringToUTF16LE added in v0.0.51

func StringToUTF16LE(s string) []byte

StringToUTF16LE converts string to UTF-16LE bytes

func StringToUTF16LEBytes added in v0.0.51

func StringToUTF16LEBytes(s string) []byte

StringToUTF16LEBytes converts string to UTF-16LE bytes

func UTF16LEBytesToString added in v0.0.51

func UTF16LEBytesToString(data []byte) (string, error)

UTF16LEBytesToString converts UTF-16LE bytes to string

func Uint32LEToBytes added in v0.0.51

func Uint32LEToBytes(value uint32) []byte

Uint32LEToBytes converts uint32 to little-endian bytes

func Uint64LEToBytes added in v0.0.51

func Uint64LEToBytes(value uint64) []byte

Uint64LEToBytes converts uint64 to little-endian bytes

func UnpadPKCS7 added in v0.0.51

func UnpadPKCS7(data []byte) ([]byte, error)

UnpadPKCS7 removes PKCS#7 padding from data

func XORBytes added in v0.0.51

func XORBytes(a, b []byte) []byte

XORBytes performs XOR operation on two byte slices

Types

type CachedCredential added in v0.0.51

type CachedCredential struct {
	Domain    string
	Username  string
	Hash      string
	LastLogin string
}

CachedCredential represents a cached domain credential (DCC2)

func GetCachedCredentials added in v0.0.51

func GetCachedCredentials(ctx context.Context, rpccon *msrrp.RPCCon, base []byte, modifyDacl bool) ([]CachedCredential, error)

GetCachedCredentials extracts cached domain credentials (DCC2) from the SECURITY\Cache registry

type CapturingNTLM added in v0.0.61

type CapturingNTLM struct {
	*spnego.NTLMInitiator
	LastChallenge     *ntlmssp.Challenge
	LastChallengeData []byte
}

CapturingNTLM wraps the built-in NTLM initiator and captures the server's challenge

func (*CapturingNTLM) InitSecContext added in v0.0.61

func (c *CapturingNTLM) InitSecContext(inputToken []byte) ([]byte, error)

type ChallengeOnlyNTLM added in v0.0.68

type ChallengeOnlyNTLM struct {
	*spnego.NTLMInitiator
	LastChallenge     *ntlmssp.Challenge
	LastChallengeData []byte
	// contains filtered or unexported fields
}

ChallengeOnlyNTLM only performs the challenge exchange and then stops

func (*ChallengeOnlyNTLM) InitSecContext added in v0.0.68

func (c *ChallengeOnlyNTLM) InitSecContext(inputToken []byte) ([]byte, error)

type Client

type Client struct {
	Host           string
	Port           int
	Username       string
	Password       string
	NTLMHash       string // NTLM hash for pass-the-hash authentication
	Domain         string
	UseAnonymous   bool
	UseNullSession bool
	ChallengeOnly  bool // If true, only get NTLM challenge and exit without authentication
	Timeout        time.Duration
	// contains filtered or unexported fields
}

Client represents a unified SMB client that provides base functionality for both enumeration and pentest operations

func NewClient

func NewClient(host string, port int) *Client

NewClient creates a new SMB client with the given configuration

func (*Client) Close

func (c *Client) Close() error

Close closes the SMB connection

func (*Client) Connect

func (c *Client) Connect() error

Connect establishes connection to SMB server and performs authentication

func (*Client) ConnectWithContext

func (c *Client) ConnectWithContext(ctx context.Context) error

ConnectWithContext establishes connection to SMB server and performs authentication with context

func (*Client) EnumerateShares

func (c *Client) EnumerateShares() ([]*commonprotocolfern.SmbShare, error)

EnumerateShares lists available shares using TreeConnect testing

func (*Client) EnumerateSharesWithContext

func (c *Client) EnumerateSharesWithContext(ctx context.Context) ([]*commonprotocolfern.SmbShare, error)

EnumerateSharesWithContext lists available shares using TreeConnect testing with context

func (*Client) ExtractServerInfoFromChallenge added in v0.0.51

func (c *Client) ExtractServerInfoFromChallenge(ctx context.Context) (*commonprotocolfern.SmbServerInfo, error)

ExtractServerInfoFromChallenge attempts to extract server information from NTLM challenge This works even when authentication fails, as the challenge contains server metadata

func (*Client) GetDomainFromServerInfo added in v0.0.51

func (c *Client) GetDomainFromServerInfo(ctx context.Context) string

GetDomainFromServerInfo extracts domain information from server info for authentication

func (*Client) GetSMBSession added in v0.0.51

func (c *Client) GetSMBSession() (*gosmb.Connection, error)

GetSMBSession returns the underlying go-smb connection for DCE/RPC operations

func (*Client) GetServerInfo

func (c *Client) GetServerInfo() *commonprotocolfern.SmbServerInfo

GetServerInfo returns extracted server information

func (*Client) IsAuthenticated

func (c *Client) IsAuthenticated() bool

IsAuthenticated returns true if client is authenticated to SMB server

func (*Client) IsConnected

func (c *Client) IsConnected() bool

IsConnected returns true if client is connected to SMB server

func (*Client) SetAnonymous

func (c *Client) SetAnonymous()

SetAnonymous configures client for anonymous authentication

func (*Client) SetChallengeOnly added in v0.0.68

func (c *Client) SetChallengeOnly()

SetChallengeOnly configures client to only retrieve NTLM challenge without authentication

func (*Client) SetCredentials

func (c *Client) SetCredentials(username, password, domain string)

SetCredentials sets username and password for authentication

func (*Client) SetCredentialsWithHash added in v0.0.61

func (c *Client) SetCredentialsWithHash(username, ntlmHash, domain string)

SetCredentialsWithHash sets username and NTLM hash for pass-the-hash authentication

func (*Client) SetNullSession

func (c *Client) SetNullSession()

SetNullSession configures client for null session authentication

func (*Client) SetServerInfo added in v0.0.61

func (c *Client) SetServerInfo(serverInfo *commonprotocolfern.SmbServerInfo)

SetServerInfo sets server info from external source (to avoid redundant extraction)

func (*Client) SkipServerInfoExtraction added in v0.0.61

func (c *Client) SkipServerInfoExtraction(skip bool)

SkipServerInfoExtraction configures whether to skip automatic server info extraction on connect

func (*Client) TestCredentials

func (c *Client) TestCredentials(username, password, domain string) (bool, string, error)

TestCredentials tests if the provided credentials are valid

type ConnectionResult added in v0.0.51

type ConnectionResult struct {
	Client     *Client
	ServerInfo *commonprotocolfern.SmbServerInfo
	Success    bool
	Error      error
}

ConnectionResult holds the result of a connection test

func TestConnectionMethod added in v0.0.51

func TestConnectionMethod(ctx context.Context, host string, port int, setupFunc func(*Client), methodName, target string) *ConnectionResult

TestConnectionMethod tests a specific SMB connection method and extracts server info This helper reduces duplication in connection testing patterns

type ContextKey added in v0.0.81

type ContextKey string

ContextKey represents context option keys for timeout handling

const (
	ContextOptionOutputTimeout      ContextKey = "output_timeout"
	ContextOptionOutputPollInterval ContextKey = "output_poll_interval"
)

type ExecutionIO added in v0.0.81

type ExecutionIO struct {
	Input  *ExecutionInput
	Output *ExecutionOutput
}

ExecutionIO handles command execution and output collection

func (*ExecutionIO) Clean added in v0.0.81

func (execIO *ExecutionIO) Clean(ctx context.Context) error

Clean cleans up the output provider

func (*ExecutionIO) CommandLine added in v0.0.81

func (execIO *ExecutionIO) CommandLine() []string

CommandLine generates the command line for execution

func (*ExecutionIO) GetOutput added in v0.0.81

func (execIO *ExecutionIO) GetOutput(ctx context.Context) error

GetOutput calls the output provider to collect output

func (*ExecutionIO) String added in v0.0.81

func (execIO *ExecutionIO) String() string

String returns the full command line as string

type ExecutionInput added in v0.0.81

type ExecutionInput struct {
	Executable     string
	ExecutablePath string
	Arguments      string
	Command        string
}

func (*ExecutionInput) CommandLine added in v0.0.81

func (i *ExecutionInput) CommandLine() []string

CommandLine returns command line array where cmd[0] is the executable and cmd[1] is the arguments

func (*ExecutionInput) String added in v0.0.81

func (i *ExecutionInput) String() string

String returns the input command as string

type ExecutionOutput added in v0.0.81

type ExecutionOutput struct {
	NoDelete   bool
	RemotePath string
	Timeout    time.Duration
	Provider   OutputProvider
	Writer     io.WriteCloser
}

type LSASecret added in v0.0.51

type LSASecret struct {
	Name        string
	Secret      string
	Description string
}

LSASecret represents an LSA secret extracted from the registry

func ExtractLSASecrets added in v0.0.51

func ExtractLSASecrets(session *gosmb.Connection) ([]LSASecret, error)

ExtractLSASecrets extracts LSA secrets from the SECURITY registry hive

type OutputFileFetcher added in v0.0.81

type OutputFileFetcher struct {
	// SMB Connection Configuration
	Host     string // SMB server hostname or IP address
	Username string // Username for authentication
	Password string // Password for authentication
	Domain   string // Domain for authentication (optional)

	// SMB Share Configuration
	Share     string // SMB share name (e.g., "ADMIN$", "C$")
	SharePath string // Base path within the share (e.g., `C:\Windows`)
	File      string // Full path to the output file to retrieve

	// Behavior Configuration
	DeleteOutputFile bool // Whether to delete the output file after retrieval
	ForceReconnect   bool // Whether to force reconnection for each operation
	// contains filtered or unexported fields
}

OutputFileFetcher handles retrieval of command output via SMB file access

func (*OutputFileFetcher) Clean added in v0.0.81

func (o *OutputFileFetcher) Clean(ctx context.Context) error

Clean implements OutputProvider interface

func (*OutputFileFetcher) GetOutput added in v0.0.81

func (o *OutputFileFetcher) GetOutput(ctx context.Context, writer io.Writer) error

GetOutput implements OutputProvider interface

type OutputProvider added in v0.0.81

type OutputProvider interface {
	GetOutput(ctx context.Context, writer io.Writer) error
	Clean(ctx context.Context) error
}

OutputProvider interface for command output retrieval

type PrintableLSASecret added in v0.0.51

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

func GetLSASecrets added in v0.0.51

func GetLSASecrets(rpccon *msrrp.RPCCon, base []byte, history, modifyDacl bool) (secrets []PrintableLSASecret, err error)

GetLSASecrets extracts LSA secrets from the Windows registry. Code inspired/partially stolen from Impacket's Secretsdump

type RegistryConnection added in v0.0.51

type RegistryConnection struct {
	Session *gosmb.Connection
	Handle  interface{} // DCE/RPC handle for registry operations
}

RegistryConnection represents a connection to remote registry service

func ConnectToRegistry added in v0.0.51

func ConnectToRegistry(session *gosmb.Connection) (*RegistryConnection, error)

ConnectToRegistry establishes a connection to the remote registry service

func (*RegistryConnection) CloseRegistryKey added in v0.0.51

func (rc *RegistryConnection) CloseRegistryKey(key *RegistryKey) error

CloseRegistryKey closes an open registry key

func (*RegistryConnection) Disconnect added in v0.0.51

func (rc *RegistryConnection) Disconnect() error

Disconnect closes the registry connection

func (*RegistryConnection) EnumerateSubKeys added in v0.0.51

func (rc *RegistryConnection) EnumerateSubKeys(key *RegistryKey) ([]string, error)

EnumerateSubKeys lists all subkeys under the given registry key

func (*RegistryConnection) EnumerateValues added in v0.0.51

func (rc *RegistryConnection) EnumerateValues(key *RegistryKey) ([]RegistryValue, error)

EnumerateValues lists all values under the given registry key

func (*RegistryConnection) OpenRegistryKey added in v0.0.51

func (rc *RegistryConnection) OpenRegistryKey(keyPath string) (*RegistryKey, error)

OpenRegistryKey opens a registry key for reading

func (*RegistryConnection) ReadRegistryValue added in v0.0.51

func (rc *RegistryConnection) ReadRegistryValue(key *RegistryKey, valueName string) (*RegistryValue, error)

ReadRegistryValue reads a value from an open registry key

type RegistryKey added in v0.0.51

type RegistryKey struct {
	Name     string
	SubKeys  []string
	Values   []RegistryValue
	Class    string
	Modified int64
}

RegistryKey represents a registry key with subkeys and values

type RegistryValue added in v0.0.51

type RegistryValue struct {
	Name string
	Type uint32
	Data []byte
}

RegistryValue represents a registry value with type and data

type SAMAccount added in v0.0.51

type SAMAccount struct {
	Username string
	RID      uint32
	NTHash   string
	LMHash   string
}

SAMAccount represents a local user account extracted from SAM

type UserCreds added in v0.0.51

type UserCreds struct {
	Username string
	RID      uint32
	Data     []byte
	IV       []byte
	AES      bool
}

UserCreds represents user credential data from SAM

func GetNTHash added in v0.0.51

func GetNTHash(rpccon *msrrp.RPCCon, base []byte, rids []string, modifyDacl bool) ([]UserCreds, error)

GetNTHash extracts NT hashes from SAM registry

type WindowsOSInfo added in v0.0.51

type WindowsOSInfo struct {
	MajorVersion uint32
	MinorVersion uint32
	BuildNumber  uint32
	ProductName  string
}

WindowsOSInfo represents Windows OS version information

type WriteCloserWrapper added in v0.0.81

type WriteCloserWrapper struct {
	io.Writer
}

WriteCloserWrapper wraps an io.Writer to implement io.WriteCloser

func (*WriteCloserWrapper) Close added in v0.0.81

func (w *WriteCloserWrapper) Close() error

Jump to

Keyboard shortcuts

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