ruby_smb 2.0.2 → 3.0.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 (285) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +46 -0
  4. data/README.md +0 -1
  5. data/examples/anonymous_auth.rb +3 -3
  6. data/examples/append_file.rb +10 -8
  7. data/examples/auth_capture.rb +71 -0
  8. data/examples/authenticate.rb +9 -5
  9. data/examples/delete_file.rb +8 -6
  10. data/examples/dump_secrets_from_sid.rb +207 -0
  11. data/examples/enum_domain_users.rb +75 -0
  12. data/examples/enum_registry_key.rb +5 -4
  13. data/examples/enum_registry_values.rb +5 -4
  14. data/examples/get_computer_info.rb +42 -0
  15. data/examples/list_directory.rb +8 -6
  16. data/examples/negotiate_with_netbios_service.rb +9 -5
  17. data/examples/net_share_enum_all.rb +6 -4
  18. data/examples/pipes.rb +11 -12
  19. data/examples/query_service_status.rb +102 -0
  20. data/examples/read_file.rb +8 -6
  21. data/examples/read_registry_key_value.rb +6 -5
  22. data/examples/rename_file.rb +9 -7
  23. data/examples/tree_connect.rb +7 -5
  24. data/examples/write_file.rb +9 -7
  25. data/lib/ruby_smb/client/authentication.rb +5 -10
  26. data/lib/ruby_smb/client/echo.rb +2 -4
  27. data/lib/ruby_smb/client/negotiation.rb +13 -16
  28. data/lib/ruby_smb/client/tree_connect.rb +2 -4
  29. data/lib/ruby_smb/client/utils.rb +16 -10
  30. data/lib/ruby_smb/client/winreg.rb +1 -1
  31. data/lib/ruby_smb/client.rb +102 -75
  32. data/lib/ruby_smb/compression/lznt1.rb +164 -0
  33. data/lib/ruby_smb/compression.rb +7 -0
  34. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  35. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  36. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  37. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  38. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  39. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  40. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  41. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  42. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  43. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  44. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  45. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  46. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  47. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  48. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  49. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  50. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  51. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  52. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  53. data/lib/ruby_smb/dcerpc/error.rb +20 -0
  54. data/lib/ruby_smb/dcerpc/ndr.rb +1204 -80
  55. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +27 -0
  56. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
  57. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
  58. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
  59. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +24 -0
  60. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
  61. data/lib/ruby_smb/dcerpc/netlogon.rb +102 -0
  62. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  63. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  64. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  65. data/lib/ruby_smb/dcerpc/request.rb +85 -19
  66. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  67. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  68. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
  69. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  70. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  71. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  72. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  73. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  74. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  75. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  76. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  77. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  78. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  79. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  80. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  81. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  82. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  83. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  84. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  85. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  86. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  87. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  88. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  89. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  90. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  91. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  92. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  93. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +36 -0
  94. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
  95. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
  96. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
  97. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
  98. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
  99. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +25 -0
  100. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
  101. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +23 -0
  102. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
  103. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
  104. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +45 -0
  105. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
  106. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
  107. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +26 -0
  108. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
  109. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
  110. data/lib/ruby_smb/dcerpc/svcctl.rb +477 -0
  111. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  112. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  113. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +62 -0
  114. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
  115. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +2 -19
  116. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  117. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  118. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  119. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  120. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  121. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +6 -7
  122. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  123. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
  124. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  125. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -13
  126. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  127. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  128. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +28 -0
  129. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
  130. data/lib/ruby_smb/dcerpc/winreg.rb +99 -22
  131. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  132. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  133. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  134. data/lib/ruby_smb/dcerpc.rb +45 -11
  135. data/lib/ruby_smb/dialect.rb +45 -0
  136. data/lib/ruby_smb/dispatcher/base.rb +1 -1
  137. data/lib/ruby_smb/dispatcher/socket.rb +2 -2
  138. data/lib/ruby_smb/error.rb +21 -5
  139. data/lib/ruby_smb/field/file_time.rb +1 -1
  140. data/lib/ruby_smb/field/string16.rb +5 -1
  141. data/lib/ruby_smb/field/stringz16.rb +17 -1
  142. data/lib/ruby_smb/generic_packet.rb +11 -1
  143. data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
  144. data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
  145. data/lib/ruby_smb/gss/provider.rb +35 -0
  146. data/lib/ruby_smb/gss.rb +56 -63
  147. data/lib/ruby_smb/nbss/session_header.rb +4 -4
  148. data/lib/ruby_smb/ntlm.rb +61 -0
  149. data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
  150. data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
  151. data/lib/ruby_smb/server/server_client.rb +162 -0
  152. data/lib/ruby_smb/server.rb +54 -0
  153. data/lib/ruby_smb/signing.rb +59 -0
  154. data/lib/ruby_smb/smb1/file.rb +10 -25
  155. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
  156. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
  157. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
  158. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
  159. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
  160. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
  161. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
  162. data/lib/ruby_smb/smb1/pipe.rb +12 -6
  163. data/lib/ruby_smb/smb1/tree.rb +13 -9
  164. data/lib/ruby_smb/smb2/file.rb +33 -33
  165. data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
  166. data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +4 -0
  167. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
  168. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
  169. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
  170. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
  171. data/lib/ruby_smb/smb2/pipe.rb +13 -6
  172. data/lib/ruby_smb/smb2/tree.rb +21 -11
  173. data/lib/ruby_smb/smb2.rb +3 -1
  174. data/lib/ruby_smb/version.rb +1 -1
  175. data/lib/ruby_smb.rb +5 -3
  176. data/spec/lib/ruby_smb/client_spec.rb +199 -86
  177. data/spec/lib/ruby_smb/compression/lznt1_spec.rb +32 -0
  178. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  179. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  180. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  181. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  182. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3977 -239
  183. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
  184. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
  185. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
  186. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
  187. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
  188. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
  189. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  190. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  191. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  192. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  193. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  194. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +162 -0
  195. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  196. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  197. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  198. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  199. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  200. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  201. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  202. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  203. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  204. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  205. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  206. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  207. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  208. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  209. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  210. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  211. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  212. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  213. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +168 -0
  214. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
  215. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
  216. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
  217. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
  218. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
  219. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +68 -0
  220. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
  221. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +53 -0
  222. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
  223. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
  224. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
  225. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
  226. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
  227. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +76 -0
  228. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +47 -0
  229. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
  230. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +508 -0
  231. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  232. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  233. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +73 -0
  234. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
  235. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -56
  236. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  237. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  238. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  239. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  240. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  241. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -20
  242. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  243. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +0 -4
  244. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  245. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  246. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +18 -42
  247. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  248. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +45 -0
  249. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
  250. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +219 -62
  251. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  252. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  253. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  254. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
  255. data/spec/lib/ruby_smb/error_spec.rb +34 -5
  256. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  257. data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
  258. data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
  259. data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
  260. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
  261. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
  262. data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
  263. data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
  264. data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
  265. data/spec/lib/ruby_smb/server_spec.rb +32 -0
  266. data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
  267. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
  268. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
  269. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
  270. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
  271. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +20 -14
  272. data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
  273. data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
  274. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
  275. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +20 -14
  276. data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
  277. data/spec/spec_helper.rb +1 -1
  278. data/spec/support/bin_helper.rb +9 -0
  279. data.tar.gz.sig +0 -0
  280. metadata +229 -23
  281. metadata.gz.sig +0 -0
  282. data/.travis.yml +0 -6
  283. data/lib/ruby_smb/client/signing.rb +0 -64
  284. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -35
  285. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -98
@@ -2,18 +2,19 @@ module RubySMB
2
2
  # Represents an SMB client capable of talking to SMB1 or SMB2 servers and handling
3
3
  # all end-user client functionality.
4
4
  class Client
5
+ require 'ruby_smb/ntlm'
6
+ require 'ruby_smb/signing'
5
7
  require 'ruby_smb/client/negotiation'
6
8
  require 'ruby_smb/client/authentication'
7
- require 'ruby_smb/client/signing'
8
9
  require 'ruby_smb/client/tree_connect'
9
10
  require 'ruby_smb/client/echo'
10
11
  require 'ruby_smb/client/utils'
11
12
  require 'ruby_smb/client/winreg'
12
13
  require 'ruby_smb/client/encryption'
13
14
 
15
+ include RubySMB::Signing
14
16
  include RubySMB::Client::Negotiation
15
17
  include RubySMB::Client::Authentication
16
- include RubySMB::Client::Signing
17
18
  include RubySMB::Client::TreeConnect
18
19
  include RubySMB::Client::Echo
19
20
  include RubySMB::Client::Utils
@@ -160,9 +161,16 @@ module RubySMB
160
161
 
161
162
  # The UID set in SMB1
162
163
  # @!attribute [rw] user_id
163
- # @return [String]
164
+ # @return [Integer]
164
165
  attr_accessor :user_id
165
166
 
167
+ # The Process ID set in SMB1
168
+ # It is randomly generated during the client initialization, but can
169
+ # be modified using the accessor.
170
+ # @!attribute [rw] pid
171
+ # @return [Integer]
172
+ attr_accessor :pid
173
+
166
174
  # The maximum size SMB message that the Client accepts (in bytes)
167
175
  # The default value is equal to {MAX_BUFFER_SIZE}.
168
176
  # @!attribute [rw] max_buffer_size
@@ -258,16 +266,26 @@ module RubySMB
258
266
  # @return [Integer] the negotiated SMB version
259
267
  attr_accessor :negotiated_smb_version
260
268
 
269
+ # Whether or not the server supports multi-credit operations. It is
270
+ # reported by the LARGE_MTU capabiliy as part of the negotiation process
271
+ # (SMB 2.x and 3.x).
272
+ # @!attribute [rw] server_supports_multi_credit
273
+ # @return [Boolean] true if the server supports multi-credit operations,
274
+ # false otherwise
275
+ attr_accessor :server_supports_multi_credit
276
+
261
277
  # @param dispatcher [RubySMB::Dispatcher::Socket] the packet dispatcher to use
262
278
  # @param smb1 [Boolean] whether or not to enable SMB1 support
263
279
  # @param smb2 [Boolean] whether or not to enable SMB2 support
264
280
  # @param smb3 [Boolean] whether or not to enable SMB3 support
265
- def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.', local_workstation: 'WORKSTATION', always_encrypt: true)
281
+ def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.',
282
+ local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
266
283
  raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
267
284
  if smb1 == false && smb2 == false && smb3 == false
268
285
  raise ArgumentError, 'You must enable at least one Protocol'
269
286
  end
270
287
  @dispatcher = dispatcher
288
+ @pid = rand(0xFFFF)
271
289
  @domain = domain
272
290
  @local_workstation = local_workstation
273
291
  @password = password.encode('utf-8') || ''.encode('utf-8')
@@ -280,27 +298,22 @@ module RubySMB
280
298
  @smb3 = smb3
281
299
  @username = username.encode('utf-8') || ''.encode('utf-8')
282
300
  @max_buffer_size = MAX_BUFFER_SIZE
283
- # These sizes will be modifed during negotiation
301
+ # These sizes will be modified during negotiation
284
302
  @server_max_buffer_size = SERVER_MAX_BUFFER_SIZE
285
303
  @server_max_read_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
286
304
  @server_max_write_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
287
305
  @server_max_transact_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
306
+ @server_supports_multi_credit = false
288
307
 
289
308
  # SMB 3.x options
290
309
  @session_encrypt_data = always_encrypt
291
310
 
292
- negotiate_version_flag = 0x02000000
293
- flags = Net::NTLM::Client::DEFAULT_FLAGS |
294
- Net::NTLM::FLAGS[:TARGET_INFO] |
295
- negotiate_version_flag ^
296
- Net::NTLM::FLAGS[:OEM]
297
-
298
311
  @ntlm_client = Net::NTLM::Client.new(
299
312
  @username,
300
313
  @password,
301
314
  workstation: @local_workstation,
302
315
  domain: @domain,
303
- flags: flags
316
+ flags: ntlm_flags
304
317
  )
305
318
 
306
319
  @tree_connects = []
@@ -344,38 +357,35 @@ module RubySMB
344
357
  # @param packet [RubySMB::GenericPacket] the packet to set the message id for
345
358
  # @return [RubySMB::GenericPacket] the modified packet
346
359
  def increment_smb_message_id(packet)
347
- packet.smb2_header.message_id = smb2_message_id
360
+ packet.smb2_header.message_id = self.smb2_message_id
348
361
  self.smb2_message_id += 1
349
362
  packet
350
363
  end
351
364
 
352
365
  # Performs protocol negotiation and session setup. It defaults to using
353
366
  # the credentials supplied during initialization, but can take a new set of credentials if needed.
354
- def login(username: self.username, password: self.password, domain: self.domain, local_workstation: self.local_workstation)
367
+ def login(username: self.username, password: self.password,
368
+ domain: self.domain, local_workstation: self.local_workstation,
369
+ ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
355
370
  negotiate
356
- session_setup(username, password, domain, true,
357
- local_workstation: local_workstation)
371
+ session_setup(username, password, domain,
372
+ local_workstation: local_workstation,
373
+ ntlm_flags: ntlm_flags)
358
374
  end
359
375
 
360
376
  def session_setup(user, pass, domain, do_recv=true,
361
- local_workstation: self.local_workstation)
377
+ local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
362
378
  @domain = domain
363
379
  @local_workstation = local_workstation
364
380
  @password = pass.encode('utf-8') || ''.encode('utf-8')
365
381
  @username = user.encode('utf-8') || ''.encode('utf-8')
366
382
 
367
- negotiate_version_flag = 0x02000000
368
- flags = Net::NTLM::Client::DEFAULT_FLAGS |
369
- Net::NTLM::FLAGS[:TARGET_INFO] |
370
- negotiate_version_flag ^
371
- Net::NTLM::FLAGS[:OEM]
372
-
373
383
  @ntlm_client = Net::NTLM::Client.new(
374
384
  @username,
375
385
  @password,
376
386
  workstation: @local_workstation,
377
387
  domain: @domain,
378
- flags: flags
388
+ flags: ntlm_flags
379
389
  )
380
390
 
381
391
  authenticate
@@ -394,8 +404,7 @@ module RubySMB
394
404
  raise RubySMB::Error::InvalidPacket.new(
395
405
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
396
406
  expected_cmd: RubySMB::SMB2::Packet::LogoffResponse::COMMAND,
397
- received_proto: response.smb2_header.protocol,
398
- received_cmd: response.smb2_header.command
407
+ packet: response
399
408
  )
400
409
  end
401
410
  else
@@ -406,8 +415,7 @@ module RubySMB
406
415
  raise RubySMB::Error::InvalidPacket.new(
407
416
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
408
417
  expected_cmd: RubySMB::SMB1::Packet::LogoffResponse::COMMAND,
409
- received_proto: response.smb_header.protocol,
410
- received_cmd: response.smb_header.command
418
+ packet: response
411
419
  )
412
420
  end
413
421
  end
@@ -416,7 +424,7 @@ module RubySMB
416
424
  end
417
425
 
418
426
  # Sends a packet and receives the raw response through the Dispatcher.
419
- # It will also sign the packet if neccessary.
427
+ # It will also sign the packet if necessary.
420
428
  #
421
429
  # @param packet [RubySMB::GenericPacket] the request to be sent
422
430
  # @param encrypt [Boolean] true if encryption has to be enabled for this transaction
@@ -427,15 +435,16 @@ module RubySMB
427
435
  version = packet.packet_smb_version
428
436
  case version
429
437
  when 'SMB1'
430
- packet.smb_header.uid = user_id if user_id
431
- packet = smb1_sign(packet)
438
+ packet.smb_header.uid = self.user_id if self.user_id
439
+ packet.smb_header.pid_low = self.pid if self.pid
440
+ packet = smb1_sign(packet) if signing_required && !session_key.empty?
432
441
  when 'SMB2'
433
442
  packet = increment_smb_message_id(packet)
434
443
  packet.smb2_header.session_id = session_id
435
- unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest)
436
- if self.smb2
444
+ unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest) || session_key.empty?
445
+ if self.smb2 && signing_required
437
446
  packet = smb2_sign(packet)
438
- elsif self.smb3
447
+ elsif self.smb3 && (signing_required || packet.is_a?(RubySMB::SMB2::Packet::TreeConnectRequest))
439
448
  packet = smb3_sign(packet)
440
449
  end
441
450
  end
@@ -443,35 +452,38 @@ module RubySMB
443
452
  packet = packet
444
453
  end
445
454
 
455
+ encrypt_data = false
446
456
  if can_be_encrypted?(packet) && encryption_supported? && (@session_encrypt_data || encrypt)
447
- send_encrypt(packet)
448
- raw_response = recv_encrypt
449
- loop do
450
- break unless is_status_pending?(raw_response)
451
- sleep 1
452
- raw_response = recv_encrypt
453
- end
454
- else
455
- dispatcher.send_packet(packet)
456
- raw_response = dispatcher.recv_packet
457
- loop do
458
- break unless is_status_pending?(raw_response)
459
- sleep 1
460
- raw_response = dispatcher.recv_packet
461
- end unless version == 'SMB1'
457
+ encrypt_data = true
462
458
  end
459
+ send_packet(packet, encrypt: encrypt_data)
460
+ raw_response = recv_packet(encrypt: encrypt_data)
461
+ smb2_header = nil
462
+ loop do
463
+ smb2_header = RubySMB::SMB2::SMB2Header.read(raw_response)
464
+ break unless is_status_pending?(smb2_header)
465
+ sleep 1
466
+ raw_response = recv_packet(encrypt: encrypt_data)
467
+ rescue IOError
468
+ # We're expecting an SMB2 packet, but the server sent an SMB1 packet
469
+ # instead. This behavior has been observed with older versions of Samba
470
+ # when something goes wrong on the server side. So, we just ignore it
471
+ # and expect the caller to handle this wrong response packet.
472
+ break
473
+ end unless version == 'SMB1'
463
474
 
464
475
  self.sequence_counter += 1 if signing_required && !session_key.empty?
476
+ # update the SMB2 message ID according to the received Credit Charged
477
+ self.smb2_message_id += smb2_header.credit_charge - 1 if smb2_header && self.server_supports_multi_credit
465
478
  raw_response
466
479
  end
467
480
 
468
481
  # Check if the response is an asynchronous operation with STATUS_PENDING
469
482
  # status code.
470
483
  #
471
- # @param raw_response [String] the raw response packet
484
+ # @param smb2_header [String] the response packet SMB2 header
472
485
  # @return [Boolean] true if it is a status pending operation, false otherwise
473
- def is_status_pending?(raw_response)
474
- smb2_header = RubySMB::SMB2::SMB2Header.read(raw_response)
486
+ def is_status_pending?(smb2_header)
475
487
  value = smb2_header.nt_status.value
476
488
  status_code = WindowsError::NTStatus.find_by_retval(value).first
477
489
  status_code == WindowsError::NTStatus::STATUS_PENDING &&
@@ -497,37 +509,50 @@ module RubySMB
497
509
  ['0x0300', '0x0302', '0x0311'].include?(@dialect)
498
510
  end
499
511
 
500
- # Encrypt and send a packet
501
- def send_encrypt(packet)
502
- begin
503
- transform_request = smb3_encrypt(packet.to_binary_s)
504
- rescue RubySMB::Error::RubySMBError => e
505
- raise RubySMB::Error::EncryptionError, "Error while encrypting #{packet.class.name} packet (SMB #{@dialect}): #{e}"
512
+ # Encrypt (if required) and send a packet.
513
+ #
514
+ # @param encrypt [Boolean] true if the packet should be encrypted, false
515
+ # otherwise
516
+ def send_packet(packet, encrypt: false)
517
+ if encrypt
518
+ begin
519
+ packet = smb3_encrypt(packet.to_binary_s)
520
+ rescue RubySMB::Error::RubySMBError => e
521
+ raise RubySMB::Error::EncryptionError, "Error while encrypting #{packet.class.name} packet (SMB #{@dialect}): #{e}"
522
+ end
506
523
  end
507
- dispatcher.send_packet(transform_request)
524
+ dispatcher.send_packet(packet)
508
525
  end
509
526
 
510
- # Receives the raw response through the Dispatcher and decrypt the packet.
527
+ # Receives the raw response through the Dispatcher and decrypt the packet (if required).
511
528
  #
529
+ # @param encrypt [Boolean] true if the packet is encrypted, false otherwise
512
530
  # @return [String] the raw unencrypted packet
513
- def recv_encrypt
531
+ def recv_packet(encrypt: false)
514
532
  begin
515
533
  raw_response = dispatcher.recv_packet
516
534
  rescue RubySMB::Error::CommunicationError => e
517
- raise RubySMB::Error::EncryptionError, "Communication error with the "\
518
- "remote host: #{e.message}. The server supports encryption but was "\
519
- "not able to handle the encrypted request."
520
- end
521
- begin
522
- transform_response = RubySMB::SMB2::Packet::TransformHeader.read(raw_response)
523
- rescue IOError
524
- raise RubySMB::Error::InvalidPacket, 'Not a SMB2 TransformHeader packet'
535
+ if encrypt
536
+ raise RubySMB::Error::EncryptionError, "Communication error with the "\
537
+ "remote host: #{e.message}. The server supports encryption but was "\
538
+ "not able to handle the encrypted request."
539
+ else
540
+ raise e
541
+ end
525
542
  end
526
- begin
527
- smb3_decrypt(transform_response)
528
- rescue RubySMB::Error::RubySMBError => e
529
- raise RubySMB::Error::EncryptionError, "Error while decrypting #{transform_response.class.name} packet (SMB #@dialect}): #{e}"
543
+ if encrypt
544
+ begin
545
+ transform_response = RubySMB::SMB2::Packet::TransformHeader.read(raw_response)
546
+ rescue IOError
547
+ raise RubySMB::Error::InvalidPacket, 'Not a SMB2 TransformHeader packet'
548
+ end
549
+ begin
550
+ raw_response = smb3_decrypt(transform_response)
551
+ rescue RubySMB::Error::RubySMBError => e
552
+ raise RubySMB::Error::EncryptionError, "Error while decrypting #{transform_response.class.name} packet (SMB #@dialect}): #{e}"
553
+ end
530
554
  end
555
+ raw_response
531
556
  end
532
557
 
533
558
  # Connects to the supplied share
@@ -551,7 +576,7 @@ module RubySMB
551
576
  # @param [String] host
552
577
  def net_share_enum_all(host)
553
578
  tree = tree_connect("\\\\#{host}\\IPC$")
554
- named_pipe = tree.open_file(filename: "srvsvc", write: true, read: true)
579
+ named_pipe = tree.open_pipe(filename: "srvsvc", write: true, read: true)
555
580
  named_pipe.net_share_enum_all(host)
556
581
  end
557
582
 
@@ -568,6 +593,7 @@ module RubySMB
568
593
  self.smb2_message_id = 0
569
594
  self.client_encryption_key = nil
570
595
  self.server_encryption_key = nil
596
+ self.server_supports_multi_credit = false
571
597
  end
572
598
 
573
599
  # Requests a NetBIOS Session Service using the provided name.
@@ -605,7 +631,7 @@ module RubySMB
605
631
  session_request.session_header.session_packet_type = RubySMB::Nbss::SESSION_REQUEST
606
632
  session_request.called_name = called_name
607
633
  session_request.calling_name = calling_name
608
- session_request.session_header.packet_length =
634
+ session_request.session_header.stream_protocol_length =
609
635
  session_request.num_bytes - session_request.session_header.num_bytes
610
636
  session_request
611
637
  end
@@ -621,5 +647,6 @@ module RubySMB
621
647
  @preauth_integrity_hash_value + data.to_binary_s
622
648
  )
623
649
  end
650
+
624
651
  end
625
652
  end
@@ -0,0 +1,164 @@
1
+ module RubySMB
2
+ module Compression
3
+ module LZNT1
4
+ def self.compress(buf, chunk_size: 0x1000)
5
+ out = ''
6
+ until buf.empty?
7
+ chunk = buf[0...chunk_size]
8
+ compressed = compress_chunk(chunk)
9
+ # chunk is compressed
10
+ if compressed.length < chunk.length
11
+ out << [0xb000 | (compressed.length - 1)].pack('v')
12
+ out << compressed
13
+ else
14
+ out << [0x3000 | (chunk.length - 1)].pack('v')
15
+ out << chunk
16
+ end
17
+ buf = buf[chunk_size..-1]
18
+ break if buf.nil?
19
+ end
20
+
21
+ out
22
+ end
23
+
24
+ def self.compress_chunk(chunk)
25
+ blob = chunk
26
+ out = ''
27
+ pow2 = 0x10
28
+ l_mask3 = 0x1002
29
+ o_shift = 12
30
+ until blob.empty?
31
+ bits = 0
32
+ tmp = ''
33
+ i = -1
34
+ loop do
35
+ i += 1
36
+ bits >>= 1
37
+ while pow2 < (chunk.length - blob.length)
38
+ pow2 <<= 1
39
+ l_mask3 = (l_mask3 >> 1) + 1
40
+ o_shift -= 1
41
+ end
42
+
43
+ max_len = [blob.length, l_mask3].min
44
+ offset, length = find(chunk[0...(chunk.length - blob.length)], blob, max_len)
45
+
46
+ # try to find more compressed pattern
47
+ _offset2, length2 = find(chunk[0...chunk.length - blob.length + 1], blob[1..-1], max_len)
48
+
49
+ length = 0 if length < length2
50
+
51
+ if length > 0
52
+ symbol = ((offset - 1) << o_shift) | (length - 3)
53
+ tmp << [symbol].pack('v')
54
+ # set the highest bit
55
+ bits |= 0x80
56
+ blob = blob[length..-1]
57
+ else
58
+ tmp += blob[0]
59
+ blob = blob[1..-1]
60
+ end
61
+
62
+ break if blob.empty? || i == 7
63
+ end
64
+
65
+ out << [bits >> (7 - i)].pack('C')
66
+ out << tmp
67
+ end
68
+
69
+ out
70
+ end
71
+
72
+ def self.decompress(buf, length_check: true)
73
+ out = ''
74
+ until buf.empty?
75
+ header = buf.unpack1('v')
76
+ length = (header & 0xfff) + 1
77
+ raise EncodingError, 'invalid chunk length' if length_check && length > (buf.length - 2)
78
+
79
+ chunk = buf[2...length + 2]
80
+ out << if header & 0x8000 == 0
81
+ chunk
82
+ else
83
+ decompress_chunk(chunk)
84
+ end
85
+ buf = buf[length + 2..-1]
86
+ end
87
+
88
+ out
89
+ end
90
+
91
+ def self.decompress_chunk(chunk)
92
+ out = ''
93
+ until chunk.empty?
94
+ flags = chunk[0].unpack1('C')
95
+ chunk = chunk[1..-1]
96
+ 8.times do |i|
97
+ if (flags >> i & 1) == 0
98
+ out << chunk[0]
99
+ chunk = chunk[1..-1]
100
+ else
101
+ flag = chunk.unpack1('v')
102
+ pos = out.length - 1
103
+ l_mask = 0xfff
104
+ o_shift = 12
105
+ while pos >= 0x10
106
+ l_mask >>= 1
107
+ o_shift -= 1
108
+ pos >>= 1
109
+ end
110
+
111
+ length = (flag & l_mask) + 3
112
+ offset = (flag >> o_shift) + 1
113
+
114
+ if length >= offset
115
+ out_offset = out[-offset..-1]
116
+ tmp = out_offset * (0xfff / out_offset.length + 1)
117
+ out << tmp[0...length]
118
+ else
119
+ out << out[-offset..-offset + length - 1]
120
+ end
121
+ chunk = chunk[2..-1]
122
+ end
123
+ break if chunk.empty?
124
+ end
125
+ end
126
+
127
+ out
128
+ end
129
+
130
+ class << self
131
+ private
132
+
133
+ def find(src, target, max_len)
134
+ result_offset = 0
135
+ result_length = 0
136
+ 1.upto(max_len - 1) do |i|
137
+ offset = src.rindex(target[0...i])
138
+ next if offset.nil?
139
+
140
+ tmp_offset = src.length - offset
141
+ tmp_length = i
142
+ if tmp_offset == tmp_length
143
+ src_offset = src[offset..-1]
144
+ tmp = src_offset * (0xfff / src_offset.length + 1)
145
+ i.upto(max_len) do |j|
146
+ offset = tmp.rindex(target[0...j])
147
+ break if offset.nil?
148
+
149
+ tmp_length = j
150
+ end
151
+ end
152
+
153
+ if tmp_length > result_length
154
+ result_offset = tmp_offset
155
+ result_length = tmp_length
156
+ end
157
+ end
158
+
159
+ result_length < 3 ? [0, 0] : [result_offset, result_length]
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,7 @@
1
+ module RubySMB
2
+ module Compression
3
+
4
+ require 'ruby_smb/compression/lznt1'
5
+
6
+ end
7
+ end
@@ -2,51 +2,59 @@ module RubySMB
2
2
  module Dcerpc
3
3
  # The Bind PDU as defined in
4
4
  # [The bind PDU](http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_03)
5
- class PContElemT < BinData::Record
5
+ class PContElemT < Ndr::NdrStruct
6
+ default_parameter byte_align: 4
6
7
  endian :little
7
8
 
8
- uint16 :p_cont_id, label: 'Context ID'
9
- uint8 :n_transfer_syn, label: 'Number of transfer syntaxes', initial_value: 1
10
- uint8 :reserved
9
+ ndr_uint16 :p_cont_id, label: 'Context ID'
10
+ ndr_uint8 :n_transfer_syn, label: 'Number of transfer syntaxes', initial_value: 1
11
+ ndr_uint8 :reserved
11
12
  p_syntax_id_t :abstract_syntax, label: 'Abstract syntax',
12
13
  uuid: -> { endpoint::UUID },
13
14
  ver_major: -> { endpoint::VER_MAJOR },
14
15
  ver_minor: -> { endpoint::VER_MINOR }
15
- array :transfer_syntaxes, label: 'Transfer syntax', type: :p_syntax_id_t,
16
+ array :transfer_syntaxes, label: 'Transfer syntax', type: :p_syntax_id_t,
16
17
  initial_length: -> { n_transfer_syn },
17
18
  uuid: -> { Ndr::UUID },
18
19
  ver_major: -> { Ndr::VER_MAJOR },
19
- ver_minor: -> { Ndr::VER_MINOR }
20
+ ver_minor: -> { Ndr::VER_MINOR },
21
+ byte_align: 4
20
22
  end
21
23
 
22
- class PContListT < BinData::Record
24
+ class PContListT < Ndr::NdrStruct
25
+ default_parameter byte_align: 4
23
26
  endian :little
24
27
 
25
- uint8 :n_context_elem, label: 'Number of context elements', initial_value: -> { 1 }
26
- uint8 :reserved
27
- uint16 :reserved2
28
- array :p_cont_elem, label: 'Presentation context elements', type: :p_cont_elem_t,
28
+ ndr_uint8 :n_context_elem, label: 'Number of context elements', initial_value: -> { 1 }
29
+ ndr_uint8 :reserved
30
+ ndr_uint16 :reserved2
31
+ array :p_cont_elem, label: 'Presentation context elements', type: :p_cont_elem_t,
29
32
  initial_length: -> {n_context_elem},
30
- endpoint: -> {endpoint}
33
+ endpoint: -> {endpoint},
34
+ byte_align: 4
31
35
  end
32
36
 
33
37
  class Bind < BinData::Record
34
- endian :little
35
-
36
- pdu_header :pdu_header, label: 'PDU header'
38
+ PTYPE = PTypes::BIND
37
39
 
38
- uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
39
- uint16 :max_recv_frag, label: 'max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
40
- uint32 :assoc_group_id, label: 'ncarnation of client-server assoc group'
40
+ endian :little
41
41
 
42
+ # PDU Header
43
+ pdu_header :pdu_header, label: 'PDU header'
44
+ ndr_uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
45
+ ndr_uint16 :max_recv_frag, label: 'max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
46
+ ndr_uint32 :assoc_group_id, label: 'incarnation of client-server assoc group'
42
47
  p_cont_list_t :p_context_list, label: 'Presentation context list', endpoint: -> { endpoint }
43
- string :auth_verifier, label: 'Authentication verifier',
48
+
49
+ # Auth Verifier
50
+ sec_trailer :sec_trailer, onlyif: -> { pdu_header.auth_length > 0 }
51
+ string :auth_value,
44
52
  onlyif: -> { pdu_header.auth_length > 0 },
45
53
  read_length: -> { pdu_header.auth_length }
46
54
 
47
55
  def initialize_instance
48
56
  super
49
- pdu_header.ptype = RubySMB::Dcerpc::PTypes::BIND
57
+ pdu_header.ptype = PTYPE
50
58
  end
51
59
  end
52
60
  end