Documentation ¶
Overview ¶
Package oracle provides the zgrab2 scanner module for Oracle's TNS protocol. Default Port: 1521 (TCP)
The scan does the first part of a TNS handshake, prior to the point where any actual authentication is required; the happy case goes 1. client-to-server: Connect(--client-version, --min-server-version, --connect-descriptor) 2. server-to-client: Resend 3. client-to-server: Connect(exact same data) 4. server-to-client: Accept(server_version) 5. client-to-server: Data: Native Service Negotiation 6. server-to-client: Data: Native Service Negotiation(component release versions)
The default scan uses a generic connect descriptor with no explicit connect data / service name, so it relies on the server to choose the destination.
Sending an intentionally invalid --connect-descriptor can force a Refuse response, which should include a version number.
The output includes the server's protocol version and any component release versions that are returned.
Index ¶
- Constants
- Variables
- func RegisterModule()
- type ConnectFlags
- type Connection
- type DataFlags
- type Descriptor
- type DescriptorEntry
- type Flags
- type HandshakeLog
- type Module
- type NSNOptions
- type NSNService
- type NSNServiceType
- type NSNValue
- func NSNValueBytes(bytes []byte) *NSNValue
- func NSNValueStatus(val uint16) *NSNValue
- func NSNValueString(val string) *NSNValue
- func NSNValueUB1(val uint8) *NSNValue
- func NSNValueUB2(val uint16) *NSNValue
- func NSNValueVersion(v string) *NSNValue
- func ReadNSNValue(reader io.Reader, ret *NSNValue) (*NSNValue, error)
- type NSNValueType
- type NTProtocolCharacteristics
- type PacketType
- type RefuseReason
- type ReleaseVersion
- type ScanResults
- type Scanner
- func (scanner *Scanner) GetName() string
- func (scanner *Scanner) GetTrigger() string
- func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error
- func (scanner *Scanner) InitPerSender(senderID int) error
- func (scanner *Scanner) Protocol() string
- func (scanner *Scanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error)
- type ServiceOptions
- type TNSAccept
- type TNSConnect
- type TNSData
- type TNSDataNSN
- type TNSDriver
- type TNSFlags
- type TNSHeader
- type TNSMode
- type TNSPacket
- type TNSPacketBody
- type TNSRedirect
- type TNSRefuse
- type TNSResend
Constants ¶
const ( // PacketTypeConnect identifies a Connect packet (first packet sent by the // client, containing the connect descriptor). PacketTypeConnect PacketType = 1 // PacketTypeAccept identifies an Accept packet (the server's response to // a Connect packet, contains some server configuration flags). PacketTypeAccept = 2 // PacketTypeAcknowledge identifies an Acknowledge packet. PacketTypeAcknowledge = 3 // PacketTypeRefuse identifies a Refuse packet. Sent when e.g. the connect // descriptor is incorrect. PacketTypeRefuse = 4 // PacketTypeRedirect idenfies a Redirect packet. The server can respond to // a Connect packet with a Redirect containing a new connect descriptor. PacketTypeRedirect = 5 // PacketTypeData identifies a Data packet. The packet's payload may have // further structure. PacketTypeData = 6 // PacketTypeNull identifies a Null packet. PacketTypeNull = 7 // PacketTypeAbort identifies an Abort packet. PacketTypeAbort = 9 // PacketTypeResend identifies a Resend packet. When the server sends this // packet, the client sends the exact data that it sent previously. PacketTypeResend = 11 // PacketTypeMarker identifies a Marker packet. PacketTypeMarker = 12 // PacketTypeAttention identifies an Attention packet. PacketTypeAttention = 13 // PacketTypeControl identifies a Control packet. PacketTypeControl = 14 )
const ( SOBrokenConnectNotify ServiceOptions = 0x2000 SOPacketChecksum = 0x1000 SOHeaderChecksum = 0x0800 SOFullDuplex = 0x0400 SOHalfDuplex = 0x0200 SOUnknown0100 = 0x0100 SOUnknown0080 = 0x0080 SOUnknown0040 = 0x0040 SOUnknown0020 = 0x0020 SODirectIO = 0x0010 SOAttentionProcessing = 0x0008 SOCanReceiveAttention = 0x0004 SOCanSendAttention = 0x0002 SOUnknown0001 = 0x0001 SOUnknown4000 = 0x4000 SOUnknown8000 = 0x8000 )
const ( NTPCHangon NTProtocolCharacteristics = 0x8000 NTPCConfirmedRelease = 0x4000 NTPCTDUBasedIO = 0x2000 NTPCSpawnerRunning = 0x1000 NTPCDataTest = 0x0800 NTPCCallbackIO = 0x0400 NTPCAsyncIO = 0x0200 NTPCPacketIO = 0x0100 NTPCCanGrant = 0x0080 NTPCCanHandoff = 0x0040 NTPCGenerateSIGIO = 0x0020 NTPCGenerateSIGPIPE = 0x0010 NTPCGenerateSIGURG = 0x0008 NTPCUrgentIO = 0x0004 NTPCFullDuplex = 0x0002 NTPCTestOperation = 0x0001 )
const ( CFServicesWanted ConnectFlags = 0x01 CFInterchangeInvolved = 0x02 CFServicesEnabled = 0x04 CFServicesLinkedIn = 0x08 CFServicesRequired = 0x10 CFUnknown20 = 0x20 CFUnknown40 = 0x40 CFUnknown80 = 0x80 )
const ( DFSendToken DataFlags = 0x0001 DFRequestConfirmation = 0x0002 DFConfirmation = 0x0004 DFReserved = 0x0008 DFUnknown0010 = 0x0010 DFMoreData = 0x0020 DFEOF = 0x0040 DFConfirmImmediately = 0x0080 DFRequestToSend = 0x0100 DFSendNTTrailer = 0x0200 DFUnknown0400 = 0x0400 DFUnknown0800 = 0x0800 DFUnknown1000 = 0x1000 DFUnknown2000 = 0x2000 DFUnknown4000 = 0x4000 DFUnknown8000 = 0x8000 )
TODO: details
const ( // NSNServiceAuthentication identifies an Authentication service // (TODO: details). NSNServiceAuthentication NSNServiceType = 1 // NSNServiceEncryption identifies an Encryption service (TODO: details). NSNServiceEncryption = 2 // NSNServiceDataIntegrity identifies a Data Integrity service // (TODO: details). NSNServiceDataIntegrity = 3 // NSNServiceSupervisor identifies a Supervisor service (TODO: details). NSNServiceSupervisor = 4 )
const ( // NSNValueTypeString identifies a string value type. NSNValueTypeString NSNValueType = 0 // NSNValueTypeBytes identifies a binary value type (an array of bytes). NSNValueTypeBytes = 1 // NSNValueTypeUB1 identifies an unsigned 8-bit integer. NSNValueTypeUB1 = 2 // NSNValueTypeUB2 identifies an unsigned 16-bit big-endian integer. NSNValueTypeUB2 = 3 // NSNValueTypeUB4 identifies an unsigned 32-bit big-endian integer. NSNValueTypeUB4 = 4 // NSNValueTypeVersion identifies a 32-bit ReleaseVersion value. NSNValueTypeVersion = 5 // NSNValueTypeStatus identifies a 16-bit status value. NSNValueTypeStatus = 6 )
const ( // DataIDNSN identifies a Native Security Negotiation data payload. DataIDNSN uint32 = 0xdeadbeef )
Variables ¶
var ( // ErrInvalidData is returned when the server returns syntactically-invalid // (or very unlikely / problematic) data. ErrInvalidData = errors.New("server returned invalid data") // ErrInvalidInput is returned when user-supplied data is not valid. ErrInvalidInput = errors.New("caller provided invalid input") // ErrUnexpectedResponse is returned when the server returns a valid TNS // response but it is not the expected type. ErrUnexpectedResponse = errors.New("server returned unexpected response") // ErrBufferTooSmall is returned when the caller provides a buffer that is // too small for the required data. ErrBufferTooSmall = errors.New("buffer too small") )
Functions ¶
Types ¶
type ConnectFlags ¶
type ConnectFlags uint8
ConnectFlags are flags used by the client and the server to negotiate connection settings.
func (ConnectFlags) Set ¶
func (flags ConnectFlags) Set() map[string]bool
Set gets a set representation of the ConnectFlags.
type Connection ¶
type Connection struct {
// contains filtered or unexported fields
}
Connection holds the state for a scan connection to the Oracle server.
func (*Connection) Connect ¶
func (conn *Connection) Connect(connectDescriptor string) (*HandshakeLog, error)
Connect to the server and do a handshake with the given config.
func (*Connection) SendPacket ¶
func (conn *Connection) SendPacket(packet TNSPacketBody) (TNSPacketBody, error)
SendPacket sends the given packet body to the server (prefixing the appropriate header -- with flags == 0), and read / parse the response. Automatically handles Resend responses; the caller is responsible for handling other exceptional cases.
type DataFlags ¶
type DataFlags uint16
DataFlags is a 16-bit flags field used in the TNSData packet.
type Descriptor ¶
type Descriptor []DescriptorEntry
Descriptor is a nested series of parens, used for e.g. connect descriptors and for error responses. To simplify their usage in searches, they are stored in a flattened form. Since duplicate keys are allowed, a simple map will not work, so instead it stores an list of key/value pairs, in the order they appear in the string. NOTE: This is insufficient to re-construct the input (since there is no way to tell "array elements" stop), so there is no Encode method.
func DecodeDescriptor ¶
func DecodeDescriptor(descriptor string) (Descriptor, error)
DecodeDescriptor takes a descriptor in native Oracle format and returns a flattened map.
func (*Descriptor) GetValue ¶
func (descriptor *Descriptor) GetValue(key string) (string, error)
GetValue gets the unique Value for the given Key (in dotted string format). If a unique Value cannot be found (that is, there are no matches, or there is more than one match), returns "", ErrUnexpectedResponse.
func (Descriptor) GetValues ¶
func (descriptor Descriptor) GetValues(key string) []string
GetValues returns an array containing all Values in the descriptor that exactly match the given Key (key is in dotted string format).
type DescriptorEntry ¶
DescriptorEntry is a simple key-value pair representing a single primitive value in the descriptor string. The key is a dotted string representation of the path to the value, e.g. for "(A=(B=(C=ABC1)(C=ABC2)(D=ABD1))(E=AE1))", the DescriptorEntries would be {"A.B.C", "ABC1"}, {"A.B.C", "ABC2"}, {"A.B.D", "ABD1" }, {"A.E", "AE1"}.
type Flags ¶
type Flags struct { zgrab2.BaseFlags zgrab2.TLSFlags // Version is the client version number sent to the server in the Connect // packet. TODO: Find version number mappings. Version uint16 `long:"client-version" description:"The client version number to send." default:"312"` // MinVersion is the minimum protocol version that the client claims support // for in the Connect packet. Same format as Version above. MinVersion uint16 `long:"min-server-version" description:"The minimum supported client version to send in the connect packet." default:"300"` // ReleaseVersion is the five-component dotted-decimal release version // string the client should send during native Native Security Negotiation. ReleaseVersion string `` /* 173-byte string literal not displayed */ // GlobalServiceOptions sets the ServiceOptions flags the client will send // to the server in the Connect packet. 16 bits. GlobalServiceOptions string `long:"global-service-options" description:"The Global Service Options flags to send in the connect packet." default:"0x0C41"` // SDU sets the requested Session Data Unit size value the client sends in // the Connect packet. 16 bits. SDU string `long:"sdu" description:"The SDU value to send in the connect packet." default:"0x2000"` // TDU sets the request Transport Data Unit size value the client sends in // the Connect packet. 16 bits. TDU string `long:"tdu" description:"The TDU value to send in the connect packet." default:"0xFFFF"` // ProtocolCharacteristics sets the protocol characteristics flags the // client sends to the server in the Connect packet. 16 bits. ProtocolCharacterisics string `` /* 128-byte string literal not displayed */ // ConnectFlags sets the connect flags the client sends to the server in the // Connect packet. The upper 16 bits give the first byte, the lower 16 bits // the second byte. ConnectFlags string `long:"connect-flags" description:"The connect flags for the connect packet." default:"0x4141"` // ConnectDescriptor sets the connect descriptor the client sends in the // data payload of the Connect packet. // See https://docs.oracle.com/cd/E11882_01/network.112/e41945/glossary.htm#BGBEAGEA ConnectDescriptor string `long:"connect-descriptor" description:"The connect descriptor to use in the connect packet."` // TCPS determines whether the connection starts with a TLS handshake. TCPS bool `long:"tcps" description:"Wrap the connection with a TLS handshake."` // NewTNS causes the client to use the newer TNS header format with 32-bit // lengths. NewTNS bool `long:"new-tns" description:"If set, use new-style TNS headers"` // Verbose causes more verbose logging, and includes debug fields inthe scan // results. Verbose bool `long:"verbose" description:"More verbose logging, include debug fields in the scan results"` }
Flags holds the command-line configuration for the HTTP scan module. Populated by the framework.
type HandshakeLog ¶
type HandshakeLog struct { // AcceptVersion is the protocol version value from the Accept packet. AcceptVersion uint16 `json:"accept_version"` // GlobalServiceOptions is the set of GlobalServiceOptions flags that the // server returns in the Accept packet. GlobalServiceOptions map[string]bool `json:"global_service_options,omitempty"` // ConnectFlags0 is the first set of ConnectFlags values that the server // returns in the Accept packet for the first. ConnectFlags0 map[string]bool `json:"connect_flags0,omitempty"` // ConnectFlags1 is the second set of ConnectFlags values that the server // returns in the Accept packet for the first. ConnectFlags1 map[string]bool `json:"connect_flags1,omitempty"` // DidResend is true if the server sent a Resend packet in response to the // client's first Connect packet. DidResend bool `json:"did_resend"` // RedirectTargetRaw is the connect descriptor returned by the server in the // Redirect packet, if one is sent. Otherwise it is empty/omitted. RedirectTargetRaw string `json:"redirect_target_raw,omitempty"` // RedirectTarget is the parsed connect descriptor returned by the server in // the Redirect packet, if one is sent. Otherwise it is empty/omitted. RedirectTarget Descriptor `json:"redirect_target,omitempty"` // RefuseErrorRaw is the Data from the Refuse packet returned by the server; // it is empty if the server does not return a Refuse packet. RefuseErrorRaw string `json:"refuse_error_raw,omitempty"` // RefuseError is the parsed descriptor returned by the server in the Refuse // packet; it is empty if the server does not return a Refuse packet. RefuseError Descriptor `json:"refuse_error,omitempty"` // RefuseReasonApp is the "AppReason" returned by the server in a Refused // response packet. RefuseReasonApp string `json:"refuse_reason_app,omitempty"` // RefuseReasonSys is the "SysReason" returned by the server in a Refused // response packet. RefuseReasonSys string `json:"refuse_reason_sys,omitempty"` // RefuseVersion is the parsed DESCRIPTION.VSNNUM field from the RefuseError // string returned by the server in the Refuse packet, in dotted-decimal // format. RefuseVersion string `json:"refuse_version,omitempty"` // NSNVersion is the ReleaseVersion string (in dotted decimal format) in the // root of the Native Service Negotiation packet. NSNVersion string `json:"nsn_version,omitempty"` // NSNServiceVersions is a map from the Native Service Negotiation service // name to the ReleaseVersion in that service packet. NSNServiceVersions map[string]string `json:"nsn_service_versions,omitempty"` }
HandshakeLog gives the results of the initial connection handshake in a form suitable for zgrab2 output.
type Module ¶
type Module struct { }
Module implements the zgrab2.Module interface.
func (*Module) Description ¶
Description returns an overview of this module.
func (*Module) NewFlags ¶
func (module *Module) NewFlags() interface{}
NewFlags returns a default Flags object.
func (*Module) NewScanner ¶
NewScanner returns a new Scanner instance.
type NSNOptions ¶
type NSNOptions uint8
NSNOptions is an 8-bit flags value describing the Native Security Negotiation options (TODO: details).
type NSNService ¶
type NSNService struct { Type NSNServiceType Values []NSNValue Marker uint32 }
NSNService is an individual "packet" inside the NSN data payload; it consists in an identifier and a list of values or "sub-packets" giving configuration settings for that service type. These are somewhat described here: https://docs.oracle.com/cd/B19306_01/network.102/b14212/troublestng.htm
func ReadNSNService ¶
func ReadNSNService(reader io.Reader, ret *NSNService) (*NSNService, error)
ReadNSNService reads an NSNService packet from the stream. On failure to read a service, returns nil + an error (though the stream will be in a bad state).
func (*NSNService) Encode ¶
func (service *NSNService) Encode() ([]byte, error)
Encode returns the encoded NSNService in a newly allocated buffer. If the length of the encoded value would be larger than 16 bits, returns an error.
func (*NSNService) GetSize ¶
func (service *NSNService) GetSize() (uint16, error)
GetSize returns the encoded size of the NSNService. Returns an error rather than overflowing.
type NSNServiceType ¶
type NSNServiceType uint16
NSNServiceType is an enumerated type identifying the "service" types inside a NSN packet.
func (NSNServiceType) IsUnknown ¶
func (typ NSNServiceType) IsUnknown() bool
IsUnknown returns true iff the service type value is not one of the recognized enum values.
func (NSNServiceType) String ¶
func (typ NSNServiceType) String() string
String gives the string representation of the service type.
type NSNValue ¶
type NSNValue struct { Type NSNValueType Value []byte }
NSNValue represents a single value or "sub-packet" within an NSNService. It consists of a type identifier and the value itself.
func NSNValueBytes ¶
NSNValueBytes returns a NSNValue of type Bytes with the given value.
func NSNValueStatus ¶
NSNValueStatus returns a NSNValue of type Status with the given value.
func NSNValueString ¶
NSNValueString returns a NSNValue of type String with the given value.
func NSNValueUB1 ¶
NSNValueUB1 returns a NSNValue of type UB1 with the given value.
func NSNValueUB2 ¶
NSNValueUB2 returns a NSNValue of type UB2 with the given value.
func NSNValueVersion ¶
NSNValueVersion returns a NSNValue of type Version whose value is given in dotted-decimal format.
func ReadNSNValue ¶
ReadNSNValue reads a NSNValue from the stream, returns nil/error if one cannot be read (leaving the stream in a bad state).
func (*NSNValue) Encode ¶
Encode returns the encoding of the NSNValue in a newly-allocated byte slice. Returns an error if the length of the value would be longer than 16 bits.
func (*NSNValue) MarshalJSON ¶
MarshalJSON encodes the NSNValue as a JSON object: a type/value pair.
type NSNValueType ¶
type NSNValueType uint16
NSNValueType is a 16-bit enumerated value identifying the different data types of the values or "sub-packets" in the NSNService packets. NOTE: this list may not be comprehensive.
type NTProtocolCharacteristics ¶
type NTProtocolCharacteristics uint16
NTProtocolCharacteristics are flags used by the client and the server to negotiate connection settings.
func (NTProtocolCharacteristics) Set ¶
func (flags NTProtocolCharacteristics) Set() map[string]bool
Set gets a set representation of the NTProtocolCharacteristics flags.
type PacketType ¶
type PacketType uint8
PacketType is the type identifier used in the TNS header to identify the format of the packet.
func (PacketType) String ¶
func (packetType PacketType) String() string
String returns the string representation of the PacketType.
type RefuseReason ¶
type RefuseReason uint8
RefuseReason is an enumeration describing the reason the request was refused. TODO: details.
func (RefuseReason) String ¶
func (reason RefuseReason) String() string
type ReleaseVersion ¶
type ReleaseVersion uint32
ReleaseVersion is a packed version number describing the release version of a specific (sub-)component. Logically it has five components, described at https://docs.oracle.com/cd/B28359_01/server.111/b28310/dba004.htm: major.maintenance.appserver.component.platform. The number of bits allocated to each are respectively 8.4.4.8.8, so 0x01230405 would denote "1.2.3.4.5".
func EncodeReleaseVersion ¶
func EncodeReleaseVersion(value string) (ReleaseVersion, error)
EncodeReleaseVersion gets a ReleaseVersion instance from its dotted-decimal representation, e.g.: EncodeReleaseVersion("64.3.2.1.0") = ReleaseVersion(0x40320100).
func (ReleaseVersion) Bytes ¶
func (v ReleaseVersion) Bytes() []byte
Bytes returns the big-endian binary encoding of the release version.
func (ReleaseVersion) String ¶
func (v ReleaseVersion) String() string
String returns the dotted-decimal representation of the release version: major.maintenance.appserver.component.platform.
type ScanResults ¶
type ScanResults struct { // Handshake is the log of the TNS handshake between client and server. Handshake *HandshakeLog `json:"handshake,omitempty"` // TLSLog contains the log of the TLS handshake (and any additional // configured TLS scan operations). TLSLog *zgrab2.TLSLog `json:"tls,omitempty"` }
ScanResults instances are returned by the module's Scan function.
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner implements the zgrab2.Scanner interface.
func (*Scanner) GetTrigger ¶
GetTrigger returns the Trigger defined in the Flags.
func (*Scanner) InitPerSender ¶
InitPerSender initializes the scanner for a given sender.
func (*Scanner) Scan ¶
func (scanner *Scanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error)
Scan does the following:
- Make a TCP connection to the target
- If --tcps is set, do a TLS handshake and use the wrapped socket in future calls.
- Instantiate the TNS driver (TNSMode12c if --new-tns is set, otherwise TNSModeOld)
- Send the Connect packet to the server with the provided options and connect descriptor
- If the server responds with a valid TNS packet, an Oracle server has been detected. If not, fail.
- If the response is... a. ...a Resend packet, then set result.DidResend and re-send the packet. b. ...a Refused packet, then set the result.RefuseReason and RefuseError, then exit. c. ...a Redirect packet, then set result.RedirectTarget and exit. d. ...an Accept packet, go to 7 e. ...anything else: exit with SCAN_APPLICATION_ERROR
- Pull the server protocol version and other flags from the Accept packet into the results, then send a Native Security Negotiation Data packet.
- If the response is not a Data packet, exit with SCAN_APPLICATION_ERROR.
- Pull the versions out of the response and exit with SCAN_SUCCESS.
type ServiceOptions ¶
type ServiceOptions uint16
ServiceOptions are flags used by the client and server in negotiating the connection settings.
func (ServiceOptions) Set ¶
func (flags ServiceOptions) Set() map[string]bool
Set gets a set representation of the ServiceOptions flags.
type TNSAccept ¶
type TNSAccept struct { // Version is the protocol version the server is using. TODO: find the // actual format. Version uint16 // GlobalServiceOptions specify connection settings (TODO: details). GlobalServiceOptions ServiceOptions // SDU gives the Session Data Unit size for this connection. SDU uint16 // TDU gives the Transfer Data Unit size for this connection. TDU uint16 // ByteOrder gives the encoding of the integer 1 as a 16-bit integer // (NOTE: clients and servers seem to routinely send a little-endian 1, // while clearly using big-endian encoding for integers, at least at the // TNS layer...?) ByteOrder [2]byte // DataLength is the length of the AcceptData payload. DataLength uint16 // DataOffset is the offset from the start of the packet (including the // 8 bytes of the header) of the AcceptData. Always (?) 0x20. DataOffset uint16 // ConnectFlags0 specifies connection settings (TODO: details). ConnectFlags0 ConnectFlags // ConnectFlags1 specifies connection settings (TODO: details). ConnectFlags1 ConnectFlags // Unknown18 provides support for case like TNSConnect, where there is // "data" after the end of the known packet but before the start of the // AcceptData pointed to by DataOffset. // Currently this is always 8 bytes. Unknown18 []byte // AcceptData is the packet payload (TODO: details). AcceptData []byte }
TNSAccept is the server's response to a successful TNSConnect request from the client.
func ReadTNSAccept ¶
ReadTNSAccept reads a TNSAccept packet body from the stream. reader should point to the first byte after the TNSHeader.
func (*TNSAccept) GetType ¶
func (packet *TNSAccept) GetType() PacketType
GetType identifies the packet as a PacketTypeAccept.
type TNSConnect ¶
type TNSConnect struct { // Version is the client's version. // TODO: Find Version format (10r2 = 0x0139? 9r2 = 0x0138? 9i = 0x0137? 8 = 0x0136?) Version uint16 // MinVersion is the lowest version the client supports. MinVersion uint16 // GlobalServiceOptions specify connection settings (TODO: details). GlobalServiceOptions ServiceOptions // SDU gives the requested Session Data Unit size. (often 0x0000) SDU uint16 // TDU gives the requested Transfer Data Unit size. (often 0x7fff) TDU uint16 // ProtocolCharacteristics specify connection settings (TODO: details). ProtocolCharacteristics NTProtocolCharacteristics // TODO MaxBeforeAck uint16 // ByteOrder gives the encoding of the integer 1 as a 16-bit integer with // the client's desired endianness. ByteOrder [2]byte // DataLength gives the length of the connect descriptor. DataLength uint16 // DataOffset gives the offset (from the start of the header) of the // connect descriptor -- i.e. 0x3A + len(Unknown3A). DataOffset uint16 // MaxResponseSize gives the client's desired maximum response size. MaxResponseSize uint32 // ConnectFlags0 specifies connection settings (TODO: details). ConnectFlags0 ConnectFlags // ConnectFlags1 specifies connection settings (TODO: details). ConnectFlags1 ConnectFlags // TODO CrossFacility0 uint32 // TODO CrossFacility1 uint32 // TODO ConnectionID0 [8]byte // TODO ConnectionID1 [8]byte // Unknown3A is the data between the last trace unique connection ID and the // connect descriptor, starting from offset 0x3A. // The DataOffset points past this, and the DataLength counts from there, so // this is indeed part of the "header". // On recent versions of Oracle this is 12 bytes. // On older versions, it is 0 bytes. Unknown3A []byte // ConnectDescriptor is the packet's payload, a nested sequence of // (KEY=(KEY1=...)(KEY2=...)). See Oracle's "About Connect Descriptors" at // https://docs.oracle.com/cd/E11882_01/network.112/e41945/concepts.htm#NETAG253 ConnectDescriptor string }
TNSConnect is sent by the client to request a connection with the server. The server may respond with (at least) Accept, Resend or Redirect. If len(packet) > 255, send a packet with data="", followed by data
func ReadTNSConnect ¶
func ReadTNSConnect(reader io.Reader, header *TNSHeader) (*TNSConnect, error)
ReadTNSConnect reads a TNSConnect packet from the reader, which should point to the first byte after the end of the TNSHeader.
func (*TNSConnect) Encode ¶
func (packet *TNSConnect) Encode() ([]byte, error)
Encode the TNSConnect packet body into a newly-allocated buffer. If the packet would be longer than 255 bytes, the data is empty and the connection string immediately follows.
func (*TNSConnect) GetType ¶
func (packet *TNSConnect) GetType() PacketType
GetType identifies the packet as a PacketTypeConnect.
type TNSData ¶
type TNSData struct { // DataFlags gives information on the data (TODO: details) DataFlags DataFlags // Data is the packet's payload. Its length is equal to the header's length // less 10 bytes (8 for the header itself, 2 for the DataFlags). Data []byte }
TNSData is the packet type used to send (more or less) arbitrary data between client and server. All packets have the DataFlags, and for many, the first four bytes of the data have a 32-bit value identifying the type of data.
func ReadTNSData ¶
ReadTNSData reads a TNSData packet from the stream, which should point to the first byte after the TNSHeader.
func (*TNSData) GetID ¶
GetID returns a TNSData's ID (the first four bytes of the data), if available otherwise returns 0.
func (*TNSData) GetType ¶
func (packet *TNSData) GetType() PacketType
GetType identifies the packet as PacketTypeData.
type TNSDataNSN ¶
type TNSDataNSN struct { // ID is the TNSData identifier for NSN (0xdeadbeef) ID uint32 // Version is the ReleaseVersion, which seems to often be 0 in practice. Version ReleaseVersion // Options is an 8-bit flags value giving options for the connection (TODO: // details). Options NSNOptions // Services is an array of NSNService values, giving the configuration for // that service type. Services []NSNService }
TNSDataNSN represents the decoded body of a TNSData packet for a Native Security Negotiation payload.
func DecodeTNSDataNSN ¶
func DecodeTNSDataNSN(data []byte) (*TNSDataNSN, error)
DecodeTNSDataNSN reads a TNSDataNSN packet from a TNSData body.
func ReadTNSDataNSN ¶
func ReadTNSDataNSN(reader io.Reader) (*TNSDataNSN, error)
ReadTNSDataNSN reads a TNSDataNSN packet from a stream pointing to the start of the NSN data.
func (*TNSDataNSN) Encode ¶
func (packet *TNSDataNSN) Encode() ([]byte, error)
Encode returns the encoded TNSDataNSN data in a newly-allocated buffer.
func (*TNSDataNSN) GetSize ¶
func (packet *TNSDataNSN) GetSize() (uint16, error)
GetSize returns the encoded size of the TNSDataNSN body. Returns an error if the data length would be longer than 16 bits.
type TNSDriver ¶
type TNSDriver struct { // Mode determines what type of packets will be sent -- TNSModeOld or // TNSMode12c. Mode TNSMode }
TNSDriver abstracts the bottom-level TNS packet encoding.
func (*TNSDriver) EncodePacket ¶
EncodePacket encodes the packet (header + body). If header is nil, create one with no flags and the type set to the body's type. If header.Length == 0, set it to the appropriate value (length of encoded body + 8).
func (*TNSDriver) ReadTNSHeader ¶
ReadTNSHeader reads/decodes a TNSHeader from the first 8 bytes of the stream.
type TNSHeader ¶
type TNSHeader struct { // Length is the big-endian length of the entire packet, including the 8 // bytes of the header itself. // For versions prior to 12(c?), the length is a uint16. For newer versions, // it is a uint32 (taking the place of the PacketChecksum) Length uint32 // PacketChecksum is in practice set to 0. PacketChecksum uint16 // PacketType identifies the type of packet data. Type PacketType // Flags is called "Reserved Byte" in Wireshark. Flags TNSFlags // HeaderChecksum is in practice set to 0. HeaderChecksum uint16 // contains filtered or unexported fields }
TNSHeader is the 8-byte header that precedes all TNS packets.
type TNSMode ¶
type TNSMode int
TNSMode determines the format of the TNSHeader; used in TNSDriver.
const ( // TNSModeOld uses the pre-12c format TNSHeader, with 16-bit lengths. TNSModeOld TNSMode = 0 // TNSMode12c uses the newer TNSHeader format, with 32-bit lengths and no // PacketChecksum. TNSMode12c = 1 )
type TNSPacket ¶
type TNSPacket struct { Header *TNSHeader Body TNSPacketBody }
TNSPacket is a TNSHeader + a body.
type TNSPacketBody ¶
type TNSPacketBody interface { GetType() PacketType Encode() ([]byte, error) }
TNSPacketBody is the interface for the "body" of a TNSPacket (that is, everything after the header).
type TNSRedirect ¶
type TNSRedirect struct { // DataLength is the length of the packet's Data payload. DataLength uint16 // Data is the TNSRedirect's payload -- it contains a new connect descriptor // for the client to use in a subsequent TNSConnect call. Data []byte }
TNSRedirect is returned by the server in response to a TNSConnect when it needs to direct the caller elsewhere. Its Data is a new connect descriptor for the caller to use.
func ReadTNSRedirect ¶
func ReadTNSRedirect(reader io.Reader, header *TNSHeader) (*TNSRedirect, error)
ReadTNSRedirect reads a TNSRedirect packet from the stream, which should point to the first byte after the TNSHeader.
func (*TNSRedirect) Encode ¶
func (packet *TNSRedirect) Encode() ([]byte, error)
Encode the TNSRedirect packet body into a newly-allocated buffer.
func (*TNSRedirect) GetType ¶
func (packet *TNSRedirect) GetType() PacketType
GetType identifies the packet as PacketTypeRedirect.
type TNSRefuse ¶
type TNSRefuse struct { // TODO: details AppReason RefuseReason // TODO: details SysReason RefuseReason // DataLength is the length of the packet's Data payload DataLength uint16 // Data is the packet's payload. TODO: details Data []byte }
TNSRefuse is returned by the server when an error occurs (for instance, an invalid connect descriptor).
func ReadTNSRefuse ¶
ReadTNSRefuse reads a TNSRefuse packet from the stream, which should point to the first byte after the TNSHeader.
func (*TNSRefuse) GetType ¶
func (packet *TNSRefuse) GetType() PacketType
GetType identifies the packet as PacketTypeRefuse.
type TNSResend ¶
type TNSResend struct { }
TNSResend is empty -- the entire packet is just a header with a type of PacketTypeResend (0x0b == 11).
func ReadTNSResend ¶
ReadTNSResend reads a TNSResend packet from the reader, which should point to the first byte after the end of the header -- so in this case, it reads nothing and returns an empty TNSResend{} instance.
func (*TNSResend) Encode ¶
Encode the packet body (which for a Resend packet just means returning an empty byte slice).
func (*TNSResend) GetType ¶
func (packet *TNSResend) GetType() PacketType
GetType identifies the packet as a PacketTypeResend.