packetgen-plugin-smb 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/packetgen-plugin-smb.rb +7 -5
- data/lib/packetgen/plugin/gssapi.rb +125 -0
- data/lib/packetgen/plugin/smb.rb +26 -32
- data/lib/packetgen/plugin/smb/blocks.rb +2 -2
- data/lib/packetgen/plugin/smb/browser.rb +3 -3
- data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +3 -3
- data/lib/packetgen/plugin/smb/browser/host_announcement.rb +4 -4
- data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +3 -3
- data/lib/packetgen/plugin/smb/close.rb +9 -59
- data/lib/packetgen/plugin/smb/close/request.rb +45 -0
- data/lib/packetgen/plugin/smb/close/response.rb +36 -0
- data/lib/packetgen/plugin/smb/filetime.rb +10 -9
- data/lib/packetgen/plugin/smb/nt_create_and_x.rb +9 -264
- data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +159 -0
- data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +128 -0
- data/lib/packetgen/plugin/smb/string.rb +4 -4
- data/lib/packetgen/plugin/smb/trans.rb +9 -190
- data/lib/packetgen/plugin/smb/trans/request.rb +121 -0
- data/lib/packetgen/plugin/smb/trans/response.rb +94 -0
- data/lib/packetgen/plugin/smb2.rb +181 -0
- data/lib/packetgen/plugin/smb2/base.rb +31 -0
- data/lib/packetgen/plugin/smb2/error.rb +50 -0
- data/lib/packetgen/plugin/smb2/guid.rb +68 -0
- data/lib/packetgen/plugin/smb2/negotiate.rb +22 -0
- data/lib/packetgen/plugin/smb2/negotiate/context.rb +131 -0
- data/lib/packetgen/plugin/smb2/negotiate/request.rb +166 -0
- data/lib/packetgen/plugin/smb2/negotiate/response.rb +190 -0
- data/lib/packetgen/plugin/smb2/session_setup.rb +21 -0
- data/lib/packetgen/plugin/smb2/session_setup/request.rb +98 -0
- data/lib/packetgen/plugin/smb2/session_setup/response.rb +69 -0
- data/lib/packetgen/plugin/smb_version.rb +1 -1
- data/packetgen-plugin-smb.gemspec +2 -1
- metadata +42 -4
@@ -0,0 +1,131 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
class SMB2
|
10
|
+
module Negotiate
|
11
|
+
# NegotiateContext structure.
|
12
|
+
# 0 1 2 3
|
13
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
14
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
15
|
+
# | Type | DataLength |
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | Reserved |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | Data (variable) |
|
20
|
+
# + +
|
21
|
+
# | ... |
|
22
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
23
|
+
# @author Sylvain Daubert
|
24
|
+
class Context < PacketGen::Types::Fields
|
25
|
+
# Known types
|
26
|
+
TYPES = {
|
27
|
+
'PREAUTH_INTEGRITY_CAP' => 1,
|
28
|
+
'ENCRYPTION_CAP' => 2
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
# @!attribute type
|
32
|
+
# 16-bit context type
|
33
|
+
# @return [Integer]
|
34
|
+
define_field :type, PacketGen::Types::Int16leEnum, enum: TYPES
|
35
|
+
# @!attribute data_length
|
36
|
+
# 16-bit data length
|
37
|
+
# @return [Integer]
|
38
|
+
define_field :data_length, PacketGen::Types::Int16le
|
39
|
+
# @!attribute reserved
|
40
|
+
# 32-bit reserved field
|
41
|
+
# @return [Integer]
|
42
|
+
define_field :reserved, PacketGen::Types::Int32le
|
43
|
+
# @!attribute data
|
44
|
+
# context data
|
45
|
+
# @return [String]
|
46
|
+
define_field :data, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: h[:data_length]) }
|
47
|
+
# @!attribute pad
|
48
|
+
# Padding to align next context on a 8-byte offset
|
49
|
+
# @return [String]
|
50
|
+
define_field :pad, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: -> { v = 8 - (h.offset_of(:data) + h.data_length) % 8; v == 8 ? 0 : v }) }
|
51
|
+
|
52
|
+
# @private
|
53
|
+
alias old_read read
|
54
|
+
|
55
|
+
# Populate object from a binary string
|
56
|
+
# @param [String] str
|
57
|
+
# @return [Context]
|
58
|
+
def read(str)
|
59
|
+
return self if str.nil?
|
60
|
+
if self.instance_of? Context
|
61
|
+
self[:type].read str[0, 2]
|
62
|
+
name = TYPES.key(type)
|
63
|
+
return old_read(str) if name.nil?
|
64
|
+
|
65
|
+
klassname = name.downcase.capitalize.gsub(/_(\w)/) { $1.upcase }
|
66
|
+
return old_read(str) unless Negotiate.const_defined? klassname
|
67
|
+
|
68
|
+
klass = Negotiate.const_get(klassname)
|
69
|
+
klass.new.read str
|
70
|
+
else
|
71
|
+
old_read str
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get human-readable type
|
76
|
+
# @return [String]
|
77
|
+
def human_type
|
78
|
+
self[:type].to_human
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get human-readable context
|
82
|
+
# @return [String]
|
83
|
+
def to_human
|
84
|
+
human_type
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class PreauthIntegrityCap < Context
|
89
|
+
remove_field :data
|
90
|
+
# @!attribute hash_alg_count
|
91
|
+
# 16-bit number of hash algorithm in {#hash_alg}
|
92
|
+
# @return [Integer]
|
93
|
+
define_field_before :pad, :hash_alg_count, PacketGen::Types::Int16le
|
94
|
+
# @!attribute salt_length
|
95
|
+
# 16-bit length of {#salt} field, in bytes.
|
96
|
+
# @return [Integer]
|
97
|
+
define_field_before :pad, :salt_length, PacketGen::Types::Int16le
|
98
|
+
# @!attribute hash_alg
|
99
|
+
# Array of 16-bit integer IDs specifying the supported preauthentication
|
100
|
+
# hash algorithms
|
101
|
+
# @return [PacketGen::Types::ArrayOfInt16le]
|
102
|
+
define_field_before :pad, :hash_alg, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:hash_alg_count]) }
|
103
|
+
# @!attribute salt
|
104
|
+
# Salt value for hash
|
105
|
+
# @return [String]
|
106
|
+
define_field_before :pad, :salt, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: h[:salt_length]) }
|
107
|
+
update_field :pad, builder: ->(h, t) { t.new(length_from: -> { v = 8 - (h.offset_of(:salt) + h.salt_length) % 8; v == 8 ? 0 : v }) }
|
108
|
+
end
|
109
|
+
|
110
|
+
class EncryptionCap < Context
|
111
|
+
remove_field :data
|
112
|
+
# @!attribute cipher_count
|
113
|
+
# 16-bit number of cipher algorithm in {#ciphers}
|
114
|
+
# @return [Integer]
|
115
|
+
define_field_before :pad, :cipher_count, PacketGen::Types::Int16le
|
116
|
+
# @!attribute ciphers
|
117
|
+
# Array of 16-bit integer IDs specifying the supported encryption
|
118
|
+
# algorithms
|
119
|
+
# @return [PacketGen::Types::ArrayOfInt16le]
|
120
|
+
define_field_before :pad, :ciphers, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:hash_alg_count]) }
|
121
|
+
update_field :pad, builder: ->(h, t) { t.new(length_from: -> { v = 8 - (h.offset_of(:cipher_count) + h[:cipher_count].sz) % 8; v == 8 ? 0 : v }) }
|
122
|
+
end
|
123
|
+
|
124
|
+
# Array of {Context}
|
125
|
+
# @author Sylvain Daubert
|
126
|
+
class ArrayOfContext < PacketGen::Types::Array
|
127
|
+
set_of Context
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
class SMB2
|
10
|
+
module Negotiate
|
11
|
+
# SMB2 Negotiate request structure
|
12
|
+
# 0 1 2 3
|
13
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
14
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
15
|
+
# | StructureSize | DialectCount |
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | SecurityMode | Reserved |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | Capabilities |
|
20
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
21
|
+
# | ClientGUID |
|
22
|
+
# + +
|
23
|
+
# | |
|
24
|
+
# + +
|
25
|
+
# | |
|
26
|
+
# + +
|
27
|
+
# | |
|
28
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
29
|
+
# | ContextOffset |
|
30
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
31
|
+
# | ContextCount | Reserved2 |
|
32
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
33
|
+
# | Dialects (variable) |
|
34
|
+
# + +
|
35
|
+
# | ... |
|
36
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
37
|
+
# | Pad (variable) |
|
38
|
+
# + +
|
39
|
+
# | ... |
|
40
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
41
|
+
# | ContextList (variable) |
|
42
|
+
# + +
|
43
|
+
# | ... |
|
44
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
45
|
+
# @author Sylvain Daubert
|
46
|
+
class Request < Base
|
47
|
+
# Security modes
|
48
|
+
SECURITY_MODES = {
|
49
|
+
'signing_enabled' => 1,
|
50
|
+
'signing required' => 2
|
51
|
+
}
|
52
|
+
|
53
|
+
# @!attribute structure_size
|
54
|
+
# 16-bit negotiate request structure size. Should be 36.
|
55
|
+
# @return [Integer]
|
56
|
+
define_field :structure_size, PacketGen::Types::Int16le, default: 36
|
57
|
+
# @!attribute dialect_count
|
58
|
+
# 16-bit number of dialects that are contained in {#dialects}.
|
59
|
+
# @return [Integer]
|
60
|
+
define_field :dialect_count, PacketGen::Types::Int16le
|
61
|
+
# @!attribute security_mode
|
62
|
+
# 16-bit security mode field.
|
63
|
+
# @return [Integer]
|
64
|
+
define_field :security_mode, PacketGen::Types::Int16leEnum, enum: SECURITY_MODES
|
65
|
+
# @!attribute reserved
|
66
|
+
# 16-bit reserved field.
|
67
|
+
# @return [Integer]
|
68
|
+
define_field :reserved, PacketGen::Types::Int16le
|
69
|
+
# @!attribute capabilities
|
70
|
+
# 32-bit capabilities field.
|
71
|
+
# @return [Integer]
|
72
|
+
define_field :capabilities, PacketGen::Types::Int32le
|
73
|
+
# @!attribute cap_encryption
|
74
|
+
# Indicates if encryption is supported
|
75
|
+
# @return [Boolean]
|
76
|
+
# @!attribute cap_dir_leasing
|
77
|
+
# Indicates if directory leasing is supported
|
78
|
+
# @return [Boolean]
|
79
|
+
# @!attribute cap_persistent_handles
|
80
|
+
# Indicates if persisten handles are supported
|
81
|
+
# @return [Boolean]
|
82
|
+
# @!attribute cap_multi_channel
|
83
|
+
# Indicates if multiple channels are supported for a single session
|
84
|
+
# @return [Boolean]
|
85
|
+
# @!attribute cap_large_mtu
|
86
|
+
# Indicates if multi credit operations are supported
|
87
|
+
# @return [Boolean]
|
88
|
+
# @!attribute cap_leasing
|
89
|
+
# Indicates if leasing is supported
|
90
|
+
# @return [Boolean]
|
91
|
+
# @!attribute cap_dfs
|
92
|
+
# Indicates if Distributed File system (DFS) is supported
|
93
|
+
# @return [Boolean]
|
94
|
+
define_bit_fields_on :capabilities, :cap_rsv, 25, :cap_encryption, :cap_dir_leasing,
|
95
|
+
:cap_persistent_handles, :cap_multi_channel,
|
96
|
+
:cap_large_mtu, :cap_leasing, :cap_dfs
|
97
|
+
# @!attribute client_guid
|
98
|
+
# @return []
|
99
|
+
define_field :client_guid, GUID
|
100
|
+
# @!attribute context_offset
|
101
|
+
# Only for SMB3 dialect.
|
102
|
+
# @return [Integer]
|
103
|
+
define_field :context_offset, PacketGen::Types::Int32le
|
104
|
+
# @!attribute context_count
|
105
|
+
# Only for SMB3 dialect.
|
106
|
+
# @return [Integer]
|
107
|
+
define_field :context_count, PacketGen::Types::Int16le
|
108
|
+
# @!attribute reserved2
|
109
|
+
# Only for SMB3 dialect.
|
110
|
+
# @return [Integer]
|
111
|
+
define_field :reserved2, PacketGen::Types::Int16le
|
112
|
+
# @!attribute dialects
|
113
|
+
# Array of 16-bit integers specifying the supported dialtec revisions.
|
114
|
+
# @return [Array<PacketGen::Types::Int16le>]
|
115
|
+
define_field :dialects, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:dialect_count]) }
|
116
|
+
# @!attribute pad
|
117
|
+
# Optional padding between the end of the {#dialects} array and the first negotiate
|
118
|
+
# context in {#context_list} so that the first negotiate context is 8-byte aligned.
|
119
|
+
# @return [String]
|
120
|
+
define_smb2_pad_field :pad
|
121
|
+
# @!attribute context_list
|
122
|
+
# If {#dialects} contains the value 0x0311, then this field must contain an array
|
123
|
+
# of {Context}
|
124
|
+
# @return [ArrayOfContext]
|
125
|
+
define_field :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
|
126
|
+
|
127
|
+
# @return [String]
|
128
|
+
def inspect
|
129
|
+
super do |attr|
|
130
|
+
case attr
|
131
|
+
when :capabilities
|
132
|
+
value = bits_on(attr).reject { |_, v| v > 1 }
|
133
|
+
.keys
|
134
|
+
.select { |b| send("#{b}?") }
|
135
|
+
.map(&:to_s)
|
136
|
+
.join(',')
|
137
|
+
.gsub!(/cap_/, '')
|
138
|
+
value = '%-16s (0x%08x)' % [value, self[attr].to_i]
|
139
|
+
str = PacketGen::Inspect.shift_level
|
140
|
+
str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
|
141
|
+
attr, value]
|
142
|
+
when :dialects
|
143
|
+
list = self.dialects.map { |v| "%#04x" % v.to_i }.join(',')
|
144
|
+
str = PacketGen::Inspect.shift_level
|
145
|
+
str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
|
146
|
+
attr, list]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Calculate and set {#context_offset} field. Also calculate
|
152
|
+
# lengths in {Context contexts}.
|
153
|
+
# @return [Integer]
|
154
|
+
def calc_length
|
155
|
+
self.context_offset = SMB2.new.sz + offset_of(:context_list)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Protocol name
|
159
|
+
# @return [String]
|
160
|
+
def protocol_name
|
161
|
+
'SMB2::Negotiate::Request'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
class SMB2
|
10
|
+
module Negotiate
|
11
|
+
# SMB2 Negotiate response structure
|
12
|
+
# 0 1 2 3
|
13
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
14
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
15
|
+
# | StructureSize | SecurityMode |
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | DialectRevision | ContextCount |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | ServerGUID |
|
20
|
+
# + +
|
21
|
+
# | |
|
22
|
+
# + +
|
23
|
+
# | |
|
24
|
+
# + +
|
25
|
+
# | |
|
26
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
27
|
+
# | Capabilities |
|
28
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
29
|
+
# | MaxTranSize |
|
30
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
31
|
+
# | MaxReadSize |
|
32
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
33
|
+
# | MaxWriteSize |
|
34
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
35
|
+
# | SystemTime |
|
36
|
+
# + +
|
37
|
+
# | |
|
38
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
39
|
+
# | StartTime |
|
40
|
+
# + +
|
41
|
+
# | |
|
42
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
43
|
+
# | BufferOffset | BufferLength |
|
44
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
45
|
+
# | ContextOffset |
|
46
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
47
|
+
# | Buffer (variable) |
|
48
|
+
# + +
|
49
|
+
# | ... |
|
50
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
51
|
+
# | Pad (variable) |
|
52
|
+
# + +
|
53
|
+
# | ... |
|
54
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
55
|
+
# | ContextList (variable) |
|
56
|
+
# + +
|
57
|
+
# | ... |
|
58
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
59
|
+
# @author Sylvain Daubert
|
60
|
+
class Response < Base
|
61
|
+
# @!attribute structure_size
|
62
|
+
# 16-bit negotiate request structure size. Should be 65.
|
63
|
+
# @return [Integer]
|
64
|
+
define_field :structure_size, PacketGen::Types::Int16le, default: 65
|
65
|
+
# @!attribute security_mode
|
66
|
+
# 16-bit security mode field.
|
67
|
+
# @return [Integer]
|
68
|
+
define_field :security_mode, PacketGen::Types::Int16leEnum, enum: Negotiate::Request::SECURITY_MODES
|
69
|
+
# @!attribute dialect
|
70
|
+
# 16-bit prefered SMB2 protocol dialect number.
|
71
|
+
# @return [Integer]
|
72
|
+
define_field :dialect, PacketGen::Types::Int16le
|
73
|
+
# @!attribute context_count
|
74
|
+
# Only for SMB3 dialect.
|
75
|
+
# @return [Integer]
|
76
|
+
define_field :context_count, PacketGen::Types::Int16le
|
77
|
+
# @!attribute server_guid
|
78
|
+
# @return []
|
79
|
+
define_field :server_guid, GUID
|
80
|
+
# @!attribute capabilities
|
81
|
+
# 32-bit capabilities field.
|
82
|
+
# @return [Integer]
|
83
|
+
define_field :capabilities, PacketGen::Types::Int32le
|
84
|
+
# @!attribute cap_encryption
|
85
|
+
# Indicates if encryption is supported
|
86
|
+
# @return [Boolean]
|
87
|
+
# @!attribute cap_dir_leasing
|
88
|
+
# Indicates if directory leasing is supported
|
89
|
+
# @return [Boolean]
|
90
|
+
# @!attribute cap_persistent_handles
|
91
|
+
# Indicates if persisten handles are supported
|
92
|
+
# @return [Boolean]
|
93
|
+
# @!attribute cap_multi_channel
|
94
|
+
# Indicates if multiple channels are supported for a single session
|
95
|
+
# @return [Boolean]
|
96
|
+
# @!attribute cap_large_mtu
|
97
|
+
# Indicates if multi credit operations are supported
|
98
|
+
# @return [Boolean]
|
99
|
+
# @!attribute cap_leasing
|
100
|
+
# Indicates if leasing is supported
|
101
|
+
# @return [Boolean]
|
102
|
+
# @!attribute cap_dfs
|
103
|
+
# Indicates if Distributed File system (DFS) is supported
|
104
|
+
# @return [Boolean]
|
105
|
+
define_bit_fields_on :capabilities, :cap_rsv, 25, :cap_encryption, :cap_dir_leasing,
|
106
|
+
:cap_persistent_handles, :cap_multi_channel,
|
107
|
+
:cap_large_mtu, :cap_leasing, :cap_dfs
|
108
|
+
# @!attribute max_trans_size
|
109
|
+
# 32-bit value indicating the maximum size of the buffer used for
|
110
|
+
# QUERY_INFO, QUERY_DIRECTORY, SET_INFO and CHANGE_NOTIFY operations.
|
111
|
+
# @return [Integer]
|
112
|
+
define_field :max_trans_size, PacketGen::Types::Int32le
|
113
|
+
# @!attribute max_read_size
|
114
|
+
# 32-bit value indicating the maximum size of a READ request
|
115
|
+
# @return [Integer]
|
116
|
+
define_field :max_read_size, PacketGen::Types::Int32le
|
117
|
+
# @!attribute max_write_size
|
118
|
+
# 32-bit value indicating the maximum size of a WRITE request
|
119
|
+
# @return [Integer]
|
120
|
+
define_field :max_write_size, PacketGen::Types::Int32le
|
121
|
+
# @!attribute system_time
|
122
|
+
# System time of the SMB2 server
|
123
|
+
# @return [SMB::Filetime]
|
124
|
+
define_field :system_time, SMB::Filetime
|
125
|
+
# @!attribute start_time
|
126
|
+
# Start time of the SMB2 server
|
127
|
+
# @return [SMB::Filetime]
|
128
|
+
define_field :start_time, SMB::Filetime
|
129
|
+
# @!attribute buffer_offset
|
130
|
+
# The offset, from the beginning of the SMB2 header of the {#buffer}.
|
131
|
+
# @return [Integer]
|
132
|
+
define_field :buffer_offset, PacketGen::Types::Int16le
|
133
|
+
# @!attribute buffer_length
|
134
|
+
# The length of the {#buffer} field.
|
135
|
+
# @return [Integer]
|
136
|
+
define_field :buffer_length, PacketGen::Types::Int16le
|
137
|
+
# @!attribute context_offset
|
138
|
+
# Only for SMB3 dialect.
|
139
|
+
# @return [Integer]
|
140
|
+
define_field :context_offset, PacketGen::Types::Int32le
|
141
|
+
# @!attribute buffer
|
142
|
+
# @return [GSSAPI]
|
143
|
+
define_field :buffer, GSSAPI, token: :init
|
144
|
+
# @!attribute pad
|
145
|
+
# Optional padding between the end of the {#buffer} field and the first negotiate
|
146
|
+
# context in {#context_list} so that the first negotiate context is 8-byte aligned.
|
147
|
+
# @return [String]
|
148
|
+
define_smb2_pad_field :pad
|
149
|
+
# @!attribute context_list
|
150
|
+
# If {#dialect} has the value 0x0311, then this field must contain an array
|
151
|
+
# of {Context}
|
152
|
+
# @return [ArrayOfContext]
|
153
|
+
define_field :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
|
154
|
+
|
155
|
+
# @return [String]
|
156
|
+
def inspect
|
157
|
+
super do |attr|
|
158
|
+
next unless attr == :capabilities
|
159
|
+
value = bits_on(attr).reject { |_, v| v > 1 }
|
160
|
+
.keys
|
161
|
+
.select { |b| send("#{b}?") }
|
162
|
+
.map(&:to_s)
|
163
|
+
.join(',')
|
164
|
+
.gsub!(/cap_/, '')
|
165
|
+
value = '%-16s (0x%08x)' % [value, self[attr].to_i]
|
166
|
+
str = PacketGen::Inspect.shift_level
|
167
|
+
str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
|
168
|
+
attr, value]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Calculate and set {#context_offset}, {#buffer_offset} and {#buffer_length} fields.
|
173
|
+
# Also calculate lengths in {Context contexts}.
|
174
|
+
# @return [void]
|
175
|
+
def calc_length
|
176
|
+
self.context_offset = SMB2.new.sz + offset_of(:context_list)
|
177
|
+
self.buffer_offset = SMB2.new.sz + offset_of(:buffer)
|
178
|
+
self.buffer_length = buffer.sz
|
179
|
+
context_list.each { |ctx| ctx.calc_length if ctx.respond_to? :calc_length }
|
180
|
+
end
|
181
|
+
|
182
|
+
# Protocol name
|
183
|
+
# @return [String]
|
184
|
+
def protocol_name
|
185
|
+
'SMB2::Negotiate::Response'
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|