packetgen-plugin-smb 0.5.0 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/specs.yml +28 -0
  3. data/.rubocop.yml +26 -2
  4. data/Gemfile +15 -0
  5. data/README.md +51 -12
  6. data/Rakefile +10 -4
  7. data/examples/llmnr-responder +110 -0
  8. data/examples/smb-responder +233 -0
  9. data/lib/packetgen/plugin/gssapi.rb +16 -10
  10. data/lib/packetgen/plugin/llmnr.rb +4 -4
  11. data/lib/packetgen/plugin/netbios/datagram.rb +3 -3
  12. data/lib/packetgen/plugin/netbios/name.rb +4 -4
  13. data/lib/packetgen/plugin/netbios/session.rb +5 -5
  14. data/lib/packetgen/plugin/netbios.rb +2 -0
  15. data/lib/packetgen/plugin/ntlm/authenticate.rb +197 -0
  16. data/lib/packetgen/plugin/ntlm/av_pair.rb +115 -0
  17. data/lib/packetgen/plugin/ntlm/challenge.rb +140 -0
  18. data/lib/packetgen/plugin/ntlm/negotiate.rb +127 -0
  19. data/lib/packetgen/plugin/ntlm/ntlmv2_response.rb +59 -0
  20. data/lib/packetgen/plugin/ntlm.rb +211 -0
  21. data/lib/packetgen/plugin/smb/blocks.rb +2 -2
  22. data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +2 -2
  23. data/lib/packetgen/plugin/smb/browser/host_announcement.rb +2 -2
  24. data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +2 -2
  25. data/lib/packetgen/plugin/smb/browser.rb +2 -2
  26. data/lib/packetgen/plugin/smb/close/request.rb +2 -2
  27. data/lib/packetgen/plugin/smb/close/response.rb +2 -2
  28. data/lib/packetgen/plugin/smb/close.rb +2 -2
  29. data/lib/packetgen/plugin/smb/filetime.rb +10 -2
  30. data/lib/packetgen/plugin/smb/negotiate/dialect.rb +7 -0
  31. data/lib/packetgen/plugin/smb/negotiate/request.rb +7 -0
  32. data/lib/packetgen/plugin/smb/negotiate/response.rb +9 -3
  33. data/lib/packetgen/plugin/smb/negotiate.rb +2 -2
  34. data/lib/packetgen/plugin/smb/nt_create_and_x.rb +2 -2
  35. data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +4 -4
  36. data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +2 -2
  37. data/lib/packetgen/plugin/smb/string.rb +60 -23
  38. data/lib/packetgen/plugin/smb/trans/request.rb +3 -3
  39. data/lib/packetgen/plugin/smb/trans/response.rb +2 -2
  40. data/lib/packetgen/plugin/smb/trans.rb +2 -2
  41. data/lib/packetgen/plugin/smb.rb +12 -12
  42. data/lib/packetgen/plugin/smb2/base.rb +3 -3
  43. data/lib/packetgen/plugin/smb2/error.rb +3 -4
  44. data/lib/packetgen/plugin/smb2/guid.rb +4 -3
  45. data/lib/packetgen/plugin/smb2/negotiate/context.rb +3 -3
  46. data/lib/packetgen/plugin/smb2/negotiate/request.rb +3 -5
  47. data/lib/packetgen/plugin/smb2/negotiate/response.rb +9 -7
  48. data/lib/packetgen/plugin/smb2/negotiate.rb +2 -2
  49. data/lib/packetgen/plugin/smb2/session_setup/request.rb +9 -5
  50. data/lib/packetgen/plugin/smb2/session_setup/response.rb +10 -6
  51. data/lib/packetgen/plugin/smb2/session_setup.rb +2 -2
  52. data/lib/packetgen/plugin/smb2.rb +3 -3
  53. data/lib/packetgen/plugin/smb_version.rb +3 -1
  54. data/lib/packetgen-plugin-smb.rb +3 -2
  55. data/packetgen-plugin-smb.gemspec +8 -10
  56. metadata +21 -84
  57. data/.travis.yml +0 -12
@@ -0,0 +1,211 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of packetgen-plugin-smb.
4
+ # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
5
+ # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
6
+ # This program is published under MIT license.
7
+
8
+ module PacketGen::Plugin
9
+ # Base class for NTLM authentication protocol.
10
+ # @author Sylvain Daubert
11
+ class NTLM < PacketGen::Types::Fields
12
+ # NTLM message types
13
+ TYPES = {
14
+ 'negotiate' => 1,
15
+ 'challenge' => 2,
16
+ 'authenticate' => 3
17
+ }.freeze
18
+
19
+ # NTLM signature
20
+ SIGNATURE = "NTLMSSP\0"
21
+
22
+ # void version
23
+ VOID_VERSION = [0].pack('q').freeze
24
+ VOID_CHALLENGE = VOID_VERSION
25
+
26
+ # @!attribute signature
27
+ # 8-byte NTLM signature
28
+ # @return [String]
29
+ define_field :signature, PacketGen::Types::String, static_length: 8, default: SIGNATURE
30
+ # @!attribute type
31
+ # 4-byte message type
32
+ # @return [Integer]
33
+ define_field :type, PacketGen::Types::Int32leEnum, enum: TYPES
34
+ # @!attribute payload
35
+ # @return [String]
36
+ define_field :payload, PacketGen::Types::String
37
+
38
+ class <<self
39
+ # @api private
40
+ # Return fields defined in payload one.
41
+ # @return [Hash]
42
+ attr_accessor :payload_fields
43
+
44
+ # Create a NTLM object from a binary string
45
+ # @param [String] str
46
+ # @return [NTLM]
47
+ def read(str)
48
+ ntlm = self.new.read(str)
49
+ type = TYPES.key(ntlm.type)
50
+ return ntlm if type.nil?
51
+
52
+ klass = NTLM.const_get(type.capitalize)
53
+ klass.new.read(str)
54
+ end
55
+
56
+ # Define a flags field.
57
+ # @return [void]
58
+ def define_negotiate_flags
59
+ define_field_before :payload, :flags, PacketGen::Types::Int32le
60
+ define_bit_fields_on :flags, :flags_w, :flags_v, :flags_u, :flags_r13, 3,
61
+ :flags_t, :flags_r4, :flags_s, :flags_r,
62
+ :flags_r5, :flags_q, :flags_p, :flags_r6,
63
+ :flags_o, :flags_n, :flags_m, :flags_r7,
64
+ :flags_l, :flags_k, :flags_j, :flags_r8,
65
+ :flags_h, :flags_r9, :flags_g, :flags_f,
66
+ :flags_e, :flags_d, :flags_r10, :flags_c,
67
+ :flags_b, :flags_a
68
+ alias_method :nego56?, :flags_w?
69
+ alias_method :key_exch?, :flags_v?
70
+ alias_method :nego128?, :flags_u?
71
+ alias_method :version?, :flags_t?
72
+ alias_method :target_info?, :flags_s?
73
+ alias_method :non_nt_session_key?, :flags_r?
74
+ alias_method :identify?, :flags_q?
75
+ alias_method :ext_session_security?, :flags_p?
76
+ alias_method :target_type_server?, :flags_o?
77
+ alias_method :target_type_domain?, :flags_n?
78
+ alias_method :always_sign?, :flags_m?
79
+ alias_method :oem_workstation_supplied?, :flags_l?
80
+ alias_method :oem_domain_supplied?, :flags_k?
81
+ alias_method :anonymous?, :flags_j?
82
+ alias_method :ntlm?, :flags_h?
83
+ alias_method :lm_key?, :flags_g?
84
+ alias_method :datagram?, :flags_f?
85
+ alias_method :seal?, :flags_e?
86
+ alias_method :sign?, :flags_d?
87
+ alias_method :request_target?, :flags_c?
88
+ alias_method :oem?, :flags_b?
89
+ alias_method :unicode?, :flags_a?
90
+ alias_method :old_flags_a=, :flags_a=
91
+ alias_method :old_flags=, :flags=
92
+
93
+ class_eval do
94
+ def flags_a=(value)
95
+ self.old_flags_a = value
96
+ self.class.payload_fields.each do |name, _|
97
+ attr = send(name)
98
+ attr.unicode = value if attr.respond_to?(:unicode=)
99
+ end
100
+
101
+ value
102
+ end
103
+
104
+ def flags=(value)
105
+ self.old_flags = value
106
+ self.flags_a = value & 1
107
+ end
108
+ end
109
+ end
110
+
111
+ # Define a field in payload. Also add +name_len+, +name_maxlen+ and
112
+ # +name_offset+ fields.
113
+ # @param [Symbol] name name of field.
114
+ # @param [Class,nil] type type of +name+ field.
115
+ # @param [Hash] options type's options needed at build time
116
+ # @return [void]
117
+ def define_in_payload(name, type=SMB::String, options={})
118
+ @payload_fields ||= {}
119
+ @payload_fields[name] = [type, options]
120
+
121
+ define_field_before :payload, :"#{name}_len", PacketGen::Types::Int16le
122
+ define_field_before :payload, :"#{name}_maxlen", PacketGen::Types::Int16le
123
+ define_field_before :payload, :"#{name}_offset", PacketGen::Types::Int32le
124
+
125
+ attr_accessor name
126
+ end
127
+ end
128
+
129
+ # @abstract This method is meaningful for {NTLM} subclasses only.
130
+ def initialize(options={})
131
+ super
132
+ return if self.class.payload_fields.nil?
133
+
134
+ self.class.payload_fields.each do |name, type_and_opt|
135
+ type, options = type_and_opt
136
+ content = if type.new.respond_to?(:unicode?)
137
+ type.new(options.merge(unicode: unicode?))
138
+ else
139
+ type.new(options)
140
+ end
141
+ send(:"#{name}=", content)
142
+ end
143
+ end
144
+
145
+ # @abstract This class is meaningful for {NTLM} subclasses only.
146
+ # Populate object from a binary string
147
+ # @param [String] str
148
+ # @return [self]
149
+ def read(str)
150
+ super
151
+ return self if self.class.payload_fields.nil?
152
+
153
+ self.class.payload_fields.each do |name, type_and_opt|
154
+ type, options = type_and_opt
155
+ offset_in_payload = send(:"#{name}_offset") - offset_of(:payload)
156
+ length = send(:"#{name}_len")
157
+ content = if type.new.respond_to?(:unicode?)
158
+ type.new(options.merge(unicode: unicode?))
159
+ else
160
+ type.new(options)
161
+ end
162
+ content.read(payload[offset_in_payload, length]) if length.positive?
163
+ send(:"#{name}=", content)
164
+ end
165
+
166
+ self
167
+ end
168
+
169
+ # @abstract This class is meaningful for {NTLM} subclasses only.
170
+ # Calculate and set +len+, +maxlen+ and +offset+ fields defined for
171
+ # fields in {#payload}.
172
+ # @return [void]
173
+ def calc_length
174
+ return self if self.class.payload_fields.nil?
175
+
176
+ previous_len = 0
177
+ self.class.payload_fields.each do |name, _type_and_opt|
178
+ send(:"#{name}_len=", 0)
179
+ send(:"#{name}_offset=", offset_of(:payload) + previous_len)
180
+
181
+ field = send(name)
182
+ next unless field && !field.empty?
183
+
184
+ length = field.respond_to?(:sz) ? field.sz : field.size
185
+ send(:"#{name}_len=", length)
186
+ send(:"#{name}_maxlen=", length)
187
+ previous_len = length
188
+ end
189
+ end
190
+
191
+ # @abstract This class is meaningful for {NTLM} subclasses only.
192
+ # @return [String]
193
+ def to_s
194
+ s = super
195
+ return s if self.class.payload_fields.nil?
196
+
197
+ self.class.payload_fields.each do |name, _type_and_opt|
198
+ attr = send(name)
199
+ attr.unicode = unicode? if attr.respond_to?(:unicode=)
200
+ s << attr.to_s unless attr.nil? || send("#{name}_len").zero?
201
+ end
202
+ s
203
+ end
204
+ end
205
+ end
206
+
207
+ require_relative 'ntlm/av_pair'
208
+ require_relative 'ntlm/ntlmv2_response'
209
+ require_relative 'ntlm/negotiate'
210
+ require_relative 'ntlm/challenge'
211
+ require_relative 'ntlm/authenticate'
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Common blocks used for unsupported SMB messages.
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  class Browser
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  class Browser
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  class Browser
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Browser Trans sub-protocol.
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  module Close
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  module Close
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Namespace for CLOSE related classes
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # SMB FILETIME.
11
11
  # @author Sylvain Daubert
12
12
  class Filetime
13
+ include PacketGen::Types::Fieldable
14
+
13
15
  # Base time for SMB FILETIME.
14
16
  # This value also indicate no time.
15
17
  NO_TIME = Time.utc(1601).freeze
@@ -22,6 +24,12 @@ module PacketGen::Plugin
22
24
  # String to parse time
23
25
  PARSE_TIME_STR = '%Y-%m-%d %H:%M:%S.%N %Z'
24
26
 
27
+ # Return a new Filetime object initialized to current time.
28
+ # @return [Filetime]
29
+ def self.now
30
+ new(time: Time.now.utc)
31
+ end
32
+
25
33
  # @param [Hash] options
26
34
  # @option options [Integer] :filetime
27
35
  # @option options [Time] :time
@@ -1,3 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of packetgen-plugin-smb.
4
+ # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
5
+ # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
6
+ # This program is published under MIT license.
7
+
1
8
  module PacketGen::Plugin
2
9
  class SMB
3
10
  module Negotiate
@@ -1,3 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of packetgen-plugin-smb.
4
+ # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
5
+ # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
6
+ # This program is published under MIT license.
7
+
1
8
  module PacketGen::Plugin
2
9
  class SMB
3
10
  module Negotiate
@@ -1,13 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of packetgen-plugin-smb.
4
+ # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
5
+ # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
6
+ # This program is published under MIT license.
7
+
1
8
  module PacketGen::Plugin
2
9
  class SMB
3
10
  module Negotiate
4
11
  # SMB Negotiation Response header.
5
12
  #
6
- # See also {Blocks}, as {Negotiate::Rersponse} is a specialization of {Blocks#words}
13
+ # See also {Blocks}, as {Negotiate::Response} is a specialization of {Blocks#words}
7
14
  # and {Blocks#bytes}.
8
15
  # @author Sylvain Daubert
9
16
  class Response < Blocks
10
-
11
17
  # Get index of the dialect selected by the server from the list presented in the request.
12
18
  # @return [Integer]
13
19
  def dialect_index
@@ -20,4 +26,4 @@ module PacketGen::Plugin
20
26
  end
21
27
  end
22
28
  end
23
- end
29
+ end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Namespace for NEGOTIATE related classes
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Namespace for NT_CREATE_ANDX related classes
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Namespace for NT_CREATE_ANDX related classes
@@ -128,7 +128,7 @@ module PacketGen::Plugin
128
128
  # Padding before {#filename} to align it on 16-bit boundary. Only present
129
129
  # if {SMB#flags2_unicode?} is +true+.
130
130
  # @return [Integer]
131
- define_field :pad1, PacketGen::Types::Int8, optional: ->(h) { h.packet && h.packet.smb.flags2_unicode? }
131
+ define_field :pad1, PacketGen::Types::Int8, optional: ->(h) { h&.packet&.smb&.flags2_unicode? }
132
132
  # @!attribute filename
133
133
  # A string that represents the fully qualified name of the file
134
134
  # relative to the supplied TID
@@ -154,6 +154,6 @@ module PacketGen::Plugin
154
154
  self.byte_count = bcount
155
155
  end
156
156
  end
157
- end
157
+ end
158
158
  end
159
159
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Namespace for NT_CREATE_ANDX related classes
@@ -1,28 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
8
+ require 'forwardable'
7
9
 
8
10
  module PacketGen::Plugin
9
11
  class SMB
10
- # SMB strings (UTF-16 little-endian).
12
+ # SMB strings (UTF-16 little-endian or OEM).
11
13
  # @author Sylvain Daubert
12
- class String < PacketGen::Types::CString
13
- # @param [Boolean] value
14
+ class String
15
+ extend Forwardable
16
+ include PacketGen::Types::Fieldable
17
+
18
+ def_delegators :@string, :[], :length, :size, :inspect, :==, :<<,
19
+ :unpack, :force_encoding, :encoding, :index, :empty?,
20
+ :encode
21
+
22
+ # @return [::String]
23
+ attr_reader :string
24
+ # @param [Boolean] null_terminated
14
25
  # @return [Boolean]
15
- attr_writer :unicode
26
+ attr_writer :null_terminated
16
27
 
17
28
  # @param [Hash] options
18
- # @option options [Integer] :static_length set a static length for this string
19
29
  # @option options [Boolean] :unicode If +true+, string is encoded as a UTF-16
20
30
  # unicode string. If +false+, string is encode in ASCII. Defaults to +true+.
31
+ # @option options [Boolean] :null_terminated If +true+, string is null-terminated.
32
+ # If +false+, string is not null-terminated. Defaults to +true+.
21
33
  def initialize(options={})
22
- super
23
34
  @unicode = options.key?(:unicode) ? options[:unicode] : true
24
- self.encode!('UTF-16LE') if @unicode
25
- self.encode!('ASCII-8BIT') unless @unicode
35
+ @null_terminated = options.key?(:null_terminated) ? options[:null_terminated] : true
36
+ @string = +''.encode(self_encoding)
26
37
  end
27
38
 
28
39
  # @return [Boolean]
@@ -30,6 +41,19 @@ module PacketGen::Plugin
30
41
  @unicode
31
42
  end
32
43
 
44
+ # @param [Boolean] bool
45
+ # @return [Boolean]
46
+ def unicode=(bool)
47
+ @unicode = bool
48
+ @string.force_encoding(self_encoding)
49
+ bool
50
+ end
51
+
52
+ # @return [Boolean]
53
+ def null_terminated?
54
+ @null_terminated
55
+ end
56
+
33
57
  # @param [::String] str
34
58
  # @return [String] self
35
59
  def read(str)
@@ -37,34 +61,47 @@ module PacketGen::Plugin
37
61
 
38
62
  str2 = case str.encoding
39
63
  when Encoding::BINARY
40
- binidx = nil
41
- 0.step(to: str.size, by: 2) do |i|
42
- binidx = i if str[i, 2] == binary_terminator
43
- end
44
- s = if binidx.nil?
45
- str
46
- else
47
- str[0, binidx]
48
- end
49
- s.force_encoding(self_encoding)
64
+ str.dup.force_encoding(self_encoding)
50
65
  else
51
66
  str.encode(self_encoding)
52
67
  end
53
- str2 = str2[0, @static_length / 2] if @static_length.is_a? Integer
54
68
  idx = str2.index(+"\x00".encode(self_encoding))
55
69
  str2 = str2[0, idx] unless idx.nil?
56
- self.replace str2
70
+ @string = str2
57
71
  self
58
72
  end
59
73
 
74
+ # @return [String]
75
+ def to_s
76
+ str = string.dup.force_encoding('BINARY')
77
+ return str unless null_terminated?
78
+
79
+ str << binary_terminator.force_encoding('BINARY')
80
+ end
81
+
82
+ # Populate String from a human readable (ie UTF-8) string
83
+ # @param [String] str
84
+ # @return [self]
85
+ def from_human(str)
86
+ return self if str.nil?
87
+
88
+ @string = str.encode(self_encoding)
89
+ self
90
+ end
91
+
92
+ # @return [String]
93
+ def to_human
94
+ string.encode('UTF-8')
95
+ end
96
+
60
97
  private
61
98
 
62
99
  def self_encoding
63
- @unicode ? Encoding::UTF_16LE : Encoding:: ASCII_8BIT
100
+ @unicode ? Encoding::UTF_16LE : Encoding::ASCII_8BIT
64
101
  end
65
102
 
66
103
  def binary_terminator
67
- @unicode ? "\x00\x00" : "\x00"
104
+ [0].pack('C').encode(self_encoding)
68
105
  end
69
106
  end
70
107
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  module Trans
@@ -96,7 +96,7 @@ module PacketGen::Plugin
96
96
  # 8-bit optional padding to align {#name} on a 2-byte boundary. Only present
97
97
  # if {SMB#flags2_unicode?} is +true+.
98
98
  # @return [Integer]
99
- define_field :padname, PacketGen::Types::Int8, optional: ->(h) { h.packet && h.packet.smb.flags2_unicode? }
99
+ define_field :padname, PacketGen::Types::Int8, optional: ->(h) { h&.packet&.smb&.flags2_unicode? }
100
100
  # @!attribute name
101
101
  # Pathname of the mailslot or named pipe.
102
102
  # @return [String]
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  module Trans
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of packetgen-plugin-smb.
2
4
  # See https://github.com/sdaubert/packetgen-plugin-smb for more informations
3
5
  # Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen::Plugin
9
9
  class SMB
10
10
  # Namespace for TRANS related classes