Documentation
¶
Overview ¶
Package mssql provides SQL Server connection and data collection functionality.
Package mssql provides SQL Server connection and data collection functionality.
Package mssql - Custom NTLM authentication provider with EPA channel binding support. This bridges the go-mssqldb integratedauth interface with our custom ntlmAuth implementation that supports MsvAvChannelBindings and MsvAvTargetName AV_PAIRs.
go-mssqldb's built-in NTLM implementation (integratedauth/ntlm) does NOT include EPA channel binding tokens, causing authentication failures when SQL Server has Extended Protection set to "Required". This provider solves that by injecting the correct CBT (computed from the TLS server certificate) into the NTLM Type3 message.
Package mssql - EPA test orchestrator. Performs raw TDS+TLS+NTLM login attempts with controllable Channel Binding and Service Binding AV_PAIRs to determine EPA enforcement level. This matches the approach used in the Python reference implementation (MssqlExtended.py / MssqlInformer.py).
Package mssql - Custom Kerberos authentication provider for go-mssqldb.
go-mssqldb's built-in krb5 provider (integratedauth/krb5) uses gokrb5's spnego.SPNEGOClient.InitSecContext() which hardcodes ContextFlagInteg and ContextFlagConf in the AP-REQ authenticator checksum. This can cause SQL Server to reject the token with "untrusted domain" errors when the connection is TLS-encrypted or EPA is enabled.
This provider builds the SPNEGO token manually (same approach as the LDAP GSSAPI bind fix in gssapi_krb5.go) with empty GSS flags, giving us full control over the token generation.
Package mssql - Kerberos configuration helpers. Auto-generates a minimal krb5.conf when --domain and --dc are provided but no explicit krb5.conf path is given. This avoids requiring users to manually create /etc/krb5.conf on systems where it doesn't exist.
Package mssql - NTLMv2 authentication with controllable AV_PAIRs for EPA testing. Implements NTLM Type1/Type2/Type3 message generation with the ability to add, remove, or modify MsvAvChannelBindings and MsvAvTargetName AV_PAIRs.
Package mssql - TDS transport layer for raw EPA testing. Implements TDS packet framing and TLS-over-TDS handshake adapter.
Index ¶
- func AVPairName(id uint16) string
- func GenerateKrb5Config(domain, kdcAddress string) (string, error)
- func IsAuthError(err error) bool
- func IsEPAPrereqError(err error) bool
- func TestConnection(serverInstance, userID, password string, timeout time.Duration) error
- type Client
- func (c *Client) CheckPort(ctx context.Context) error
- func (c *Client) Close() error
- func (c *Client) CollectServerInfo(ctx context.Context) (*types.ServerInfo, error)
- func (c *Client) Connect(ctx context.Context) error
- func (c *Client) DB() *sql.DB
- func (c *Client) DBW() *DBWrapper
- func (c *Client) SetCollectFromLinkedServers(collect bool)
- func (c *Client) SetDNSResolver(resolver string)
- func (c *Client) SetDebug(debug bool)
- func (c *Client) SetDomain(domain string)
- func (c *Client) SetEPAResult(result *EPATestResult)
- func (c *Client) SetKerberosConfig(configFile, ccacheFile, keytabFile, realm string)
- func (c *Client) SetLDAPCredentials(ldapUser, ldapPassword string)
- func (c *Client) SetLogger(l *slog.Logger)
- func (c *Client) SetNTHash(hash []byte)
- func (c *Client) SetProxyDialer(d interface{ ... })
- func (c *Client) SetVerbose(verbose bool)
- func (c *Client) TestEPA(ctx context.Context) (*EPATestResult, error)
- type DBWrapper
- func (w *DBWrapper) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
- func (w *DBWrapper) QueryContext(ctx context.Context, query string, args ...interface{}) (Rows, error)
- func (w *DBWrapper) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner
- type EPAPrereqError
- type EPATestConfig
- type EPATestMode
- type EPATestResult
- type QueryResult
- type RowScanner
- type Rows
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AVPairName ¶
AVPairName returns a human-readable name for an AV_PAIR ID.
func GenerateKrb5Config ¶
generateKrb5Config creates a minimal krb5.conf in a temp file and returns its path. The caller is responsible for cleaning up the file (e.g. via os.Remove or defer).
func IsAuthError ¶
IsAuthError checks if the error is an authentication failure that would count toward AD account lockout, as opposed to transport/TLS errors that do not.
func IsEPAPrereqError ¶
IsEPAPrereqError checks if an error is an EPA prerequisite failure.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client handles SQL Server connections and data collection
func (*Client) CheckPort ¶
CheckPort performs a quick TCP connectivity check against the SQL Server port. Call this before EPA testing or authentication to skip unreachable servers fast.
func (*Client) CollectServerInfo ¶
CollectServerInfo gathers all information about the SQL Server
func (*Client) SetCollectFromLinkedServers ¶
func (*Client) SetDNSResolver ¶
SetDNSResolver sets the DNS resolver IP (e.g. domain controller) for hostname lookups.
func (*Client) SetDomain ¶
SetDomain sets the domain for NTLM authentication (needed for EPA testing)
func (*Client) SetEPAResult ¶
func (c *Client) SetEPAResult(result *EPATestResult)
SetEPAResult stores a pre-computed EPA test result on the client. When set, collectEncryptionSettings will use this instead of running EPA tests.
func (*Client) SetKerberosConfig ¶
SetKerberosConfig sets Kerberos authentication parameters.
func (*Client) SetLDAPCredentials ¶
SetLDAPCredentials sets the LDAP credentials used for EPA testing. The ldapUser can be in DOMAIN\user or user@domain format.
func (*Client) SetNTHash ¶
SetNTHash sets a pre-computed NT hash (16 bytes) for pass-the-hash authentication. When set, NTLM auth will use this hash instead of deriving one from the password.
func (*Client) SetProxyDialer ¶
func (c *Client) SetProxyDialer(d interface { DialContext(ctx context.Context, network, address string) (net.Conn, error) })
SetProxyDialer sets a SOCKS5 proxy dialer for all network operations.
func (*Client) SetVerbose ¶
SetVerbose enables or disables verbose logging
func (*Client) TestEPA ¶
func (c *Client) TestEPA(ctx context.Context) (*EPATestResult, error)
TestEPA performs Extended Protection for Authentication testing using raw TDS+TLS+NTLM connections with controllable Channel Binding and Service Binding. This matches the approach used in the Python reference implementation (MssqlExtended.py / MssqlInformer.py).
Two-path EPA detection flow (per MS-TDS spec):
Path 1 - TDS 7.x normal (most servers): PRELOGIN(cleartext) -> TLS-over-TDS handshake -> LOGIN7 with NTLM Type1 -> server returns NTLM Type2 challenge (contains encryption flag) Path 2 - TDS 8.0 strict (ForceStrictEncryption=1): Direct TLS handshake -> PRELOGIN(inside TLS) -> LOGIN7 with NTLM Type1 -> server returns NTLM Type2 challenge Tried only when Path 1 PRELOGIN fails (strict servers reject cleartext PRELOGIN).
EPA determination logic (for encrypted connections):
- Normal login (unmodified NTLM) succeeds -> baseline established
- BogusCBT login (garbage channel binding token) fails with "untrusted domain" -> server is checking channel bindings, proceed to step 3 BogusCBT succeeds -> EPA is Off (server ignores channel bindings)
- MissingCBT login (no channel binding token at all): Fails with "untrusted domain" -> EPA = Required Succeeds -> EPA = Allowed (accepts but doesn't require CBT)
For unencrypted connections (ENCRYPT_OFF): service binding is tested instead.
type DBWrapper ¶
type DBWrapper struct {
// contains filtered or unexported fields
}
DBWrapper provides a small interface around database/sql query methods.
func NewDBWrapper ¶
NewDBWrapper creates a new database wrapper.
func (*DBWrapper) ExecContext ¶
func (w *DBWrapper) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
ExecContext executes a query without returning rows.
func (*DBWrapper) QueryContext ¶
func (w *DBWrapper) QueryContext(ctx context.Context, query string, args ...interface{}) (Rows, error)
QueryContext executes a query and returns rows.
func (*DBWrapper) QueryRowContext ¶
func (w *DBWrapper) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner
QueryRowContext executes a query and returns a single row.
type EPAPrereqError ¶
type EPAPrereqError struct {
Err error
}
EPAPrereqError indicates that the EPA prerequisite check failed. When this error is returned, no further EPA tests or MSSQL authentication attempts should be made (to match the Python mssql.py flow and avoid account lockout with invalid credentials).
func (*EPAPrereqError) Error ¶
func (e *EPAPrereqError) Error() string
func (*EPAPrereqError) Unwrap ¶
func (e *EPAPrereqError) Unwrap() error
type EPATestConfig ¶
type EPATestConfig struct {
Hostname string
Port int
InstanceName string
Domain string
Username string
Password string
NTHash []byte // Pre-computed NT hash for pass-the-hash (16 bytes)
TestMode EPATestMode
Logger *slog.Logger
Verbose bool
Debug bool
DisableMIC bool // Diagnostic: omit MsvAvFlags and MIC from Type3
UseRawTargetInfo bool // Diagnostic: use server's raw target info (no EPA mods, no MIC)
UseClientTimestamp bool // Diagnostic: use time.Now() FILETIME instead of server's MsvAvTimestamp
DNSResolver string // DNS resolver IP (e.g. domain controller)
ProxyDialer interface {
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
}
EPATestConfig holds configuration for a single EPA test connection.
type EPATestMode ¶
type EPATestMode int
EPATestMode controls what AV_PAIRs are included/excluded in the NTLM Type3 message.
const ( // EPATestNormal includes correct CBT and service binding EPATestNormal EPATestMode = iota // EPATestBogusCBT includes incorrect CBT hash EPATestBogusCBT // EPATestMissingCBT excludes MsvAvChannelBindings AV_PAIR entirely EPATestMissingCBT // EPATestBogusService includes incorrect service name ("cifs") EPATestBogusService // EPATestMissingService excludes MsvAvTargetName and strips target service EPATestMissingService )
type EPATestResult ¶
type EPATestResult struct {
UnmodifiedSuccess bool
NoSBSuccess bool
NoCBTSuccess bool
ForceEncryption bool
StrictEncryption bool
EncryptionFlag byte
EPAStatus string
}
EPATestResult holds the results of EPA connection testing
type QueryResult ¶
type QueryResult map[string]interface{}
QueryResult represents a row of query results.
type RowScanner ¶
type RowScanner interface {
Scan(dest ...interface{}) error
}
RowScanner provides a unified interface for scanning rows.