Documentation
¶
Overview ¶
Package nspi implements MS-NSPI (Name Service Provider Interface) protocol for querying Exchange address books via RPC over HTTP v2. This is a modular library that can be used by multiple tools.
Index ¶
- Constants
- Variables
- func FormatFileTime(ft uint64) string
- func FormatGUID(data []byte) string
- func FormatSID(data []byte) string
- func GetDNFromGUID(guidStr string) string
- func GetGUIDFromDN(entryID []byte) []byte
- func SimplifyPropertyRow(row *PropertyRow) map[PropertyTag]interface{}
- func UUIDToMSRPC(u uuid.UUID) [16]byte
- type AddressBookEntry
- type BinaryObject
- type Client
- func (c *Client) Connect() error
- func (c *Client) Disconnect() error
- func (c *Client) GetSpecialTable() error
- func (c *Client) LoadHTableContainerID() error
- func (c *Client) QueryColumns() ([]PropertyTag, error)
- func (c *Client) QueryRows(containerID int32, count uint32, propTags []PropertyTag) (*PropertyRowSet, error)
- func (c *Client) QueryRowsExplicit(containerID int32, count uint32, propTags []PropertyTag, eTable []uint32) (*PropertyRowSet, error)
- func (c *Client) QueryRowsWithCallback(containerID int32, count uint32, propTags []PropertyTag, ...) error
- func (c *Client) ResolveNamesW(names []string, propTags []PropertyTag) (*PropertyRowSet, error)
- func (c *Client) SetCredentials(username, password, domain string, hashes string)
- func (c *Client) SetKerberosConfig(useKerberos bool, creds *session.Credentials)
- func (c *Client) Unbind() error
- func (c *Client) UpdateStat(containerID int32) error
- type ContextHandle
- type PropertyRow
- type PropertyRowSet
- type PropertyTag
- type PropertyTagArray
- type PropertyValue
- type STAT
Constants ¶
const ( NSPI_VERSION_MAJOR = 56 NSPI_VERSION_MINOR = 0 )
Interface version
const ( PtypEmbeddedTable = 0x0000000D PtypNull = 0x00000001 PtypUnspecified = 0x00000000 PtypInteger16 = 0x00000002 PtypInteger32 = 0x00000003 PtypFloating32 = 0x00000004 PtypFloating64 = 0x00000005 PtypCurrency = 0x00000006 PtypFloatingTime = 0x00000007 PtypErrorCode = 0x0000000A PtypBoolean = 0x0000000B PtypInteger64 = 0x00000014 PtypString8 = 0x0000001E PtypString = 0x0000001F PtypTime = 0x00000040 PtypGuid = 0x00000048 PtypBinary = 0x00000102 PtypMultipleInt16 = 0x00001002 PtypMultipleInt32 = 0x00001003 PtypMultipleStr8 = 0x0000101E PtypMultipleStr = 0x0000101F PtypMultipleTime = 0x00001040 PtypMultipleGuid = 0x00001048 PtypMultipleBin = 0x00001102 )
Property type values (2.2.1)
const ( DT_MAILUSER = 0x00000000 DT_DISTLIST = 0x00000001 DT_FORUM = 0x00000002 DT_AGENT = 0x00000003 DT_ORGANIZATION = 0x00000004 DT_PRIVATE_DISTLIST = 0x00000005 DT_REMOTE_MAILUSER = 0x00000006 DT_CONTAINER = 0x00000100 DT_TEMPLATE = 0x00000101 DT_ADDRESS_TEMPLATE = 0x00000102 DT_SEARCH = 0x00000200 )
Display Type Values (2.2.3)
const ( CP_TELETEX = 0x00004F25 CP_WINUNICODE = 0x000004B0 )
Required Codepages (2.2.5)
const ( NORM_IGNORECASE = 1 << 0 NORM_IGNORENONSPACE = 1 << 1 NORM_IGNORESYMBOLS = 1 << 2 SORT_STRINGSORT = 1 << 12 NORM_IGNOREKANATYPE = 1 << 16 NORM_IGNOREWIDTH = 1 << 17 )
Comparison Flags (2.2.6.1)
const ( MID_BEGINNING_OF_TABLE = 0x00000000 MID_END_OF_TABLE = 0x00000002 MID_CURRENT = 0x00000001 )
Positioning Minimal Entry IDs (2.2.8)
const ( MID_UNRESOLVED = 0x00000000 MID_AMBIGUOUS = 0x00000001 MID_RESOLVED = 0x00000002 )
Ambiguous Name Resolution Minimal Entry IDs (2.2.9)
const ( SortTypeDisplayName = 0 SortTypePhoneticDisplayName = 0x00000003 SortTypeDisplayName_RO = 0x000003E8 SortTypeDisplayName_W = 0x000003E9 )
Table Sort Orders (2.2.10)
const ( FSkipObjects = 0x00000001 FEphID = 0x00000002 )
Retrieve Property Flags (2.2.12)
const ( NspiAddressCreationTemplates = 0x00000002 NspiUnicodeStrings = 0x00000004 )
NspiGetSpecialTable Flags (2.2.13)
const ( TI_TEMPLATE = 0x00000001 TI_SCRIPT = 0x00000004 TI_EMT = 0x00000010 TI_HELPFILE_NAME = 0x00000020 TI_HELPFILE_CONTENTS = 0x00000040 )
NspiGetTemplateInfo Flags (2.2.16)
const ( OP_NspiBind = 0 OP_NspiUnbind = 1 OP_NspiUpdateStat = 2 OP_NspiQueryRows = 3 OP_NspiSeekEntries = 4 OP_NspiGetMatches = 5 OP_NspiResortRestrict = 6 OP_NspiDNToMId = 7 OP_NspiGetPropList = 8 OP_NspiGetProps = 9 OP_NspiCompareMIds = 10 OP_NspiModProps = 11 OP_NspiGetSpecialTable = 12 OP_NspiGetTemplateInfo = 13 OP_NspiModLinkAtt = 14 OP_NspiQueryColumns = 16 OP_NspiResolveNames = 19 OP_NspiResolveNamesW = 20 )
NSPI Operation Numbers
const (
FAnonymousLogin = 0x00000020
)
NspiBind Flags (2.2.11)
const (
FDelete = 0x00000001
)
NspiModLinkAtt Flags (2.2.17)
const NSPI_DEFAULT_LOCALE = 0x00000409
Default Language Code Identifier (2.2.4)
const (
NspiUnicodeProptypes = 0x80000000
)
NspiQueryColumns Flags (2.2.14)
const (
NspiVerifyNames = 0x00000002
)
NspiGetIDsFromNames Flags (2.2.15)
Variables ¶
var GUID_NSPI = uuid.MustParse("C840A7DC-42C0-1A10-B4B9-08002B2FE182")
Permanent Entry ID GUID (2.2.7)
var MSRPC_UUID_NSPI = uuid.MustParse("F5CC5A18-4264-101A-8C59-08002B2F8426")
NSPI interface UUID
Functions ¶
func FormatFileTime ¶
FormatFileTime converts a Windows FILETIME (100-nanosecond intervals since January 1, 1601) to a human-readable string in local time (matching Impacket)
func FormatGUID ¶
FormatGUID formats 16 bytes as a GUID string (little-endian fields)
func GetDNFromGUID ¶
GetDNFromGUID creates a minimal DN from a GUID for ResolveNames lookup
func GetGUIDFromDN ¶
GetGUIDFromDN extracts GUID from an NSPI PermanentEntryID
func SimplifyPropertyRow ¶
func SimplifyPropertyRow(row *PropertyRow) map[PropertyTag]interface{}
SimplifyPropertyRow converts a PropertyRow to a map for easier access
Types ¶
type AddressBookEntry ¶
type AddressBookEntry struct {
MId int32
Name string
GUID []byte
Flags uint32
Depth uint32
IsMaster bool
ParentGUID []byte
Count uint32
StartMId uint32
Printed bool
Properties map[PropertyTag]interface{}
}
AddressBookEntry represents a parsed address book entry
type BinaryObject ¶
type BinaryObject []byte
BinaryObject wraps binary data for proper display
func (BinaryObject) String ¶
func (b BinaryObject) String() string
String returns hex representation
type Client ¶
type Client struct {
Transport *rpch.AuthTransport
Handler ContextHandle
Stat *STAT
CallID uint32
// Address book hierarchy (map for lookup, slice for insertion order)
HTable map[int32]*AddressBookEntry
HTableOrder []int32
// Cached properties list
Properties []PropertyTag
// Any existing container ID for queries
AnyExistingContainerID int32
// contains filtered or unexported fields
}
Client is an NSPI protocol client
func (*Client) GetSpecialTable ¶
GetSpecialTable performs NspiGetSpecialTable operation to get address book hierarchy
func (*Client) LoadHTableContainerID ¶
LoadHTableContainerID finds an existing container ID for queries
func (*Client) QueryColumns ¶
func (c *Client) QueryColumns() ([]PropertyTag, error)
QueryColumns performs NspiQueryColumns operation to get available properties
func (*Client) QueryRows ¶
func (c *Client) QueryRows(containerID int32, count uint32, propTags []PropertyTag) (*PropertyRowSet, error)
QueryRows performs NspiQueryRows with pagination until MID_END_OF_TABLE
func (*Client) QueryRowsExplicit ¶
func (c *Client) QueryRowsExplicit(containerID int32, count uint32, propTags []PropertyTag, eTable []uint32) (*PropertyRowSet, error)
QueryRowsExplicit performs NspiQueryRows with an explicit table (lpETable)
func (*Client) QueryRowsWithCallback ¶
func (c *Client) QueryRowsWithCallback(containerID int32, count uint32, propTags []PropertyTag, callback func(*PropertyRowSet) error) error
QueryRowsWithCallback performs paginated QueryRows and calls the callback for each batch. This is used for two-phase queries where we first get MIds then fetch full properties.
func (*Client) ResolveNamesW ¶
func (c *Client) ResolveNamesW(names []string, propTags []PropertyTag) (*PropertyRowSet, error)
ResolveNamesW performs NspiResolveNamesW operation for GUID lookups
func (*Client) SetCredentials ¶
SetCredentials sets authentication credentials
func (*Client) SetKerberosConfig ¶
func (c *Client) SetKerberosConfig(useKerberos bool, creds *session.Credentials)
SetKerberosConfig enables Kerberos authentication for this client
func (*Client) UpdateStat ¶
UpdateStat performs NspiUpdateStat operation
type ContextHandle ¶
ContextHandle represents an NSPI context handle
func (*ContextHandle) IsNull ¶
func (h *ContextHandle) IsNull() bool
IsNull checks if the context handle is null
func (*ContextHandle) Marshal ¶
func (h *ContextHandle) Marshal() []byte
Marshal serializes the context handle
func (*ContextHandle) Unmarshal ¶
func (h *ContextHandle) Unmarshal(data []byte) error
Unmarshal deserializes the context handle
type PropertyRow ¶
type PropertyRow struct {
Reserved uint32
Values []PropertyValue
}
PropertyRow represents a row of property values
type PropertyRowSet ¶
type PropertyRowSet struct {
Rows []PropertyRow
}
PropertyRowSet represents a set of property rows
func ParsePropertyRowSet ¶
func ParsePropertyRowSet(data []byte, propTags []PropertyTag) (*PropertyRowSet, error)
ParsePropertyRowSet parses a PropertyRowSet_r from NDR response data. The NDR format is:
- Pointer referent for ppRows (4 bytes)
- cRows (4 bytes)
- Conformant array max count (4 bytes)
- For each row: Reserved(4), cValues(4), lpProps pointer ref(4)
- Deferred: for each row's lpProps: conformant array of PropertyValue_r
- Each PropertyValue_r: ulPropTag(4), dwAlignPad(4), union value (8 bytes)
- Further deferred data for strings, binary, etc.
type PropertyTag ¶
type PropertyTag uint32
PropertyTag represents a MAPI property tag
func (PropertyTag) Type ¶
func (p PropertyTag) Type() uint16
Type returns the property type (lower 16 bits)
type PropertyTagArray ¶
type PropertyTagArray struct {
Values []PropertyTag
}
PropertyTagArray represents an array of property tags
func (*PropertyTagArray) Marshal ¶
func (a *PropertyTagArray) Marshal() []byte
Marshal serializes the property tag array
func (*PropertyTagArray) MarshalNDR ¶
func (a *PropertyTagArray) MarshalNDR() []byte
MarshalNDR serializes the property tag array in NDR format. The IDL defines: [size_is(cValues+1)] DWORD aulPropTag[] This is a conformant-varying array. Wire format:
MaxCount(4) = cValues+1, cValues(4), Offset(4) = 0, ActualCount(4) = cValues, elements
type PropertyValue ¶
type PropertyValue struct {
Tag PropertyTag
Value interface{} // Can be int16, int32, int64, string, []byte, etc.
}
PropertyValue represents a MAPI property value