msproto
import "github.com/TheManticoreProject/Manticore/network/dcerpc/ms-protocols/msproto"
Package msproto holds the shared contracts and transport-binding helpers common to every high-level MS-protocol client (ms-srvs, ms-rrp, ms-drsr, …).
An MS-protocol client is the workflow layer above a single DCE/RPC interface: it binds that interface’s abstract syntax over some transport and exposes friendly methods. The clients differ on two orthogonal axes — where the transport comes from (a borrowed SMB named pipe vs. an owned ncacn_ip_tcp connection) and how long a bound association lives (a persistent bind reused across calls vs. a fresh bind per call). This package captures only what is genuinely common across those axes:
- Protocol: every client reports the abstract syntax it speaks and can be Closed.
- Session: the subset of clients that hold a persistent bound association also expose Connect/IsConnected.
- Binder: the “open a transport and bind a syntax” step, with one implementation per transport provenance (PipeBinder over SMB, TCPBinder over ncacn_ip_tcp).
It deliberately does NOT unify context-handle types (those are interface-specific) nor the bind-per-call vs. persistent-bind policy (that stays each client’s choice).
This package depends only on the DCE/RPC transport, client, syntax, and credentials layers; the MS-protocol packages depend on it, never the reverse.
Index
Constants
DefaultTCPTimeout bounds the endpoint-mapper and target TCP dials and reads when a TCPBinder is built without an explicit timeout.
const DefaultTCPTimeout = 10 * time.Second
type Binder
Binder opens a transport and binds an abstract syntax over it, returning a ready DCE/RPC client plus a close function that tears that transport down. It abstracts the one step every MS-protocol shares (transport acquisition + bind) over the differing transport provenances, so a protocol client can issue calls without embedding any dial/bind plumbing of its own.
A stateless client calls Bind once per workflow and invokes the returned closer immediately; a session client calls Bind once in Connect and holds the result.
type Binder interface {
// Bind opens a transport, performs any transport-level authentication the provenance
// requires, binds the given abstract syntax, and returns the bound client and its
// closer. The caller owns the close function and must call it to release the transport.
Bind(s syntax.SyntaxID) (*dcerpcclient.Client, func() error, error)
}
type PipeBinder
PipeBinder binds an interface over a DCE/RPC named pipe borrowed from an established SMB session. It performs no DCE/RPC-layer authentication: a named pipe inherits the security context of the SMB session it rides on.
type PipeBinder struct {
// contains filtered or unexported fields
}
func NewPipeBinder
func NewPipeBinder(dialer PipeDialer, pipe string) *PipeBinder
NewPipeBinder returns a Binder that opens the given named pipe over dialer for every Bind call. pipe is the IPC$-relative pipe name (e.g. `\srvsvc`, `\winreg`).
func (*PipeBinder) Bind
func (b *PipeBinder) Bind(s syntax.SyntaxID) (*dcerpcclient.Client, func() error, error)
Bind opens a fresh named-pipe transport and binds s over it.
type PipeDialer
PipeDialer opens a fresh DCE/RPC named-pipe transport for the given pipe over an established, IPC$-tree-connected SMB session. It is the only capability the named-pipe MS-protocols (ms-srvs, ms-rrp) need from the SMB layer, so depending on this interface rather than a concrete SMB client keeps them independent of the SMB dialect: network/smb/client.Client satisfies it (via its RPCTransport method) and routes to an SMB1 or SMB2 named-pipe transport according to what was negotiated.
type PipeDialer interface {
RPCTransport(pipeName string) (dcerpctransport.Transport, error)
}
type Protocol
Protocol is the contract every MS-protocol client satisfies, regardless of transport provenance or session model.
type Protocol interface {
// Interface reports the DCE/RPC abstract syntax (UUID + version) this protocol speaks.
Interface() syntax.SyntaxID
// Close releases everything the client holds — server-side context handles and any
// owned transport. It follows io.Closer semantics: it is safe to call when nothing is
// held (e.g. a stateless client, or one that never connected) and returns nil then.
Close() error
}
type Session
Session is implemented by the MS-protocol clients that hold a persistent bound association for the lifetime of the client (their context handles chain across calls and are scoped to that one association). Stateless clients that bind a fresh transport per call satisfy Protocol but not Session.
type Session interface {
Protocol
// Connect establishes the persistent association (resolving endpoints and binding the
// abstract syntax as the protocol requires). It is idempotent: calling it on an
// already-connected client is a no-op that returns nil.
Connect() error
// IsConnected reports whether Connect has succeeded and Close has not yet run.
IsConnected() bool
}
type TCPBinder
TCPBinder binds an interface over an owned ncacn_ip_tcp connection. Unlike a borrowed pipe, this transport carries no ambient security context, so TCPBinder authenticates at the DCE/RPC layer with NTLM at the configured level (packet privacy by default, which the secret-bearing interfaces such as drsuapi require). When Port is zero the target port is resolved through the endpoint mapper on TCP/135 for the syntax being bound.
type TCPBinder struct {
Host string
Port int // 0 resolves via the endpoint mapper
Creds *credentials.Credentials
Timeout time.Duration
AuthType uint8 // DCE/RPC auth type; defaults to NTLMSSP
AuthLevel uint8 // DCE/RPC auth level; defaults to packet privacy (sign + seal)
}
func NewTCPBinder
func NewTCPBinder(host string, port int, creds *credentials.Credentials, timeout time.Duration) *TCPBinder
NewTCPBinder returns a Binder over ncacn_ip_tcp to host authenticating with creds at NTLM packet-privacy level. port may be 0 to resolve the target via the endpoint mapper; a zero timeout falls back to DefaultTCPTimeout.
func (*TCPBinder) Bind
func (b *TCPBinder) Bind(s syntax.SyntaxID) (*dcerpcclient.Client, func() error, error)
Bind resolves the endpoint (unless Port is set), dials it over ncacn_ip_tcp, authenticates with NTLM at the configured level, and binds s.