oracle

package
v0.0.0-...-5d1382d Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2023 License: Apache-2.0, ISC Imports: 11 Imported by: 0

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

View Source
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
)
View Source
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
)
View Source
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
)
View Source
const (
	CFServicesWanted      ConnectFlags = 0x01
	CFInterchangeInvolved              = 0x02
	CFServicesEnabled                  = 0x04
	CFServicesLinkedIn                 = 0x08
	CFServicesRequired                 = 0x10
	CFUnknown20                        = 0x20
	CFUnknown40                        = 0x40
	CFUnknown80                        = 0x80
)
View Source
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

View Source
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
)
View Source
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
)
View Source
const (
	// DataIDNSN identifies a Native Security Negotiation data payload.
	DataIDNSN uint32 = 0xdeadbeef
)

Variables

View Source
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

func RegisterModule

func RegisterModule()

RegisterModule registers the zgrab2 module.

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.

func (DataFlags) Set

func (flags DataFlags) Set() map[string]bool

Set gets a set representation of the DataFlags.

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

type DescriptorEntry struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

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.

func (*Flags) Help

func (flags *Flags) Help() string

Help returns the module's help string.

func (*Flags) Validate

func (flags *Flags) Validate(args []string) error

Validate checks that the flags are valid. On success, returns nil. On failure, returns an error instance describing the error.

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

func (module *Module) Description() string

Description returns an overview of this module.

func (*Module) NewFlags

func (module *Module) NewFlags() interface{}

NewFlags returns a default Flags object.

func (*Module) NewScanner

func (module *Module) NewScanner() zgrab2.Scanner

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

func NSNValueBytes(bytes []byte) *NSNValue

NSNValueBytes returns a NSNValue of type Bytes with the given value.

func NSNValueStatus

func NSNValueStatus(val uint16) *NSNValue

NSNValueStatus returns a NSNValue of type Status with the given value.

func NSNValueString

func NSNValueString(val string) *NSNValue

NSNValueString returns a NSNValue of type String with the given value.

func NSNValueUB1

func NSNValueUB1(val uint8) *NSNValue

NSNValueUB1 returns a NSNValue of type UB1 with the given value.

func NSNValueUB2

func NSNValueUB2(val uint16) *NSNValue

NSNValueUB2 returns a NSNValue of type UB2 with the given value.

func NSNValueVersion

func NSNValueVersion(v string) *NSNValue

NSNValueVersion returns a NSNValue of type Version whose value is given in dotted-decimal format.

func ReadNSNValue

func ReadNSNValue(reader io.Reader, ret *NSNValue) (*NSNValue, error)

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

func (value *NSNValue) Encode() ([]byte, error)

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

func (value *NSNValue) MarshalJSON() ([]byte, error)

MarshalJSON encodes the NSNValue as a JSON object: a type/value pair.

func (*NSNValue) String

func (value *NSNValue) String() string

String gives the friendly encoding of the sub-packet value; integers are given in decimal, versions in dotted decimal format, binary data as base64, strings as strings.

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) GetName

func (scanner *Scanner) GetName() string

GetName returns the Scanner name defined in the Flags.

func (*Scanner) GetTrigger

func (scanner *Scanner) GetTrigger() string

GetTrigger returns the Trigger defined in the Flags.

func (*Scanner) Init

func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error

Init initializes the Scanner.

func (*Scanner) InitPerSender

func (scanner *Scanner) InitPerSender(senderID int) error

InitPerSender initializes the scanner for a given sender.

func (*Scanner) Protocol

func (scanner *Scanner) Protocol() string

Protocol returns the protocol identifier of the scan.

func (*Scanner) Scan

func (scanner *Scanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error)

Scan does the following:

  1. Make a TCP connection to the target
  2. If --tcps is set, do a TLS handshake and use the wrapped socket in future calls.
  3. Instantiate the TNS driver (TNSMode12c if --new-tns is set, otherwise TNSModeOld)
  4. Send the Connect packet to the server with the provided options and connect descriptor
  5. If the server responds with a valid TNS packet, an Oracle server has been detected. If not, fail.
  6. 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
  7. Pull the server protocol version and other flags from the Accept packet into the results, then send a Native Security Negotiation Data packet.
  8. If the response is not a Data packet, exit with SCAN_APPLICATION_ERROR.
  9. 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

func ReadTNSAccept(reader io.Reader, header *TNSHeader) (*TNSAccept, error)

ReadTNSAccept reads a TNSAccept packet body from the stream. reader should point to the first byte after the TNSHeader.

func (*TNSAccept) Encode

func (packet *TNSAccept) Encode() ([]byte, error)

Encode the TNSAccept packet body into a newly-allocated byte slice.

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

func ReadTNSData(reader io.Reader, header *TNSHeader) (*TNSData, error)

ReadTNSData reads a TNSData packet from the stream, which should point to the first byte after the TNSHeader.

func (*TNSData) Encode

func (packet *TNSData) Encode() ([]byte, error)

Encode the TNSData packet body into a newly-allocated buffer.

func (*TNSData) GetID

func (packet *TNSData) GetID() uint32

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

func (driver *TNSDriver) EncodePacket(packet *TNSPacket) ([]byte, error)

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

func (driver *TNSDriver) ReadTNSHeader(reader io.Reader) (*TNSHeader, error)

ReadTNSHeader reads/decodes a TNSHeader from the first 8 bytes of the stream.

func (*TNSDriver) ReadTNSPacket

func (driver *TNSDriver) ReadTNSPacket(reader io.Reader) (*TNSPacket, error)

ReadTNSPacket reads a TNSPacket from the stream, or returns nil + an error if one cannot be read.

type TNSFlags

type TNSFlags uint8

TNSFlags is the type for the TNS header's flags.

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.

func (*TNSHeader) Encode

func (header *TNSHeader) Encode() ([]byte, error)

Encode returns the encoded TNSHeader.

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

func ReadTNSRefuse(reader io.Reader, header *TNSHeader) (*TNSRefuse, error)

ReadTNSRefuse reads a TNSRefuse packet from the stream, which should point to the first byte after the TNSHeader.

func (*TNSRefuse) Encode

func (packet *TNSRefuse) Encode() ([]byte, error)

Encode the TNSRefuse packet body into a newly-allocated buffer.

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

func ReadTNSResend(reader io.Reader, header *TNSHeader) (*TNSResend, error)

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

func (packet *TNSResend) Encode() ([]byte, error)

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.

Jump to

Keyboard shortcuts

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