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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/packetgen-plugin-smb.rb +7 -5
  3. data/lib/packetgen/plugin/gssapi.rb +125 -0
  4. data/lib/packetgen/plugin/smb.rb +26 -32
  5. data/lib/packetgen/plugin/smb/blocks.rb +2 -2
  6. data/lib/packetgen/plugin/smb/browser.rb +3 -3
  7. data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +3 -3
  8. data/lib/packetgen/plugin/smb/browser/host_announcement.rb +4 -4
  9. data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +3 -3
  10. data/lib/packetgen/plugin/smb/close.rb +9 -59
  11. data/lib/packetgen/plugin/smb/close/request.rb +45 -0
  12. data/lib/packetgen/plugin/smb/close/response.rb +36 -0
  13. data/lib/packetgen/plugin/smb/filetime.rb +10 -9
  14. data/lib/packetgen/plugin/smb/nt_create_and_x.rb +9 -264
  15. data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +159 -0
  16. data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +128 -0
  17. data/lib/packetgen/plugin/smb/string.rb +4 -4
  18. data/lib/packetgen/plugin/smb/trans.rb +9 -190
  19. data/lib/packetgen/plugin/smb/trans/request.rb +121 -0
  20. data/lib/packetgen/plugin/smb/trans/response.rb +94 -0
  21. data/lib/packetgen/plugin/smb2.rb +181 -0
  22. data/lib/packetgen/plugin/smb2/base.rb +31 -0
  23. data/lib/packetgen/plugin/smb2/error.rb +50 -0
  24. data/lib/packetgen/plugin/smb2/guid.rb +68 -0
  25. data/lib/packetgen/plugin/smb2/negotiate.rb +22 -0
  26. data/lib/packetgen/plugin/smb2/negotiate/context.rb +131 -0
  27. data/lib/packetgen/plugin/smb2/negotiate/request.rb +166 -0
  28. data/lib/packetgen/plugin/smb2/negotiate/response.rb +190 -0
  29. data/lib/packetgen/plugin/smb2/session_setup.rb +21 -0
  30. data/lib/packetgen/plugin/smb2/session_setup/request.rb +98 -0
  31. data/lib/packetgen/plugin/smb2/session_setup/response.rb +69 -0
  32. data/lib/packetgen/plugin/smb_version.rb +1 -1
  33. data/packetgen-plugin-smb.gemspec +2 -1
  34. 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