ruby_smb 2.0.9 → 2.0.13

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 (228) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +5 -15
  4. data/examples/auth_capture.rb +71 -0
  5. data/examples/dump_secrets_from_sid.rb +207 -0
  6. data/examples/enum_domain_users.rb +75 -0
  7. data/examples/get_computer_info.rb +42 -0
  8. data/examples/query_service_status.rb +42 -4
  9. data/lib/ruby_smb/client/negotiation.rb +1 -1
  10. data/lib/ruby_smb/client.rb +10 -20
  11. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  12. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  13. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  14. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  15. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  16. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  17. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  18. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  19. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  20. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  21. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  22. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  23. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  24. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  25. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  26. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  27. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  28. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  29. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  30. data/lib/ruby_smb/dcerpc/error.rb +17 -0
  31. data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
  32. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
  33. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
  34. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
  35. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
  36. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
  37. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
  38. data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
  39. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  40. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  41. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  42. data/lib/ruby_smb/dcerpc/request.rb +79 -32
  43. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  44. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  45. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
  46. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  47. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  48. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  49. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  50. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  51. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  52. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  53. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  54. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  55. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  56. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  57. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  58. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  59. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  60. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  61. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  62. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  63. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  64. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  65. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  66. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  67. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  68. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  69. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  70. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
  71. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
  72. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
  73. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
  74. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
  75. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
  76. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
  77. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
  78. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
  79. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
  80. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
  81. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
  82. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
  83. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
  84. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
  85. data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
  86. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  87. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  88. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
  89. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
  90. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
  91. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  92. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  93. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  94. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  95. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  96. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
  97. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  98. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  99. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
  100. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  101. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  102. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
  103. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
  104. data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
  105. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  106. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  107. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  108. data/lib/ruby_smb/dcerpc.rb +41 -11
  109. data/lib/ruby_smb/dialect.rb +45 -0
  110. data/lib/ruby_smb/dispatcher/base.rb +1 -1
  111. data/lib/ruby_smb/field/file_time.rb +1 -1
  112. data/lib/ruby_smb/field/string16.rb +5 -1
  113. data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
  114. data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
  115. data/lib/ruby_smb/gss/provider.rb +35 -0
  116. data/lib/ruby_smb/gss.rb +56 -63
  117. data/lib/ruby_smb/ntlm.rb +61 -0
  118. data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
  119. data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
  120. data/lib/ruby_smb/server/server_client.rb +162 -0
  121. data/lib/ruby_smb/server.rb +54 -0
  122. data/lib/ruby_smb/signing.rb +59 -0
  123. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
  124. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
  125. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
  126. data/lib/ruby_smb/smb1/pipe.rb +4 -0
  127. data/lib/ruby_smb/smb1/tree.rb +1 -1
  128. data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
  129. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
  130. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
  131. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
  132. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
  133. data/lib/ruby_smb/smb2/pipe.rb +4 -0
  134. data/lib/ruby_smb/smb2/tree.rb +1 -1
  135. data/lib/ruby_smb/smb2.rb +3 -1
  136. data/lib/ruby_smb/version.rb +1 -1
  137. data/lib/ruby_smb.rb +2 -1
  138. data/spec/lib/ruby_smb/client_spec.rb +8 -11
  139. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  140. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  141. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  142. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  143. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
  144. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
  145. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
  146. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
  147. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
  148. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  149. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  150. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  151. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  152. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  153. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
  154. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  155. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  156. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  157. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  158. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  159. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  160. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  161. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  162. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  163. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  164. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  165. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  166. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  167. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  168. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  169. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  170. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  171. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  172. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
  173. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
  174. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
  175. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
  176. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
  177. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
  178. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
  179. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
  180. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
  181. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
  182. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
  183. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
  184. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
  185. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
  186. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
  187. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
  188. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  189. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  190. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
  191. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
  192. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
  193. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  194. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  195. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  196. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  197. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  198. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
  199. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  200. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  201. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  202. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
  203. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  204. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
  205. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
  206. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
  207. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  208. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  209. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  210. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  211. data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
  212. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
  213. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
  214. data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
  215. data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
  216. data/spec/lib/ruby_smb/server_spec.rb +32 -0
  217. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
  218. data/spec/lib/ruby_smb/smb1/tree_spec.rb +4 -4
  219. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
  220. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
  221. data/spec/lib/ruby_smb/smb2/tree_spec.rb +5 -5
  222. data/spec/support/bin_helper.rb +9 -0
  223. data.tar.gz.sig +2 -1
  224. metadata +119 -6
  225. metadata.gz.sig +0 -0
  226. data/lib/ruby_smb/client/signing.rb +0 -64
  227. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
  228. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
@@ -11,26 +11,16 @@ module RubySMB
11
11
  endian :little
12
12
 
13
13
  logonsrv_handle :primary_name
14
- string :pad1, length: -> { pad_length(self.primary_name) }
15
- ndr_string :account_name
14
+ ndr_conf_var_wide_stringz :account_name
16
15
  netlogon_secure_channel_type :secure_channel_type
17
- string :pad2, length: -> { pad_length(self.secure_channel_type) }
18
- ndr_string :computer_name
16
+ ndr_conf_var_wide_stringz :computer_name
19
17
  netlogon_credential :client_credential
20
- string :pad3, length: -> { pad_length(self.client_credential) }
21
- uint32 :flags
18
+ ndr_uint32 :flags
22
19
 
23
20
  def initialize_instance
24
21
  super
25
22
  @opnum = NETR_SERVER_AUTHENTICATE3
26
23
  end
27
-
28
- # Determines the correct length for the padding, so that the next
29
- # field is 4-byte aligned.
30
- def pad_length(prev_element)
31
- offset = (prev_element.abs_offset + prev_element.to_binary_s.length) % 4
32
- (4 - offset) % 4
33
- end
34
24
  end
35
25
  end
36
26
  end
@@ -11,9 +11,9 @@ module RubySMB
11
11
  endian :little
12
12
 
13
13
  netlogon_credential :server_credential
14
- uint32 :negotiate_flags
15
- uint32 :account_rid
16
- uint32 :error_status
14
+ ndr_uint32 :negotiate_flags
15
+ ndr_uint32 :account_rid
16
+ ndr_uint32 :error_status
17
17
 
18
18
  def initialize_instance
19
19
  super
@@ -11,26 +11,16 @@ module RubySMB
11
11
  endian :little
12
12
 
13
13
  logonsrv_handle :primary_name
14
- string :pad1, length: -> { pad_length(self.primary_name) }
15
- ndr_string :account_name
14
+ ndr_conf_var_wide_stringz :account_name
16
15
  netlogon_secure_channel_type :secure_channel_type
17
- string :pad2, length: -> { pad_length(self.secure_channel_type) }
18
- ndr_string :computer_name
19
- string :pad3, length: -> { pad_length(self.computer_name) }
16
+ ndr_conf_var_wide_stringz :computer_name
20
17
  netlogon_authenticator :authenticator
21
- ndr_fixed_byte_array :clear_new_password, length: 516 # this is an encrypted NL_TRUST_PASSWORD
18
+ ndr_fixed_byte_array :clear_new_password, initial_length: 516 # this is an encrypted NL_TRUST_PASSWORD
22
19
 
23
20
  def initialize_instance
24
21
  super
25
22
  @opnum = Netlogon::NETR_SERVER_PASSWORD_SET2
26
23
  end
27
-
28
- # Determines the correct length for the padding, so that the next
29
- # field is 4-byte aligned.
30
- def pad_length(prev_element)
31
- offset = (prev_element.abs_offset + prev_element.to_binary_s.length) % 4
32
- (4 - offset) % 4
33
- end
34
24
  end
35
25
  end
36
26
  end
@@ -11,7 +11,7 @@ module RubySMB
11
11
  endian :little
12
12
 
13
13
  netlogon_authenticator :return_authenticator
14
- uint32 :error_status
14
+ ndr_uint32 :error_status
15
15
 
16
16
  def initialize_instance
17
17
  super
@@ -10,22 +10,14 @@ module RubySMB
10
10
 
11
11
  endian :little
12
12
 
13
- logonsrv_handle :primary_name
14
- string :pad1, length: -> { pad_length(self.primary_name) }
15
- ndr_string :computer_name
16
- netlogon_credential :client_challenge
13
+ logonsrv_handle :primary_name
14
+ ndr_conf_var_wide_stringz :computer_name
15
+ netlogon_credential :client_challenge
17
16
 
18
17
  def initialize_instance
19
18
  super
20
19
  @opnum = NETR_SERVER_REQ_CHALLENGE
21
20
  end
22
-
23
- # Determines the correct length for the padding, so that the next
24
- # field is 4-byte aligned.
25
- def pad_length(prev_element)
26
- offset = (prev_element.abs_offset + prev_element.to_binary_s.length) % 4
27
- (4 - offset) % 4
28
- end
29
21
  end
30
22
  end
31
23
  end
@@ -11,7 +11,7 @@ module RubySMB
11
11
  endian :little
12
12
 
13
13
  netlogon_credential :server_challenge
14
- uint32 :error_status
14
+ ndr_uint32 :error_status
15
15
 
16
16
  def initialize_instance
17
17
  super
@@ -13,19 +13,20 @@ module RubySMB
13
13
  NETR_SERVER_PASSWORD_SET2 = 30
14
14
 
15
15
  # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/3b224201-b531-43e2-8c79-b61f6dea8640
16
- class LogonsrvHandle < Ndr::NdrLpStr; end
16
+ class LogonsrvHandle < Ndr::NdrWideStringzPtr; end
17
17
 
18
18
  # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/d55e2632-7163-4f6c-b662-4b870e8cc1cd
19
19
  class NetlogonCredential < Ndr::NdrFixedByteArray
20
- default_parameters length: 8
20
+ default_parameters initial_length: 8
21
21
  end
22
22
 
23
23
  # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/76c93227-942a-4687-ab9d-9d972ffabdab
24
- class NetlogonAuthenticator < BinData::Record
24
+ class NetlogonAuthenticator < Ndr::NdrStruct
25
+ default_parameter byte_align: 4
25
26
  endian :little
26
27
 
27
28
  netlogon_credential :credential
28
- uint32 :timestamp
29
+ ndr_uint32 :timestamp
29
30
  end
30
31
 
31
32
  # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/4d1235e3-2c96-4e9f-a147-3cb338a0d09f
@@ -1,11 +1,12 @@
1
1
  module RubySMB
2
2
  module Dcerpc
3
- class PSyntaxIdT < BinData::Record
3
+ class PSyntaxIdT < Ndr::NdrStruct
4
+ default_parameter byte_align: 4
4
5
  endian :little
5
6
 
6
7
  uuid :if_uuid, initial_value: -> { uuid }
7
- uint16 :if_ver_major, initial_value: -> { ver_major }
8
- uint16 :if_ver_minor, initial_value: -> { ver_minor }
8
+ ndr_uint16 :if_ver_major, initial_value: -> { ver_major }
9
+ ndr_uint16 :if_ver_minor, initial_value: -> { ver_minor }
9
10
  end
10
11
  end
11
12
  end
@@ -10,14 +10,14 @@ module RubySMB
10
10
  uint8 :ptype, label: 'PDU type'
11
11
 
12
12
  struct :pfc_flags do
13
- bit1 :object_uuid, label: 'Object UUID'
14
- bit1 :maybe, label: 'Maybe call semantics'
13
+ bit1 :object_uuid, label: 'Object UUID'
14
+ bit1 :maybe, label: 'Maybe call semantics'
15
15
  bit1 :did_not_execute, label: 'Did not execute'
16
- bit1 :conc_mpx, label: 'Concurrent multiplexing'
17
- bit1 :reserved_1, label: 'Reserved'
18
- bit1 :pending_cancel, label: 'Pending cancel'
19
- bit1 :last_frag, label: 'Last fragment', initial_value: 1
20
- bit1 :first_frag, label: 'First fragment', initial_value: 1
16
+ bit1 :conc_mpx, label: 'Concurrent multiplexing'
17
+ bit1 :reserved_1, label: 'Reserved'
18
+ bit1 :support_header_sign, label: 'Support Header Signing'
19
+ bit1 :last_frag, label: 'Last fragment', initial_value: 1
20
+ bit1 :first_frag, label: 'First fragment', initial_value: 1
21
21
  end
22
22
 
23
23
  uint32 :packed_drep, label: 'NDR data representation format label', initial_value: 0x10
@@ -17,6 +17,7 @@ module RubySMB
17
17
  BIND_NAK = 13
18
18
  ALTER_CONTEXT = 14
19
19
  ALTER_CONTEXT_RESP = 15
20
+ RPC_AUTH3 = 16
20
21
  SHUTDOWN = 17
21
22
  CO_CANCEL = 18
22
23
  ORPHANED = 19
@@ -3,66 +3,113 @@ module RubySMB
3
3
  # The Request PDU as defined in
4
4
  # [The request PDU](http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_09)
5
5
  class Request < BinData::Record
6
+ PTYPE = PTypes::REQUEST
7
+
6
8
  endian :little
7
9
 
8
- pdu_header :pdu_header, label: 'PDU header'
10
+ # PDU Header
11
+ pdu_header :pdu_header, label: 'PDU header common fields'
9
12
  uint32 :alloc_hint, label: 'Allocation hint', initial_value: -> { stub.num_bytes }
10
13
  uint16 :p_cont_id, label: 'Presentation context identification'
11
14
  uint16 :opnum, label: 'Operation Number'
12
15
  uuid :object, label: 'Object UID', onlyif: -> { pdu_header.pfc_flags.object_uuid == 1 }
13
16
 
17
+ # PDU Body
14
18
  choice :stub, label: 'Stub', selection: -> { @obj.parent.get_parameter(:endpoint) || '' } do
19
+ string 'Encrypted'
15
20
  choice 'Winreg', selection: -> { opnum } do
16
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCR, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCR
17
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCU, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCU
18
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKLM, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKLM
19
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPD, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPD
20
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKU, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKU
21
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCC, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCC
22
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPT, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPT
23
- open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPN, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPN
24
- close_key_request RubySMB::Dcerpc::Winreg::REG_CLOSE_KEY
25
- enum_key_request RubySMB::Dcerpc::Winreg::REG_ENUM_KEY
26
- enum_value_request RubySMB::Dcerpc::Winreg::REG_ENUM_VALUE
27
- open_key_request RubySMB::Dcerpc::Winreg::REG_OPEN_KEY
28
- query_info_key_request RubySMB::Dcerpc::Winreg::REG_QUERY_INFO_KEY
29
- query_value_request RubySMB::Dcerpc::Winreg::REG_QUERY_VALUE
30
- create_key_request RubySMB::Dcerpc::Winreg::REG_CREATE_KEY
31
- save_key_request RubySMB::Dcerpc::Winreg::REG_SAVE_KEY
21
+ open_root_key_request Winreg::OPEN_HKCR, opnum: Winreg::OPEN_HKCR
22
+ open_root_key_request Winreg::OPEN_HKCU, opnum: Winreg::OPEN_HKCU
23
+ open_root_key_request Winreg::OPEN_HKLM, opnum: Winreg::OPEN_HKLM
24
+ open_root_key_request Winreg::OPEN_HKPD, opnum: Winreg::OPEN_HKPD
25
+ open_root_key_request Winreg::OPEN_HKU, opnum: Winreg::OPEN_HKU
26
+ open_root_key_request Winreg::OPEN_HKCC, opnum: Winreg::OPEN_HKCC
27
+ open_root_key_request Winreg::OPEN_HKPT, opnum: Winreg::OPEN_HKPT
28
+ open_root_key_request Winreg::OPEN_HKPN, opnum: Winreg::OPEN_HKPN
29
+ close_key_request Winreg::REG_CLOSE_KEY
30
+ enum_key_request Winreg::REG_ENUM_KEY
31
+ enum_value_request Winreg::REG_ENUM_VALUE
32
+ open_key_request Winreg::REG_OPEN_KEY
33
+ query_info_key_request Winreg::REG_QUERY_INFO_KEY
34
+ query_value_request Winreg::REG_QUERY_VALUE
35
+ create_key_request Winreg::REG_CREATE_KEY
36
+ save_key_request Winreg::REG_SAVE_KEY
32
37
  string :default
33
38
  end
34
39
  choice 'Netlogon', selection: -> { opnum } do
35
- netr_server_authenticate3_request RubySMB::Dcerpc::Netlogon::NETR_SERVER_AUTHENTICATE3
36
- netr_server_password_set2_request RubySMB::Dcerpc::Netlogon::NETR_SERVER_PASSWORD_SET2
37
- netr_server_req_challenge_request RubySMB::Dcerpc::Netlogon::NETR_SERVER_REQ_CHALLENGE
40
+ netr_server_authenticate3_request Netlogon::NETR_SERVER_AUTHENTICATE3
41
+ netr_server_password_set2_request Netlogon::NETR_SERVER_PASSWORD_SET2
42
+ netr_server_req_challenge_request Netlogon::NETR_SERVER_REQ_CHALLENGE
38
43
  string :default
39
44
  end
40
45
  choice 'Srvsvc', selection: -> { opnum } do
41
- net_share_enum_all RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL, host: -> { host rescue '' }
46
+ net_share_enum_all_request Srvsvc::NET_SHARE_ENUM_ALL
42
47
  string :default
43
48
  end
44
49
  choice 'Svcctl', selection: -> { opnum } do
45
- open_sc_manager_w_request RubySMB::Dcerpc::Svcctl::OPEN_SC_MANAGER_W
46
- open_service_w_request RubySMB::Dcerpc::Svcctl::OPEN_SERVICE_W
47
- query_service_status_request RubySMB::Dcerpc::Svcctl::QUERY_SERVICE_STATUS
48
- query_service_config_w_request RubySMB::Dcerpc::Svcctl::QUERY_SERVICE_CONFIG_W
49
- change_service_config_w_request RubySMB::Dcerpc::Svcctl::CHANGE_SERVICE_CONFIG_W
50
- start_service_w_request RubySMB::Dcerpc::Svcctl::START_SERVICE_W
51
- control_service_request RubySMB::Dcerpc::Svcctl::CONTROL_SERVICE
52
- close_service_handle_request RubySMB::Dcerpc::Svcctl::CLOSE_SERVICE_HANDLE
50
+ open_sc_manager_w_request Svcctl::OPEN_SC_MANAGER_W
51
+ open_service_w_request Svcctl::OPEN_SERVICE_W
52
+ query_service_status_request Svcctl::QUERY_SERVICE_STATUS
53
+ query_service_config_w_request Svcctl::QUERY_SERVICE_CONFIG_W
54
+ change_service_config_w_request Svcctl::CHANGE_SERVICE_CONFIG_W
55
+ start_service_w_request Svcctl::START_SERVICE_W
56
+ control_service_request Svcctl::CONTROL_SERVICE
57
+ close_service_handle_request Svcctl::CLOSE_SERVICE_HANDLE
53
58
  string :default
54
59
  end
60
+ choice 'Samr', selection: -> { opnum } do
61
+ samr_connect_request Samr::SAMR_CONNECT
62
+ samr_lookup_domain_in_sam_server_request Samr::SAMR_LOOKUP_DOMAIN_IN_SAM_SERVER
63
+ samr_open_domain_request Samr::SAMR_OPEN_DOMAIN
64
+ samr_enumerate_users_in_domain_request Samr::SAMR_ENUMERATE_USERS_IN_DOMAIN
65
+ samr_rid_to_sid_request Samr::SAMR_RID_TO_SID
66
+ samr_close_handle_request Samr::SAMR_CLOSE_HANDLE
67
+ samr_get_alias_membership_request Samr::SAMR_GET_ALIAS_MEMBERSHIP
68
+ samr_open_user_request Samr::SAMR_OPEN_USER
69
+ samr_get_groups_for_user_request Samr::SAMR_GET_GROUPS_FOR_USER
70
+ string :default
71
+ end
72
+ choice 'Wkssvc', selection: -> { opnum } do
73
+ netr_wksta_get_info_request Wkssvc::NETR_WKSTA_GET_INFO
74
+ string :default
75
+ end
76
+ choice 'Epm', selection: -> { opnum } do
77
+ epm_ept_map_request RubySMB::Dcerpc::Epm::EPT_MAP
78
+ string :default
79
+ end
80
+ choice 'Drsr', selection: -> { opnum } do
81
+ drs_bind_request Drsr::DRS_BIND
82
+ drs_unbind_request Drsr::DRS_UNBIND
83
+ drs_domain_controller_info_request Drsr::DRS_DOMAIN_CONTROLLER_INFO
84
+ drs_crack_names_request Drsr::DRS_CRACK_NAMES
85
+ drs_get_nc_changes_request Drsr::DRS_GET_NC_CHANGES
86
+ string :default
87
+ end
55
88
  string :default
56
89
  end
90
+ string :auth_pad,
91
+ onlyif: -> { has_auth_verifier? },
92
+ length: -> { (16 - (stub.num_bytes % 16)) % 16 }
57
93
 
58
- string :auth_verifier, label: 'Authentication verifier',
59
- onlyif: -> { pdu_header.auth_length > 0 },
94
+ # Auth Verifier
95
+ sec_trailer :sec_trailer, onlyif: -> { has_auth_verifier? }
96
+ string :auth_value, label: 'Authentication verifier',
97
+ onlyif: -> { has_auth_verifier? },
60
98
  read_length: -> { pdu_header.auth_length }
61
99
 
62
100
  def initialize_instance
63
101
  super
64
- pdu_header.ptype = RubySMB::Dcerpc::PTypes::REQUEST
102
+ pdu_header.ptype = PTYPE
65
103
  end
104
+
105
+ def enable_encrypted_stub
106
+ @params[:endpoint] = 'Encrypted'
107
+ end
108
+
109
+ def has_auth_verifier?
110
+ self.pdu_header.auth_length > 0
111
+ end
112
+
66
113
  end
67
114
  end
68
115
  end
@@ -3,24 +3,59 @@ module RubySMB
3
3
  # The Response PDU as defined in
4
4
  # [The response PDU](http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_10)
5
5
  class Response < BinData::Record
6
- endian :little
6
+ PTYPE = PTypes::RESPONSE
7
7
 
8
- pdu_header :pdu_header, label: 'PDU header'
8
+ endian :little
9
9
 
10
- uint32 :alloc_hint, label: 'Allocation hint', initial_value: -> { stub.do_num_bytes }
11
- uint16 :p_cont_id, label: 'Presentation context identification'
12
- uint8 :cancel_count, label: 'Cancel count'
13
- uint8 :reserved
10
+ # PDU Header
11
+ pdu_header :pdu_header, label: 'PDU header common fields'
12
+ uint32 :alloc_hint, label: 'Allocation hint', initial_value: -> { stub.do_num_bytes }
13
+ uint16 :p_cont_id, label: 'Presentation context identification'
14
+ uint8 :cancel_count, label: 'Cancel count'
15
+ uint8 :reserved
14
16
 
15
- string :stub, label: 'Stub', read_length: -> { pdu_header.frag_length - stub.abs_offset - pdu_header.auth_length }
17
+ # PDU Body
18
+ string :stub, label: 'Stub', read_length: -> { stub_length }
19
+ string :auth_pad,
20
+ onlyif: -> { has_auth_verifier? },
21
+ length: -> { (16 - (stub.num_bytes % 16)) % 16 }
16
22
 
17
- string :auth_verifier, label: 'Authentication verifier',
18
- onlyif: -> { pdu_header.auth_length > 0 },
23
+ # Auth Verifier
24
+ sec_trailer :sec_trailer, onlyif: -> { has_auth_verifier? }
25
+ string :auth_value, label: 'Authentication verifier',
26
+ onlyif: -> { has_auth_verifier? },
19
27
  read_length: -> { pdu_header.auth_length }
20
28
 
21
29
  def initialize_instance
22
30
  super
23
- pdu_header.ptype = RubySMB::Dcerpc::PTypes::RESPONSE
31
+ pdu_header.ptype = PTYPE
32
+ end
33
+
34
+ def has_auth_verifier?
35
+ self.pdu_header.auth_length > 0
36
+ end
37
+
38
+ def stub_length
39
+ stub_length = pdu_header.frag_length - stub.rel_offset
40
+ if has_auth_verifier?
41
+ # Note that the resulting stub length includes auth_pad. We will be
42
+ # able to separate the auth_pad from the stub once the sec_trailer
43
+ # structure is read.
44
+ stub_length -= (sec_trailer.num_bytes + pdu_header.auth_length)
45
+ end
46
+ stub_length
47
+ end
48
+
49
+ def read(io)
50
+ super
51
+ if has_auth_verifier? && sec_trailer.auth_pad_length > 0
52
+ # At this point, auth_pad is at the end of the stub. We need to move
53
+ # it to the correct field. It is now possible since we know its
54
+ # length from the sec_trailer auth_pad_length field.
55
+ pad = stub[-(sec_trailer.auth_pad_length)..-1]
56
+ stub.assign(stub[0...-(sec_trailer.auth_pad_length)])
57
+ auth_pad.assign(pad)
58
+ end
24
59
  end
25
60
  end
26
61
  end
@@ -0,0 +1,28 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+
4
+ # [2.2.2.10 rpc_auth_3 PDU](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/a6b7b03c-4ac5-4c25-8c52-f2bec872ac97)
5
+ class RpcAuth3 < BinData::Record
6
+ PTYPE = PTypes::RPC_AUTH3
7
+
8
+ endian :little
9
+
10
+ # PDU Header
11
+ pdu_header :pdu_header
12
+ uint32 :pad
13
+
14
+ # Auth Verifier
15
+ sec_trailer :sec_trailer, onlyif: -> { pdu_header.auth_length > 0 }
16
+ string :auth_value,
17
+ onlyif: -> { pdu_header.auth_length > 0 },
18
+ read_length: -> { pdu_header.auth_length }
19
+
20
+ def initialize_instance
21
+ super
22
+ pdu_header.ptype = PTYPE
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+
@@ -3,30 +3,30 @@ module RubySMB
3
3
 
4
4
  # This class represents a RPC_SECURITY_DESCRIPTOR structure as defined in
5
5
  # [2.2.8 RPC_SECURITY_DESCRIPTOR](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/9729e781-8eb9-441b-82ca-e898f98d29c2)
6
- class RpcSecurityDescriptor < BinData::Record
6
+ class RpcSecurityDescriptor < Ndr::NdrStruct
7
+ default_parameters byte_align: 4
7
8
  endian :little
8
9
 
9
- ndr_lp_byte_array :lp_security_descriptor
10
- uint32 :cb_in_security_descriptor
11
- uint32 :cb_out_security_descriptor
10
+ ndr_byte_array_ptr :lp_security_descriptor
11
+ ndr_uint32 :cb_in_security_descriptor
12
+ ndr_uint32 :cb_out_security_descriptor
12
13
  end
13
14
 
14
15
  # This class represents a RPC_SECURITY_ATTRIBUTES structure as defined in
15
16
  # [2.2.7 RPC_SECURITY_ATTRIBUTES](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/bc37b8cf-8c94-4804-ad53-0aaf5eaf0ecb)
16
- class RpcSecurityAttributes < BinData::Record
17
+ class RpcSecurityAttributes < Ndr::NdrStruct
18
+ default_parameters byte_align: 4
17
19
  endian :little
18
20
 
19
- uint32 :n_length
21
+ ndr_uint32 :n_length
20
22
  rpc_security_descriptor :rpc_security_descriptor
21
- uint8 :b_inheritHandle
23
+ ndr_uint8 :b_inheritHandle
22
24
  end
23
25
 
24
26
  # This class represents a pointer to a RPC_SECURITY_ATTRIBUTES structure as defined in
25
27
  # [2.2.7 RPC_SECURITY_ATTRIBUTES](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/bc37b8cf-8c94-4804-ad53-0aaf5eaf0ecb)
26
- class PrpcSecurityAttributes < Ndr::NdrPointer
27
- endian :little
28
-
29
- rpc_security_attributes :referent, onlyif: -> { self.referent_id != 0 }
28
+ class PrpcSecurityAttributes < RpcSecurityAttributes
29
+ extend Ndr::PointerClassPlugin
30
30
  end
31
31
 
32
32
  end
@@ -0,0 +1,118 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+
4
+ # A RRP_UNICODE_STRING structure as defined in
5
+ # [2.2.4 RRP_UNICODE_STRING](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/c0c90f11-a4c4-496a-ac09-8a8a3697ceef)
6
+ class RrpUnicodeString < Ndr::NdrStruct
7
+ default_parameters byte_align: 4
8
+ endian :little
9
+
10
+ ndr_uint16 :buffer_length
11
+ ndr_uint16 :maximum_length
12
+ ndr_wide_stringz_ptr :buffer
13
+
14
+ def assign(val)
15
+ case val
16
+ when :null
17
+ self.buffer = val
18
+ self.buffer_length = 0
19
+ self.maximum_length = 0
20
+ when BinData::Stringz, BinData::String, String
21
+ self.buffer = val.to_s
22
+ val_length = val.strip.length
23
+ val_length += 1 unless val == ''
24
+ self.buffer_length = val_length * 2
25
+ self.maximum_length = val_length * 2
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ # Set `maximum_length` and buffer `max_count` values to `val`. It also
32
+ # takes care of initializing the buffer pointer `ref_id` if the pointer
33
+ # is null.
34
+ #
35
+ # This helper is typically called in requests where a unicode string
36
+ # field needs to contain the maximum length information without any
37
+ # string value. It is usually required by some RPC calls and used by the
38
+ # server to determine the maximum length for the corresponding output
39
+ # field in order to allocate space accordingly.
40
+ def set_max_buffer_size(val)
41
+ self.buffer.instantiate_referent if self.buffer.is_null_ptr?
42
+ self.buffer.max_count = val / 2
43
+ self.maximum_length.assign(val)
44
+ end
45
+
46
+ def to_s
47
+ return ''.encode('utf-16le') if self.buffer.is_null_ptr?
48
+ self.buffer.to_s
49
+ end
50
+ end
51
+
52
+ # A pointer to a RRP_UNICODE_STRING structure
53
+ class PrrpUnicodeString < RrpUnicodeString
54
+ extend Ndr::PointerClassPlugin
55
+ end
56
+
57
+ # A RPC_UNICODE_STRING structure as defined in
58
+ # [2.3.10 RPC_UNICODE_STRING](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/94a16bb6-c610-4cb9-8db6-26f15f560061)
59
+ class RpcUnicodeString < Ndr::NdrStruct
60
+ # Same as RrpUnicodeString, but not necessary null terminated
61
+ #
62
+ # It is the caller responsability to null terminate the string, if it has
63
+ # to. This structure won't do it automatically the way RrpUnicodeString
64
+ # do.
65
+ #
66
+ # It also takes care of detecting the terminating null character and
67
+ # exclude when calculating buffer_length and maximum_length.
68
+ default_parameters byte_align: 4
69
+ endian :little
70
+
71
+ ndr_uint16 :buffer_length
72
+ ndr_uint16 :maximum_length
73
+ ndr_wide_string_ptr :buffer
74
+
75
+ def assign(val)
76
+ case val
77
+ when :null
78
+ self.buffer = val
79
+ self.buffer_length = 0
80
+ self.maximum_length = 0
81
+ when BinData::Stringz, BinData::String, String
82
+ self.buffer = val.to_s
83
+ val_length = val.strip.length
84
+ self.buffer_length = val_length * 2
85
+ self.maximum_length = val_length * 2
86
+ else
87
+ super
88
+ end
89
+ end
90
+
91
+ # Set `maximum_length` and buffer `max_count` values to `val`. It also
92
+ # takes care of initializing the buffer pointer `ref_id` if the pointer
93
+ # is null.
94
+ #
95
+ # This helper is typically called in requests where a unicode string
96
+ # field needs to contain the maximum length information without any
97
+ # string value. It is usually required by some RPC calls and used by the
98
+ # server to determine the maximum length for the corresponding output
99
+ # field in order to allocate space accordingly.
100
+ def set_max_buffer_size(val)
101
+ self.buffer.instantiate_referent if self.buffer.is_null_ptr?
102
+ self.buffer.max_count = val / 2
103
+ self.maximum_length.assign(val)
104
+ end
105
+
106
+ def to_s
107
+ return ''.encode('utf-16le') if self.buffer.is_null_ptr?
108
+ self.buffer.to_s
109
+ end
110
+ end
111
+
112
+ # A pointer to a RPC_UNICODE_STRING structure
113
+ class PrpcUnicodeString < RpcUnicodeString
114
+ extend Ndr::PointerClassPlugin
115
+ end
116
+ end
117
+ end
118
+