packetgen-plugin-smb 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|