Best Python code snippet using Kiwi_python
rpcrt.py
Source:rpcrt.py  
1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.2#3# This software is provided under under a slightly modified version4# of the Apache Software License. See the accompanying LICENSE file5# for more information.6#7# Description:8#   Partial C706.pdf + [MS-RPCE] implementation9#10#   Best way to learn how to use these calls is to grab the protocol standard11#   so you understand what the call does, and then read the test case located12#   at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC13#14# ToDo: 15# [ ] Take out all the security provider stuff out of here (e.g. RPC_C_AUTHN_WINNT)16#     and put it elsewhere. This will make the coder cleaner and easier to add 17#     more SSP (e.g. NETLOGON)18# 19import logging20import socket21import sys22from binascii import unhexlify23from Cryptodome.Cipher import ARC424from impacket import ntlm, LOG25from impacket.structure import Structure,pack,unpack26from impacket.krb5 import kerberosv5, gssapi27from impacket.uuid import uuidtup_to_bin, generate, stringver_to_bin, bin_to_uuidtup28from impacket.dcerpc.v5.dtypes import UCHAR, ULONG, USHORT29from impacket.dcerpc.v5.ndr import NDRSTRUCT30from impacket import hresult_errors31from threading import Thread32# MS/RPC Constants33MSRPC_REQUEST   = 0x0034MSRPC_PING      = 0x0135MSRPC_RESPONSE  = 0x0236MSRPC_FAULT     = 0x0337MSRPC_WORKING   = 0x0438MSRPC_NOCALL    = 0x0539MSRPC_REJECT    = 0x0640MSRPC_ACK       = 0x0741MSRPC_CL_CANCEL = 0x0842MSRPC_FACK      = 0x0943MSRPC_CANCELACK = 0x0A44MSRPC_BIND      = 0x0B45MSRPC_BINDACK   = 0x0C46MSRPC_BINDNAK   = 0x0D47MSRPC_ALTERCTX  = 0x0E48MSRPC_ALTERCTX_R= 0x0F49MSRPC_AUTH3     = 0x1050MSRPC_SHUTDOWN  = 0x1151MSRPC_CO_CANCEL = 0x1252MSRPC_ORPHANED  = 0x1353MSRPC_RTS       = 0x1454# MS/RPC Packet Flags55PFC_FIRST_FRAG     = 0x0156PFC_LAST_FRAG      = 0x0257# For PDU types bind, bind_ack, alter_context, and58# alter_context_resp, this flag MUST be interpreted as PFC_SUPPORT_HEADER_SIGN59MSRPC_SUPPORT_SIGN  = 0x0460#For the61#remaining PDU types, this flag MUST be interpreted as PFC_PENDING_CANCEL.62MSRPC_PENDING_CANCEL= 0x0463PFC_RESERVED_1      = 0x0864PFC_CONC_MPX        = 0x1065PFC_DID_NOT_EXECUTE = 0x2066PFC_MAYBE           = 0x4067PFC_OBJECT_UUID     = 0x8068# Auth Types - Security Providers69RPC_C_AUTHN_NONE          = 0x0070RPC_C_AUTHN_GSS_NEGOTIATE = 0x0971RPC_C_AUTHN_WINNT         = 0x0A72RPC_C_AUTHN_GSS_SCHANNEL  = 0x0E73RPC_C_AUTHN_GSS_KERBEROS  = 0x1074RPC_C_AUTHN_NETLOGON      = 0x4475RPC_C_AUTHN_DEFAULT       = 0xFF76# Auth Levels77RPC_C_AUTHN_LEVEL_NONE          = 178RPC_C_AUTHN_LEVEL_CONNECT       = 279RPC_C_AUTHN_LEVEL_CALL          = 380RPC_C_AUTHN_LEVEL_PKT           = 481RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 582RPC_C_AUTHN_LEVEL_PKT_PRIVACY   = 683#Reasons for rejection of a context element, included in bind_ack result reason84rpc_provider_reason = {85    0       : 'reason_not_specified',86    1       : 'abstract_syntax_not_supported',87    2       : 'proposed_transfer_syntaxes_not_supported',88    3       : 'local_limit_exceeded',89    4       : 'protocol_version_not_specified',90    8       : 'authentication_type_not_recognized',91    9       : 'invalid_checksum'92}93MSRPC_CONT_RESULT_ACCEPT = 094MSRPC_CONT_RESULT_USER_REJECT = 195MSRPC_CONT_RESULT_PROV_REJECT = 296#Results of a presentation context negotiation97rpc_cont_def_result = {98    0       : 'acceptance',99    1       : 'user_rejection',100    2       : 'provider_rejection'101}102#status codes, references:103#https://docs.microsoft.com/windows/desktop/Rpc/rpc-return-values104#https://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/common_return_values.asp105#winerror.h106#https://www.opengroup.org/onlinepubs/9629399/apdxn.htm107rpc_status_codes = {108    0x00000005 : 'rpc_s_access_denied',109    0x00000008 : 'Authentication type not recognized',110    0x000006D8 : 'rpc_fault_cant_perform', 111    0x000006C6 : 'rpc_x_invalid_bound',                # the arrays bound are invalid112    0x000006E4 : 'rpc_s_cannot_support: The requested operation is not supported.',               # some operation is not supported113    0x000006F7 : 'rpc_x_bad_stub_data',                # the stub data is invalid, doesn't match with the IDL definition114    0x1C010001 : 'nca_s_comm_failure',                 # unable to get response from server:115    0x1C010002 : 'nca_s_op_rng_error',                 # bad operation number in call116    0x1C010003 : 'nca_s_unk_if',                       # unknown interface117    0x1C010006 : 'nca_s_wrong_boot_time',              # client passed server wrong server boot time118    0x1C010009 : 'nca_s_you_crashed',                  # a restarted server called back a client119    0x1C01000B : 'nca_s_proto_error',                  # someone messed up the protocol120    0x1C010013 : 'nca_s_out_args_too_big ',            # output args too big121    0x1C010014 : 'nca_s_server_too_busy',              # server is too busy to handle call122    0x1C010015 : 'nca_s_fault_string_too_long',        # string argument longer than declared max len123    0x1C010017 : 'nca_s_unsupported_type ',            # no implementation of generic operation for object124    0x1C000001 : 'nca_s_fault_int_div_by_zero',125    0x1C000002 : 'nca_s_fault_addr_error ',126    0x1C000003 : 'nca_s_fault_fp_div_zero',127    0x1C000004 : 'nca_s_fault_fp_underflow',128    0x1C000005 : 'nca_s_fault_fp_overflow',129    0x1C000006 : 'nca_s_fault_invalid_tag',130    0x1C000007 : 'nca_s_fault_invalid_bound ',131    0x1C000008 : 'nca_s_rpc_version_mismatch',132    0x1C000009 : 'nca_s_unspec_reject ',133    0x1C00000A : 'nca_s_bad_actid',134    0x1C00000B : 'nca_s_who_are_you_failed',135    0x1C00000C : 'nca_s_manager_not_entered ',136    0x1C00000D : 'nca_s_fault_cancel',137    0x1C00000E : 'nca_s_fault_ill_inst',138    0x1C00000F : 'nca_s_fault_fp_error',139    0x1C000010 : 'nca_s_fault_int_overflow',140    0x1C000012 : 'nca_s_fault_unspec',141    0x1C000013 : 'nca_s_fault_remote_comm_failure ',142    0x1C000014 : 'nca_s_fault_pipe_empty ',143    0x1C000015 : 'nca_s_fault_pipe_closed',144    0x1C000016 : 'nca_s_fault_pipe_order ',145    0x1C000017 : 'nca_s_fault_pipe_discipline',146    0x1C000018 : 'nca_s_fault_pipe_comm_error',147    0x1C000019 : 'nca_s_fault_pipe_memory',148    0x1C00001A : 'nca_s_fault_context_mismatch ',149    0x1C00001B : 'nca_s_fault_remote_no_memory ',150    0x1C00001C : 'nca_s_invalid_pres_context_id',151    0x1C00001D : 'nca_s_unsupported_authn_level',152    0x1C00001F : 'nca_s_invalid_checksum ',153    0x1C000020 : 'nca_s_invalid_crc',154    0x1C000021 : 'nca_s_fault_user_defined',155    0x1C000022 : 'nca_s_fault_tx_open_failed',156    0x1C000023 : 'nca_s_fault_codeset_conv_error',157    0x1C000024 : 'nca_s_fault_object_not_found ',158    0x1C000025 : 'nca_s_fault_no_client_stub',159    0x16c9a000 : "rpc_s_mod",160    0x16c9a001 : "rpc_s_op_rng_error",161    0x16c9a002 : "rpc_s_cant_create_socket",162    0x16c9a003 : "rpc_s_cant_bind_socket",163    0x16c9a004 : "rpc_s_not_in_call",164    0x16c9a005 : "rpc_s_no_port",165    0x16c9a006 : "rpc_s_wrong_boot_time",166    0x16c9a007 : "rpc_s_too_many_sockets",167    0x16c9a008 : "rpc_s_illegal_register",168    0x16c9a009 : "rpc_s_cant_recv",169    0x16c9a00a : "rpc_s_bad_pkt",170    0x16c9a00b : "rpc_s_unbound_handle",171    0x16c9a00c : "rpc_s_addr_in_use",172    0x16c9a00d : "rpc_s_in_args_too_big",173    0x16c9a00e : "rpc_s_string_too_long",174    0x16c9a00f : "rpc_s_too_many_objects",175    0x16c9a010 : "rpc_s_binding_has_no_auth",176    0x16c9a011 : "rpc_s_unknown_authn_service",177    0x16c9a012 : "rpc_s_no_memory",178    0x16c9a013 : "rpc_s_cant_nmalloc",179    0x16c9a014 : "rpc_s_call_faulted",180    0x16c9a015 : "rpc_s_call_failed",181    0x16c9a016 : "rpc_s_comm_failure",182    0x16c9a017 : "rpc_s_rpcd_comm_failure",183    0x16c9a018 : "rpc_s_illegal_family_rebind",184    0x16c9a019 : "rpc_s_invalid_handle",185    0x16c9a01a : "rpc_s_coding_error",186    0x16c9a01b : "rpc_s_object_not_found",187    0x16c9a01c : "rpc_s_cthread_not_found",188    0x16c9a01d : "rpc_s_invalid_binding",189    0x16c9a01e : "rpc_s_already_registered",190    0x16c9a01f : "rpc_s_endpoint_not_found",191    0x16c9a020 : "rpc_s_invalid_rpc_protseq",192    0x16c9a021 : "rpc_s_desc_not_registered",193    0x16c9a022 : "rpc_s_already_listening",194    0x16c9a023 : "rpc_s_no_protseqs",195    0x16c9a024 : "rpc_s_no_protseqs_registered",196    0x16c9a025 : "rpc_s_no_bindings",197    0x16c9a026 : "rpc_s_max_descs_exceeded",198    0x16c9a027 : "rpc_s_no_interfaces",199    0x16c9a028 : "rpc_s_invalid_timeout",200    0x16c9a029 : "rpc_s_cant_inq_socket",201    0x16c9a02a : "rpc_s_invalid_naf_id",202    0x16c9a02b : "rpc_s_inval_net_addr",203    0x16c9a02c : "rpc_s_unknown_if",204    0x16c9a02d : "rpc_s_unsupported_type",205    0x16c9a02e : "rpc_s_invalid_call_opt",206    0x16c9a02f : "rpc_s_no_fault",207    0x16c9a030 : "rpc_s_cancel_timeout",208    0x16c9a031 : "rpc_s_call_cancelled",209    0x16c9a032 : "rpc_s_invalid_call_handle",210    0x16c9a033 : "rpc_s_cannot_alloc_assoc",211    0x16c9a034 : "rpc_s_cannot_connect",212    0x16c9a035 : "rpc_s_connection_aborted",213    0x16c9a036 : "rpc_s_connection_closed",214    0x16c9a037 : "rpc_s_cannot_accept",215    0x16c9a038 : "rpc_s_assoc_grp_not_found",216    0x16c9a039 : "rpc_s_stub_interface_error",217    0x16c9a03a : "rpc_s_invalid_object",218    0x16c9a03b : "rpc_s_invalid_type",219    0x16c9a03c : "rpc_s_invalid_if_opnum",220    0x16c9a03d : "rpc_s_different_server_instance",221    0x16c9a03e : "rpc_s_protocol_error",222    0x16c9a03f : "rpc_s_cant_recvmsg",223    0x16c9a040 : "rpc_s_invalid_string_binding",224    0x16c9a041 : "rpc_s_connect_timed_out",225    0x16c9a042 : "rpc_s_connect_rejected",226    0x16c9a043 : "rpc_s_network_unreachable",227    0x16c9a044 : "rpc_s_connect_no_resources",228    0x16c9a045 : "rpc_s_rem_network_shutdown",229    0x16c9a046 : "rpc_s_too_many_rem_connects",230    0x16c9a047 : "rpc_s_no_rem_endpoint",231    0x16c9a048 : "rpc_s_rem_host_down",232    0x16c9a049 : "rpc_s_host_unreachable",233    0x16c9a04a : "rpc_s_access_control_info_inv",234    0x16c9a04b : "rpc_s_loc_connect_aborted",235    0x16c9a04c : "rpc_s_connect_closed_by_rem",236    0x16c9a04d : "rpc_s_rem_host_crashed",237    0x16c9a04e : "rpc_s_invalid_endpoint_format",238    0x16c9a04f : "rpc_s_unknown_status_code",239    0x16c9a050 : "rpc_s_unknown_mgr_type",240    0x16c9a051 : "rpc_s_assoc_creation_failed",241    0x16c9a052 : "rpc_s_assoc_grp_max_exceeded",242    0x16c9a053 : "rpc_s_assoc_grp_alloc_failed",243    0x16c9a054 : "rpc_s_sm_invalid_state",244    0x16c9a055 : "rpc_s_assoc_req_rejected",245    0x16c9a056 : "rpc_s_assoc_shutdown",246    0x16c9a057 : "rpc_s_tsyntaxes_unsupported",247    0x16c9a058 : "rpc_s_context_id_not_found",248    0x16c9a059 : "rpc_s_cant_listen_socket",249    0x16c9a05a : "rpc_s_no_addrs",250    0x16c9a05b : "rpc_s_cant_getpeername",251    0x16c9a05c : "rpc_s_cant_get_if_id",252    0x16c9a05d : "rpc_s_protseq_not_supported",253    0x16c9a05e : "rpc_s_call_orphaned",254    0x16c9a05f : "rpc_s_who_are_you_failed",255    0x16c9a060 : "rpc_s_unknown_reject",256    0x16c9a061 : "rpc_s_type_already_registered",257    0x16c9a062 : "rpc_s_stop_listening_disabled",258    0x16c9a063 : "rpc_s_invalid_arg",259    0x16c9a064 : "rpc_s_not_supported",260    0x16c9a065 : "rpc_s_wrong_kind_of_binding",261    0x16c9a066 : "rpc_s_authn_authz_mismatch",262    0x16c9a067 : "rpc_s_call_queued",263    0x16c9a068 : "rpc_s_cannot_set_nodelay",264    0x16c9a069 : "rpc_s_not_rpc_tower",265    0x16c9a06a : "rpc_s_invalid_rpc_protid",266    0x16c9a06b : "rpc_s_invalid_rpc_floor",267    0x16c9a06c : "rpc_s_call_timeout",268    0x16c9a06d : "rpc_s_mgmt_op_disallowed",269    0x16c9a06e : "rpc_s_manager_not_entered",270    0x16c9a06f : "rpc_s_calls_too_large_for_wk_ep",271    0x16c9a070 : "rpc_s_server_too_busy",272    0x16c9a071 : "rpc_s_prot_version_mismatch",273    0x16c9a072 : "rpc_s_rpc_prot_version_mismatch",274    0x16c9a073 : "rpc_s_ss_no_import_cursor",275    0x16c9a074 : "rpc_s_fault_addr_error",276    0x16c9a075 : "rpc_s_fault_context_mismatch",277    0x16c9a076 : "rpc_s_fault_fp_div_by_zero",278    0x16c9a077 : "rpc_s_fault_fp_error",279    0x16c9a078 : "rpc_s_fault_fp_overflow",280    0x16c9a079 : "rpc_s_fault_fp_underflow",281    0x16c9a07a : "rpc_s_fault_ill_inst",282    0x16c9a07b : "rpc_s_fault_int_div_by_zero",283    0x16c9a07c : "rpc_s_fault_int_overflow",284    0x16c9a07d : "rpc_s_fault_invalid_bound",285    0x16c9a07e : "rpc_s_fault_invalid_tag",286    0x16c9a07f : "rpc_s_fault_pipe_closed",287    0x16c9a080 : "rpc_s_fault_pipe_comm_error",288    0x16c9a081 : "rpc_s_fault_pipe_discipline",289    0x16c9a082 : "rpc_s_fault_pipe_empty",290    0x16c9a083 : "rpc_s_fault_pipe_memory",291    0x16c9a084 : "rpc_s_fault_pipe_order",292    0x16c9a085 : "rpc_s_fault_remote_comm_failure",293    0x16c9a086 : "rpc_s_fault_remote_no_memory",294    0x16c9a087 : "rpc_s_fault_unspec",295    0x16c9a088 : "uuid_s_bad_version",296    0x16c9a089 : "uuid_s_socket_failure",297    0x16c9a08a : "uuid_s_getconf_failure",298    0x16c9a08b : "uuid_s_no_address",299    0x16c9a08c : "uuid_s_overrun",300    0x16c9a08d : "uuid_s_internal_error",301    0x16c9a08e : "uuid_s_coding_error",302    0x16c9a08f : "uuid_s_invalid_string_uuid",303    0x16c9a090 : "uuid_s_no_memory",304    0x16c9a091 : "rpc_s_no_more_entries",305    0x16c9a092 : "rpc_s_unknown_ns_error",306    0x16c9a093 : "rpc_s_name_service_unavailable",307    0x16c9a094 : "rpc_s_incomplete_name",308    0x16c9a095 : "rpc_s_group_not_found",309    0x16c9a096 : "rpc_s_invalid_name_syntax",310    0x16c9a097 : "rpc_s_no_more_members",311    0x16c9a098 : "rpc_s_no_more_interfaces",312    0x16c9a099 : "rpc_s_invalid_name_service",313    0x16c9a09a : "rpc_s_no_name_mapping",314    0x16c9a09b : "rpc_s_profile_not_found",315    0x16c9a09c : "rpc_s_not_found",316    0x16c9a09d : "rpc_s_no_updates",317    0x16c9a09e : "rpc_s_update_failed",318    0x16c9a09f : "rpc_s_no_match_exported",319    0x16c9a0a0 : "rpc_s_entry_not_found",320    0x16c9a0a1 : "rpc_s_invalid_inquiry_context",321    0x16c9a0a2 : "rpc_s_interface_not_found",322    0x16c9a0a3 : "rpc_s_group_member_not_found",323    0x16c9a0a4 : "rpc_s_entry_already_exists",324    0x16c9a0a5 : "rpc_s_nsinit_failure",325    0x16c9a0a6 : "rpc_s_unsupported_name_syntax",326    0x16c9a0a7 : "rpc_s_no_more_elements",327    0x16c9a0a8 : "rpc_s_no_ns_permission",328    0x16c9a0a9 : "rpc_s_invalid_inquiry_type",329    0x16c9a0aa : "rpc_s_profile_element_not_found",330    0x16c9a0ab : "rpc_s_profile_element_replaced",331    0x16c9a0ac : "rpc_s_import_already_done",332    0x16c9a0ad : "rpc_s_database_busy",333    0x16c9a0ae : "rpc_s_invalid_import_context",334    0x16c9a0af : "rpc_s_uuid_set_not_found",335    0x16c9a0b0 : "rpc_s_uuid_member_not_found",336    0x16c9a0b1 : "rpc_s_no_interfaces_exported",337    0x16c9a0b2 : "rpc_s_tower_set_not_found",338    0x16c9a0b3 : "rpc_s_tower_member_not_found",339    0x16c9a0b4 : "rpc_s_obj_uuid_not_found",340    0x16c9a0b5 : "rpc_s_no_more_bindings",341    0x16c9a0b6 : "rpc_s_invalid_priority",342    0x16c9a0b7 : "rpc_s_not_rpc_entry",343    0x16c9a0b8 : "rpc_s_invalid_lookup_context",344    0x16c9a0b9 : "rpc_s_binding_vector_full",345    0x16c9a0ba : "rpc_s_cycle_detected",346    0x16c9a0bb : "rpc_s_nothing_to_export",347    0x16c9a0bc : "rpc_s_nothing_to_unexport",348    0x16c9a0bd : "rpc_s_invalid_vers_option",349    0x16c9a0be : "rpc_s_no_rpc_data",350    0x16c9a0bf : "rpc_s_mbr_picked",351    0x16c9a0c0 : "rpc_s_not_all_objs_unexported",352    0x16c9a0c1 : "rpc_s_no_entry_name",353    0x16c9a0c2 : "rpc_s_priority_group_done",354    0x16c9a0c3 : "rpc_s_partial_results",355    0x16c9a0c4 : "rpc_s_no_env_setup",356    0x16c9a0c5 : "twr_s_unknown_sa",357    0x16c9a0c6 : "twr_s_unknown_tower",358    0x16c9a0c7 : "twr_s_not_implemented",359    0x16c9a0c8 : "rpc_s_max_calls_too_small",360    0x16c9a0c9 : "rpc_s_cthread_create_failed",361    0x16c9a0ca : "rpc_s_cthread_pool_exists",362    0x16c9a0cb : "rpc_s_cthread_no_such_pool",363    0x16c9a0cc : "rpc_s_cthread_invoke_disabled",364    0x16c9a0cd : "ept_s_cant_perform_op",365    0x16c9a0ce : "ept_s_no_memory",366    0x16c9a0cf : "ept_s_database_invalid",367    0x16c9a0d0 : "ept_s_cant_create",368    0x16c9a0d1 : "ept_s_cant_access",369    0x16c9a0d2 : "ept_s_database_already_open",370    0x16c9a0d3 : "ept_s_invalid_entry",371    0x16c9a0d4 : "ept_s_update_failed",372    0x16c9a0d5 : "ept_s_invalid_context",373    0x16c9a0d6 : "ept_s_not_registered",374    0x16c9a0d7 : "ept_s_server_unavailable",375    0x16c9a0d8 : "rpc_s_underspecified_name",376    0x16c9a0d9 : "rpc_s_invalid_ns_handle",377    0x16c9a0da : "rpc_s_unknown_error",378    0x16c9a0db : "rpc_s_ss_char_trans_open_fail",379    0x16c9a0dc : "rpc_s_ss_char_trans_short_file",380    0x16c9a0dd : "rpc_s_ss_context_damaged",381    0x16c9a0de : "rpc_s_ss_in_null_context",382    0x16c9a0df : "rpc_s_socket_failure",383    0x16c9a0e0 : "rpc_s_unsupported_protect_level",384    0x16c9a0e1 : "rpc_s_invalid_checksum",385    0x16c9a0e2 : "rpc_s_invalid_credentials",386    0x16c9a0e3 : "rpc_s_credentials_too_large",387    0x16c9a0e4 : "rpc_s_call_id_not_found",388    0x16c9a0e5 : "rpc_s_key_id_not_found",389    0x16c9a0e6 : "rpc_s_auth_bad_integrity",390    0x16c9a0e7 : "rpc_s_auth_tkt_expired",391    0x16c9a0e8 : "rpc_s_auth_tkt_nyv",392    0x16c9a0e9 : "rpc_s_auth_repeat",393    0x16c9a0ea : "rpc_s_auth_not_us",394    0x16c9a0eb : "rpc_s_auth_badmatch",395    0x16c9a0ec : "rpc_s_auth_skew",396    0x16c9a0ed : "rpc_s_auth_badaddr",397    0x16c9a0ee : "rpc_s_auth_badversion",398    0x16c9a0ef : "rpc_s_auth_msg_type",399    0x16c9a0f0 : "rpc_s_auth_modified",400    0x16c9a0f1 : "rpc_s_auth_badorder",401    0x16c9a0f2 : "rpc_s_auth_badkeyver",402    0x16c9a0f3 : "rpc_s_auth_nokey",403    0x16c9a0f4 : "rpc_s_auth_mut_fail",404    0x16c9a0f5 : "rpc_s_auth_baddirection",405    0x16c9a0f6 : "rpc_s_auth_method",406    0x16c9a0f7 : "rpc_s_auth_badseq",407    0x16c9a0f8 : "rpc_s_auth_inapp_cksum",408    0x16c9a0f9 : "rpc_s_auth_field_toolong",409    0x16c9a0fa : "rpc_s_invalid_crc",410    0x16c9a0fb : "rpc_s_binding_incomplete",411    0x16c9a0fc : "rpc_s_key_func_not_allowed",412    0x16c9a0fd : "rpc_s_unknown_stub_rtl_if_vers",413    0x16c9a0fe : "rpc_s_unknown_ifspec_vers",414    0x16c9a0ff : "rpc_s_proto_unsupp_by_auth",415    0x16c9a100 : "rpc_s_authn_challenge_malformed",416    0x16c9a101 : "rpc_s_protect_level_mismatch",417    0x16c9a102 : "rpc_s_no_mepv",418    0x16c9a103 : "rpc_s_stub_protocol_error",419    0x16c9a104 : "rpc_s_class_version_mismatch",420    0x16c9a105 : "rpc_s_helper_not_running",421    0x16c9a106 : "rpc_s_helper_short_read",422    0x16c9a107 : "rpc_s_helper_catatonic",423    0x16c9a108 : "rpc_s_helper_aborted",424    0x16c9a109 : "rpc_s_not_in_kernel",425    0x16c9a10a : "rpc_s_helper_wrong_user",426    0x16c9a10b : "rpc_s_helper_overflow",427    0x16c9a10c : "rpc_s_dg_need_way_auth",428    0x16c9a10d : "rpc_s_unsupported_auth_subtype",429    0x16c9a10e : "rpc_s_wrong_pickle_type",430    0x16c9a10f : "rpc_s_not_listening",431    0x16c9a110 : "rpc_s_ss_bad_buffer",432    0x16c9a111 : "rpc_s_ss_bad_es_action",433    0x16c9a112 : "rpc_s_ss_wrong_es_version",434    0x16c9a113 : "rpc_s_fault_user_defined",435    0x16c9a114 : "rpc_s_ss_incompatible_codesets",436    0x16c9a115 : "rpc_s_tx_not_in_transaction",437    0x16c9a116 : "rpc_s_tx_open_failed",438    0x16c9a117 : "rpc_s_partial_credentials",439    0x16c9a118 : "rpc_s_ss_invalid_codeset_tag",440    0x16c9a119 : "rpc_s_mgmt_bad_type",441    0x16c9a11a : "rpc_s_ss_invalid_char_input",442    0x16c9a11b : "rpc_s_ss_short_conv_buffer",443    0x16c9a11c : "rpc_s_ss_iconv_error",444    0x16c9a11d : "rpc_s_ss_no_compat_codeset",445    0x16c9a11e : "rpc_s_ss_no_compat_charsets",446    0x16c9a11f : "dce_cs_c_ok",447    0x16c9a120 : "dce_cs_c_unknown",448    0x16c9a121 : "dce_cs_c_notfound",449    0x16c9a122 : "dce_cs_c_cannot_open_file",450    0x16c9a123 : "dce_cs_c_cannot_read_file",451    0x16c9a124 : "dce_cs_c_cannot_allocate_memory",452    0x16c9a125 : "rpc_s_ss_cleanup_failed",453    0x16c9a126 : "rpc_svc_desc_general",454    0x16c9a127 : "rpc_svc_desc_mutex",455    0x16c9a128 : "rpc_svc_desc_xmit",456    0x16c9a129 : "rpc_svc_desc_recv",457    0x16c9a12a : "rpc_svc_desc_dg_state",458    0x16c9a12b : "rpc_svc_desc_cancel",459    0x16c9a12c : "rpc_svc_desc_orphan",460    0x16c9a12d : "rpc_svc_desc_cn_state",461    0x16c9a12e : "rpc_svc_desc_cn_pkt",462    0x16c9a12f : "rpc_svc_desc_pkt_quotas",463    0x16c9a130 : "rpc_svc_desc_auth",464    0x16c9a131 : "rpc_svc_desc_source",465    0x16c9a132 : "rpc_svc_desc_stats",466    0x16c9a133 : "rpc_svc_desc_mem",467    0x16c9a134 : "rpc_svc_desc_mem_type",468    0x16c9a135 : "rpc_svc_desc_dg_pktlog",469    0x16c9a136 : "rpc_svc_desc_thread_id",470    0x16c9a137 : "rpc_svc_desc_timestamp",471    0x16c9a138 : "rpc_svc_desc_cn_errors",472    0x16c9a139 : "rpc_svc_desc_conv_thread",473    0x16c9a13a : "rpc_svc_desc_pid",474    0x16c9a13b : "rpc_svc_desc_atfork",475    0x16c9a13c : "rpc_svc_desc_cma_thread",476    0x16c9a13d : "rpc_svc_desc_inherit",477    0x16c9a13e : "rpc_svc_desc_dg_sockets",478    0x16c9a13f : "rpc_svc_desc_timer",479    0x16c9a140 : "rpc_svc_desc_threads",480    0x16c9a141 : "rpc_svc_desc_server_call",481    0x16c9a142 : "rpc_svc_desc_nsi",482    0x16c9a143 : "rpc_svc_desc_dg_pkt",483    0x16c9a144 : "rpc_m_cn_ill_state_trans_sa",484    0x16c9a145 : "rpc_m_cn_ill_state_trans_ca",485    0x16c9a146 : "rpc_m_cn_ill_state_trans_sg",486    0x16c9a147 : "rpc_m_cn_ill_state_trans_cg",487    0x16c9a148 : "rpc_m_cn_ill_state_trans_sr",488    0x16c9a149 : "rpc_m_cn_ill_state_trans_cr",489    0x16c9a14a : "rpc_m_bad_pkt_type",490    0x16c9a14b : "rpc_m_prot_mismatch",491    0x16c9a14c : "rpc_m_frag_toobig",492    0x16c9a14d : "rpc_m_unsupp_stub_rtl_if",493    0x16c9a14e : "rpc_m_unhandled_callstate",494    0x16c9a14f : "rpc_m_call_failed",495    0x16c9a150 : "rpc_m_call_failed_no_status",496    0x16c9a151 : "rpc_m_call_failed_errno",497    0x16c9a152 : "rpc_m_call_failed_s",498    0x16c9a153 : "rpc_m_call_failed_c",499    0x16c9a154 : "rpc_m_errmsg_toobig",500    0x16c9a155 : "rpc_m_invalid_srchattr",501    0x16c9a156 : "rpc_m_nts_not_found",502    0x16c9a157 : "rpc_m_invalid_accbytcnt",503    0x16c9a158 : "rpc_m_pre_v2_ifspec",504    0x16c9a159 : "rpc_m_unk_ifspec",505    0x16c9a15a : "rpc_m_recvbuf_toosmall",506    0x16c9a15b : "rpc_m_unalign_authtrl",507    0x16c9a15c : "rpc_m_unexpected_exc",508    0x16c9a15d : "rpc_m_no_stub_data",509    0x16c9a15e : "rpc_m_eventlist_full",510    0x16c9a15f : "rpc_m_unk_sock_type",511    0x16c9a160 : "rpc_m_unimp_call",512    0x16c9a161 : "rpc_m_invalid_seqnum",513    0x16c9a162 : "rpc_m_cant_create_uuid",514    0x16c9a163 : "rpc_m_pre_v2_ss",515    0x16c9a164 : "rpc_m_dgpkt_pool_corrupt",516    0x16c9a165 : "rpc_m_dgpkt_bad_free",517    0x16c9a166 : "rpc_m_lookaside_corrupt",518    0x16c9a167 : "rpc_m_alloc_fail",519    0x16c9a168 : "rpc_m_realloc_fail",520    0x16c9a169 : "rpc_m_cant_open_file",521    0x16c9a16a : "rpc_m_cant_read_addr",522    0x16c9a16b : "rpc_svc_desc_libidl",523    0x16c9a16c : "rpc_m_ctxrundown_nomem",524    0x16c9a16d : "rpc_m_ctxrundown_exc",525    0x16c9a16e : "rpc_s_fault_codeset_conv_error",526    0x16c9a16f : "rpc_s_no_call_active",527    0x16c9a170 : "rpc_s_cannot_support",528    0x16c9a171 : "rpc_s_no_context_available",529}530class DCERPCException(Exception):531    """532    This is the exception every client should catch regardless of the underlying533    DCERPC Transport used.534    """535    def __init__(self, error_string=None, error_code=None, packet=None):536        """537        :param string error_string: A string you want to show explaining the exception. Otherwise the default ones will be used538        :param integer error_code: the error_code if we're using a dictionary with error's descriptions539        :param NDR packet: if successfully decoded, the NDR packet of the response call. This could probably have useful540        information541        """542        Exception.__init__(self)543        self.packet = packet544        self.error_string = error_string545        if packet is not None:546            try:547                self.error_code = packet['ErrorCode']548            except:549                self.error_code = error_code550        else:551            self.error_code = error_code552    def get_error_code( self ):553        return self.error_code554 555    def get_packet( self ):556        return self.packet557    def __str__( self ):558        key = self.error_code559        if self.error_string is not None:560            return self.error_string561        if key in rpc_status_codes:562            error_msg_short = rpc_status_codes[key]563            return 'DCERPC Runtime Error: code: 0x%x - %s ' % (self.error_code, error_msg_short)564        else:565            return 'DCERPC Runtime Error: unknown error code: 0x%x' % self.error_code566# Context Item567class CtxItem(Structure):568    structure = (569        ('ContextID','<H=0'),570        ('TransItems','B=0'),571        ('Pad','B=0'),572        ('AbstractSyntax','20s=""'),573        ('TransferSyntax','20s=""'),574    )575class CtxItemResult(Structure):576    structure = (577        ('Result','<H=0'),578        ('Reason','<H=0'),579        ('TransferSyntax','20s=""'),580    )581class SEC_TRAILER(Structure):582    commonHdr = (583        ('auth_type', 'B=10'),584        ('auth_level','B=0'),585        ('auth_pad_len','B=0'),586        ('auth_rsvrd','B=0'),587        ('auth_ctx_id','<L=747920'),588    )589class MSRPCHeader(Structure):590    _SIZE = 16591    commonHdr = ( 592        ('ver_major','B=5'),                              # 0593        ('ver_minor','B=0'),                              # 1594        ('type','B=0'),                                   # 2595        ('flags','B=0'),                                  # 3596        ('representation','<L=0x10'),                     # 4597        ('frag_len','<H=self._SIZE+len(auth_data)+(16 if (self["flags"] & 0x80) > 0 else 0)+len(pduData)+len(pad)+len(sec_trailer)'),  # 8598        ('auth_len','<H=len(auth_data)'),                 # 10599        ('call_id','<L=1'),                               # 12    <-- Common up to here (including this)600    )601    structure = ( 602        ('dataLen','_-pduData','self["frag_len"]-self["auth_len"]-self._SIZE-(8 if self["auth_len"] > 0 else 0)'),603        ('pduData',':'),                                604        ('_pad', '_-pad','(4 - ((self._SIZE + (16 if (self["flags"] & 0x80) > 0 else 0) + len(self["pduData"])) & 3) & 3)'),605        ('pad', ':'),606        ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'),607        ('sec_trailer',':'),608        ('auth_dataLen','_-auth_data','self["auth_len"]'),609        ('auth_data',':'),610    )611    def __init__(self, data = None, alignment = 0):612        Structure.__init__(self,data, alignment)613        if data is None:614            self['ver_major'] = 5615            self['ver_minor'] = 0616            self['flags'] = PFC_FIRST_FRAG | PFC_LAST_FRAG617            self['type'] = MSRPC_REQUEST618            self.__frag_len_set = 0619            self['auth_len'] = 0620            self['pduData'] = b''621            self['auth_data'] = b''622            self['sec_trailer'] = b''623            self['pad'] = b''624    def get_header_size(self):625        return self._SIZE + (16 if (self["flags"] & PFC_OBJECT_UUID) > 0 else 0)626    def get_packet(self):627        if self['auth_data'] != b'':628            self['auth_len'] = len(self['auth_data'])629        # The sec_trailer structure MUST be 4-byte aligned with respect to 630        # the beginning of the PDU. Padding octets MUST be used to align the 631        # sec_trailer structure if its natural beginning is not already 4-byte aligned632        ##self['pad'] = '\xAA' * (4 - ((self._SIZE + len(self['pduData'])) & 3) & 3)633        return self.getData()634class MSRPCRequestHeader(MSRPCHeader):635    _SIZE = 24636    commonHdr = MSRPCHeader.commonHdr + ( 637        ('alloc_hint','<L=0'),                            # 16638        ('ctx_id','<H=0'),                                # 20639        ('op_num','<H=0'),                                # 22640        ('_uuid','_-uuid','16 if self["flags"] & 0x80 > 0 else 0' ), # 22641        ('uuid',':'),                                # 22642    )643    def __init__(self, data = None, alignment = 0):644        MSRPCHeader.__init__(self, data, alignment)645        if data is None:646           self['type'] = MSRPC_REQUEST647           self['ctx_id'] = 0648           self['uuid'] = b''649class MSRPCRespHeader(MSRPCHeader):650    _SIZE = 24651    commonHdr = MSRPCHeader.commonHdr + ( 652        ('alloc_hint','<L=0'),                          # 16   653        ('ctx_id','<H=0'),                              # 20654        ('cancel_count','<B=0'),                        # 22655        ('padding','<B=0'),                             # 23656    )657    def __init__(self, aBuffer = None, alignment = 0):658        MSRPCHeader.__init__(self, aBuffer, alignment)659        if aBuffer is None:660            self['type'] = MSRPC_RESPONSE661            self['ctx_id'] = 0662class MSRPCBind(Structure):663    _CTX_ITEM_LEN = len(CtxItem())664    structure = ( 665        ('max_tfrag','<H=4280'),666        ('max_rfrag','<H=4280'),667        ('assoc_group','<L=0'),668        ('ctx_num','B=0'),669        ('Reserved','B=0'),670        ('Reserved2','<H=0'),671        ('_ctx_items', '_-ctx_items', 'self["ctx_num"]*self._CTX_ITEM_LEN'),672        ('ctx_items',':'),673    )674 675    def __init__(self, data = None, alignment = 0):676        Structure.__init__(self, data, alignment)677        if data is None:678            self['max_tfrag'] = 4280679            self['max_rfrag'] = 4280680            self['assoc_group'] = 0681            self['ctx_num'] = 1682            self['ctx_items'] = b''683        self.__ctx_items = []684    def addCtxItem(self, item):685        self.__ctx_items.append(item)686    687    def getData(self):688        self['ctx_num'] = len(self.__ctx_items)689        for i in self.__ctx_items:690            self['ctx_items'] += i.getData()691        return Structure.getData(self)692class MSRPCBindAck(MSRPCHeader):693    _SIZE = 26 # Up to SecondaryAddr694    _CTX_ITEM_LEN = len(CtxItemResult())695    structure = ( 696        ('max_tfrag','<H=0'),697        ('max_rfrag','<H=0'),698        ('assoc_group','<L=0'),699        ('SecondaryAddrLen','<H&SecondaryAddr'), 700        ('SecondaryAddr','z'),                          # Optional if SecondaryAddrLen == 0701        ('PadLen','_-Pad','(4-((self["SecondaryAddrLen"]+self._SIZE) % 4))%4'),702        ('Pad',':'),703        ('ctx_num','B=0'),704        ('Reserved','B=0'),705        ('Reserved2','<H=0'),706        ('_ctx_items','_-ctx_items','self["ctx_num"]*self._CTX_ITEM_LEN'),707        ('ctx_items',':'),708        ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'),709        ('sec_trailer',':'),710        ('auth_dataLen','_-auth_data','self["auth_len"]'),711        ('auth_data',':'),712    )713    def __init__(self, data = None, alignment = 0):714        self.__ctx_items = []715        MSRPCHeader.__init__(self,data,alignment)716        if data is None:717            self['Pad'] = b''718            self['ctx_items'] = b''719            self['sec_trailer'] = b''720            self['auth_data'] = b''721    def getCtxItems(self):722        return self.__ctx_items723    def getCtxItem(self,index):724        return self.__ctx_items[index-1]725    def fromString(self, data):726        Structure.fromString(self,data)727        # Parse the ctx_items728        data = self['ctx_items']729        for i in range(self['ctx_num']):730            item = CtxItemResult(data)731            self.__ctx_items.append(item)732            data = data[len(item):]733            734class MSRPCBindNak(Structure):735    structure = ( 736        ('RejectedReason','<H=0'),737        ('SupportedVersions',':'),738    )739    def __init__(self, data = None, alignment = 0):740        Structure.__init__(self,data,alignment)741        if data is None:742            self['SupportedVersions'] = b''743class DCERPC:744    # Standard NDR Representation745    NDRSyntax   = uuidtup_to_bin(('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0'))746    # NDR 64747    NDR64Syntax = uuidtup_to_bin(('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0'))748    transfer_syntax =  NDRSyntax749    def __init__(self,transport):750        self._transport = transport751        self.set_ctx_id(0)752        self._max_user_frag = None753        self.set_default_max_fragment_size()754        self._ctx = None755    def get_rpc_transport(self):756        return self._transport757    def set_ctx_id(self, ctx_id):758        self._ctx = ctx_id759    def connect(self):760        return self._transport.connect()761    def disconnect(self):762        return self._transport.disconnect()763    def set_max_fragment_size(self, fragment_size):764        # -1 is default fragment size: 0 for v5, 1300 y pico for v4765        #  0 is don't fragment766        #    other values are max fragment size767        if fragment_size == -1:768            self.set_default_max_fragment_size()769        else:770            self._max_user_frag = fragment_size771    def set_default_max_fragment_size(self):772        # default is 0: don'fragment. v4 will override this method773        self._max_user_frag = 0774    def send(self, data):775        raise RuntimeError ('virtual method. Not implemented in subclass')776    def recv(self):777        raise RuntimeError ('virtual method. Not implemented in subclass')778    def alter_ctx(self, newUID, bogus_binds=''):779        raise RuntimeError ('virtual method. Not implemented in subclass')780    def set_credentials(self, username, password, domain='', lmhash='', nthash='', aesKey='', TGT=None, TGS=None):781        pass782    def set_auth_level(self, auth_level):783        pass784    def set_auth_type(self, auth_type, callback=None):785        pass786    def get_idempotent(self):787        return 0788    def set_idempotent(self, flag):789        pass790    def call(self, function, body, uuid=None):791        if hasattr(body, 'getData'):792            return self.send(DCERPC_RawCall(function, body.getData(), uuid))793        else:794            return self.send(DCERPC_RawCall(function, body, uuid))795    def request(self, request, uuid=None, checkError=True):796        if self.transfer_syntax == self.NDR64Syntax:797            request.changeTransferSyntax(self.NDR64Syntax)798            isNDR64 = True799        else:800            isNDR64 = False801        self.call(request.opnum, request, uuid)802        answer = self.recv()803        __import__(request.__module__)804        module = sys.modules[request.__module__]805        respClass = getattr(module, request.__class__.__name__ + 'Response')806        if  answer[-4:] != b'\x00\x00\x00\x00' and checkError is True:807            error_code = unpack('<L', answer[-4:])[0]808            if error_code in rpc_status_codes:809                # This is an error we can handle810                exception = DCERPCException(error_code = error_code)811            else:    812                sessionErrorClass = getattr(module, 'DCERPCSessionError')813                try:814                    # Try to unpack the answer, even if it is an error, it works most of the times815                    response =  respClass(answer, isNDR64 = isNDR64)816                except:817                    # No luck :(818                    exception = sessionErrorClass(error_code = error_code)819                else:820                    exception = sessionErrorClass(packet = response, error_code = error_code)821            raise exception822        else:823            response =  respClass(answer, isNDR64 = isNDR64)824            return response825class DCERPC_v4(DCERPC):826    pass827class DCERPC_v5(DCERPC):828    def __init__(self, transport):829        DCERPC.__init__(self, transport)830        self.__auth_level = RPC_C_AUTHN_LEVEL_NONE831        self.__auth_type = RPC_C_AUTHN_WINNT832        self.__auth_type_callback = None833        # Flags of the authenticated session. We will need them throughout the connection834        self.__auth_flags = 0835        self.__username = None836        self.__password = None837        self.__domain = ''838        self.__lmhash = ''839        self.__nthash = ''840        self.__aesKey = ''841        self.__TGT    = None842        self.__TGS    = None843        844        self.__clientSigningKey = b''845        self.__serverSigningKey = b''846        self.__clientSealingKey = b''847        self.__clientSealingHandle = b''848        self.__serverSealingKey = b''849        self.__serverSealingHandle = b''850        self.__sequence = 0   851        self.transfer_syntax = uuidtup_to_bin(('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0'))852        self.__callid = 1853        self._ctx = 0854        self.__sessionKey = None855        self.__max_xmit_size  = 0856        self.__flags = 0857        self.__cipher = None858        self.__confounder = b''859        self.__gss = None860    def set_session_key(self, session_key):861        self.__sessionKey = session_key862    def get_session_key(self):863        return self.__sessionKey864    def set_auth_level(self, auth_level):865        self.__auth_level = auth_level866    def set_auth_type(self, auth_type, callback = None):867        self.__auth_type = auth_type868        self.__auth_type_callback = callback869    def get_auth_type(self):870        return self.__auth_type871    def set_max_tfrag(self, size):872        self.__max_xmit_size = size873    874    def get_credentials(self):875        return self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS876    def set_credentials(self, username, password, domain = '', lmhash = '', nthash = '', aesKey = '', TGT = None, TGS = None):877        self.set_auth_level(RPC_C_AUTHN_LEVEL_CONNECT)878        self.__username = username879        self.__password = password880        self.__domain   = domain881        self.__aesKey   = aesKey882        self.__TGT      = TGT883        self.__TGS      = TGS884        if lmhash != '' or nthash != '':885            if len(lmhash) % 2:886                lmhash = '0%s' % lmhash887            if len(nthash) % 2:888                nthash = '0%s' % nthash889            try: # just in case they were converted already890                self.__lmhash = unhexlify(lmhash)891                self.__nthash = unhexlify(nthash)892            except:893                self.__lmhash = lmhash894                self.__nthash = nthash895                pass896    def bind(self, iface_uuid, alter = 0, bogus_binds = 0, transfer_syntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')):897        bind = MSRPCBind()898        #item['TransferSyntax']['Version'] = 1899        ctx = self._ctx900        for i in range(bogus_binds):901            item = CtxItem()902            item['ContextID'] = ctx903            item['TransItems'] = 1904            item['ContextID'] = ctx905            # We generate random UUIDs for bogus binds906            item['AbstractSyntax'] = generate() + stringver_to_bin('2.0')907            item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax)908            bind.addCtxItem(item)909            self._ctx += 1910            ctx += 1911        # The true one :)912        item = CtxItem()913        item['AbstractSyntax'] = iface_uuid914        item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax)915        item['ContextID'] = ctx916        item['TransItems'] = 1917        bind.addCtxItem(item)918        packet = MSRPCHeader()919        packet['type'] = MSRPC_BIND920        packet['pduData'] = bind.getData()921        packet['call_id'] = self.__callid922        if alter:923            packet['type'] = MSRPC_ALTERCTX924        if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:925            if (self.__username is None) or (self.__password is None):926                self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS = self._transport.get_credentials()927            if self.__auth_type == RPC_C_AUTHN_WINNT:928                auth = ntlm.getNTLMSSPType1('', '', signingRequired=True,929                                            use_ntlmv2=self._transport.doesSupportNTLMv2())930            elif self.__auth_type == RPC_C_AUTHN_NETLOGON:931                from impacket.dcerpc.v5 import nrpc932                auth = nrpc.getSSPType1(self.__username[:-1], self.__domain, signingRequired=True)933            elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:934                self.__cipher, self.__sessionKey, auth = kerberosv5.getKerberosType1(self.__username, self.__password,935                                                                                     self.__domain, self.__lmhash,936                                                                                     self.__nthash, self.__aesKey,937                                                                                     self.__TGT, self.__TGS,938                                                                                     self._transport.getRemoteName(),939                                                                                     self._transport.get_kdcHost())940            else:941                raise DCERPCException('Unsupported auth_type 0x%x' % self.__auth_type)942            sec_trailer = SEC_TRAILER()943            sec_trailer['auth_type']   = self.__auth_type944            sec_trailer['auth_level']  = self.__auth_level945            sec_trailer['auth_ctx_id'] = self._ctx + 79231 946            pad = (4 - (len(packet.get_packet()) % 4)) % 4947            if pad != 0:948               packet['pduData'] += b'\xFF'*pad949               sec_trailer['auth_pad_len']=pad950            packet['sec_trailer'] = sec_trailer951            packet['auth_data'] = auth952        self._transport.send(packet.get_packet())953        s = self._transport.recv()954        if s != 0:955            resp = MSRPCHeader(s)956        else:957            return 0 #mmm why not None?958        if resp['type'] == MSRPC_BINDACK or resp['type'] == MSRPC_ALTERCTX_R:959            bindResp = MSRPCBindAck(resp.getData())960        elif resp['type'] == MSRPC_BINDNAK or resp['type'] == MSRPC_FAULT:961            if resp['type'] == MSRPC_FAULT:962                resp = MSRPCRespHeader(resp.getData())963                status_code = unpack('<L', resp['pduData'][:4])[0]964            else:965                resp = MSRPCBindNak(resp['pduData'])966                status_code = resp['RejectedReason']967            if status_code in rpc_status_codes:968                raise DCERPCException(error_code = status_code)969            elif status_code in rpc_provider_reason:970                raise DCERPCException("Bind context rejected: %s" % rpc_provider_reason[status_code])971            else:972                raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code)973        else:974            raise DCERPCException('Unknown DCE RPC packet type received: %d' % resp['type'])975        # check ack results for each context, except for the bogus ones976        for ctx in range(bogus_binds+1,bindResp['ctx_num']+1):977            ctxItems = bindResp.getCtxItem(ctx)978            if ctxItems['Result'] != 0:979                msg = "Bind context %d rejected: " % ctx980                msg += rpc_cont_def_result.get(ctxItems['Result'], 'Unknown DCE RPC context result code: %.4x' % ctxItems['Result'])981                msg += "; "982                reason = bindResp.getCtxItem(ctx)['Reason']983                msg += rpc_provider_reason.get(reason, 'Unknown reason code: %.4x' % reason)984                if (ctxItems['Result'], reason) == (2, 1): # provider_rejection, abstract syntax not supported985                    msg += " (this usually means the interface isn't listening on the given endpoint)"986                raise DCERPCException(msg)987            # Save the transfer syntax for later use988            self.transfer_syntax = ctxItems['TransferSyntax'] 989        # The received transmit size becomes the client's receive size, and the received receive size becomes the client's transmit size.990        self.__max_xmit_size = bindResp['max_rfrag']991        if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:992            if self.__auth_type == RPC_C_AUTHN_WINNT:993                response, self.__sessionKey = ntlm.getNTLMSSPType3(auth, bindResp['auth_data'], self.__username,994                                                                   self.__password, self.__domain, self.__lmhash,995                                                                   self.__nthash,996                                                                   use_ntlmv2=self._transport.doesSupportNTLMv2())997                self.__flags = response['flags']998            elif self.__auth_type == RPC_C_AUTHN_NETLOGON:999                response = None1000            elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:1001                self.__cipher, self.__sessionKey, response = kerberosv5.getKerberosType3(self.__cipher,1002                                                                                         self.__sessionKey,1003                                                                                         bindResp['auth_data'])1004            self.__sequence = 01005            if self.__auth_level in (RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY):1006                if self.__auth_type == RPC_C_AUTHN_WINNT:1007                    if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:1008                        self.__clientSigningKey = ntlm.SIGNKEY(self.__flags, self.__sessionKey)1009                        self.__serverSigningKey = ntlm.SIGNKEY(self.__flags, self.__sessionKey,b"Server")1010                        self.__clientSealingKey = ntlm.SEALKEY(self.__flags, self.__sessionKey)1011                        self.__serverSealingKey = ntlm.SEALKEY(self.__flags, self.__sessionKey,b"Server")1012                        # Preparing the keys handle states1013                        cipher3 = ARC4.new(self.__clientSealingKey)1014                        self.__clientSealingHandle = cipher3.encrypt1015                        cipher4 = ARC4.new(self.__serverSealingKey)1016                        self.__serverSealingHandle = cipher4.encrypt1017                    else:1018                        # Same key for everything1019                        self.__clientSigningKey = self.__sessionKey1020                        self.__serverSigningKey = self.__sessionKey1021                        self.__clientSealingKey = self.__sessionKey1022                        self.__serverSealingKey = self.__sessionKey1023                        cipher = ARC4.new(self.__clientSigningKey)1024                        self.__clientSealingHandle = cipher.encrypt1025                        self.__serverSealingHandle = cipher.encrypt1026                elif self.__auth_type == RPC_C_AUTHN_NETLOGON:1027                    if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:1028                        self.__confounder = b''1029                    else:1030                        self.__confounder = b'12345678'1031            sec_trailer = SEC_TRAILER()1032            sec_trailer['auth_type'] = self.__auth_type1033            sec_trailer['auth_level'] = self.__auth_level1034            sec_trailer['auth_ctx_id'] = self._ctx + 79231 1035            if response is not None:1036                if self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:1037                    alter_ctx = MSRPCHeader()1038                    alter_ctx['type'] = MSRPC_ALTERCTX1039                    alter_ctx['pduData'] = bind.getData()1040                    alter_ctx['sec_trailer'] = sec_trailer1041                    alter_ctx['auth_data'] = response1042                    self._transport.send(alter_ctx.get_packet(), forceWriteAndx = 1)1043                    self.__gss = gssapi.GSSAPI(self.__cipher)1044                    self.__sequence = 01045                    self.recv()1046                    self.__sequence = 01047                else:1048                    auth3 = MSRPCHeader()1049                    auth3['type'] = MSRPC_AUTH31050                    # pad (4 bytes): Can be set to any arbitrary value when set and MUST be 1051                    # ignored on receipt. The pad field MUST be immediately followed by a 1052                    # sec_trailer structure whose layout, location, and alignment are as 1053                    # specified in section 2.2.2.111054                    auth3['pduData'] = b'    '1055                    auth3['sec_trailer'] = sec_trailer1056                    auth3['auth_data'] = response.getData()1057                    # Use the same call_id1058                    self.__callid = resp['call_id']1059                    auth3['call_id'] = self.__callid1060                    self._transport.send(auth3.get_packet(), forceWriteAndx = 1)1061            self.__callid += 11062        return resp     # means packet is signed, if verifier is wrong it fails1063    def _transport_send(self, rpc_packet, forceWriteAndx = 0, forceRecv = 0):1064        rpc_packet['ctx_id'] = self._ctx1065        rpc_packet['sec_trailer'] = b''1066        rpc_packet['auth_data'] = b''1067        if self.__auth_level in [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY]:1068            # Dummy verifier, just for the calculations1069            sec_trailer = SEC_TRAILER()1070            sec_trailer['auth_type'] = self.__auth_type1071            sec_trailer['auth_level'] = self.__auth_level1072            sec_trailer['auth_pad_len'] = 01073            sec_trailer['auth_ctx_id'] = self._ctx + 79231 1074            pad = (4 - (len(rpc_packet.get_packet()) % 4)) % 41075            if pad != 0:1076                rpc_packet['pduData'] += b'\xBB'*pad1077                sec_trailer['auth_pad_len']=pad1078            rpc_packet['sec_trailer'] = sec_trailer.getData()1079            rpc_packet['auth_data'] = b' '*161080            plain_data = rpc_packet['pduData']1081            if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY:1082                if self.__auth_type == RPC_C_AUTHN_WINNT:1083                    if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:1084                        # When NTLM2 is on, we sign the whole pdu, but encrypt just1085                        # the data, not the dcerpc header. Weird..1086                        sealedMessage, signature =  ntlm.SEAL(self.__flags, 1087                               self.__clientSigningKey, 1088                               self.__clientSealingKey,  1089                               rpc_packet.get_packet()[:-16], 1090                               plain_data, 1091                               self.__sequence, 1092                               self.__clientSealingHandle)1093                    else:1094                        sealedMessage, signature =  ntlm.SEAL(self.__flags, 1095                               self.__clientSigningKey, 1096                               self.__clientSealingKey,  1097                               plain_data, 1098                               plain_data, 1099                               self.__sequence, 1100                               self.__clientSealingHandle)1101                elif self.__auth_type == RPC_C_AUTHN_NETLOGON:1102                    from impacket.dcerpc.v5 import nrpc1103                    sealedMessage, signature = nrpc.SEAL(plain_data, self.__confounder, self.__sequence, self.__sessionKey, False)1104                elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:1105                    sealedMessage, signature = self.__gss.GSS_Wrap(self.__sessionKey, plain_data, self.__sequence)1106                rpc_packet['pduData'] = sealedMessage1107            elif self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: 1108                if self.__auth_type == RPC_C_AUTHN_WINNT:1109                    if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:1110                        # Interesting thing.. with NTLM2, what is is signed is the 1111                        # whole PDU, not just the data1112                        signature =  ntlm.SIGN(self.__flags,1113                               self.__clientSigningKey, 1114                               rpc_packet.get_packet()[:-16], 1115                               self.__sequence, 1116                               self.__clientSealingHandle)1117                    else:1118                        signature =  ntlm.SIGN(self.__flags, 1119                               self.__clientSigningKey, 1120                               plain_data, 1121                               self.__sequence, 1122                               self.__clientSealingHandle)1123                elif self.__auth_type == RPC_C_AUTHN_NETLOGON:1124                    from impacket.dcerpc.v5 import nrpc1125                    signature = nrpc.SIGN(plain_data, 1126                           self.__confounder, 1127                           self.__sequence, 1128                           self.__sessionKey, 1129                           False)1130                elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:1131                    signature = self.__gss.GSS_GetMIC(self.__sessionKey, plain_data, self.__sequence)1132            rpc_packet['sec_trailer'] = sec_trailer.getData()1133            rpc_packet['auth_data'] = signature1134            self.__sequence += 11135        self._transport.send(rpc_packet.get_packet(), forceWriteAndx = forceWriteAndx, forceRecv = forceRecv)1136    def send(self, data):1137        if isinstance(data, MSRPCHeader) is not True:1138            # Must be an Impacket, transform to structure1139            data = DCERPC_RawCall(data.OP_NUM, data.get_packet())1140        try:1141            if data['uuid'] != b'':1142                data['flags'] |= PFC_OBJECT_UUID1143        except:1144            # Structure doesn't have uuid1145            pass1146        data['ctx_id'] = self._ctx1147        data['call_id'] = self.__callid1148        data['alloc_hint'] = len(data['pduData'])1149        # We should fragment PDUs if:1150        # 1) Payload exceeds __max_xmit_size received during BIND response1151        # 2) We'e explicitly fragmenting packets with lower values1152        should_fragment = False1153        # Let's decide what will drive fragmentation for this request1154        if self._max_user_frag > 0:1155            # User set a frag size, let's compare it with the max transmit size agreed when binding the interface1156            fragment_size = min(self._max_user_frag, self.__max_xmit_size)1157        else:1158            fragment_size = self.__max_xmit_size1159        # Sanity check. Fragmentation can't be too low, otherwise sec_trailer won't fit1160        if self.__auth_level in [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY]:1161            if fragment_size <= 8:1162                # Minimum pdu fragment size is 8, important when doing PKT_INTEGRITY/PRIVACY. We need a minimum size of 81163                # (Kerberos)1164                fragment_size = 81165        # ToDo: Better calculate the size needed. Now I'm setting a number that surely is enough for Kerberos and NTLM1166        # ToDo: trailers, both for INTEGRITY and PRIVACY. This means we're not truly honoring the user's frag request.1167        if len(data['pduData']) + 128 > fragment_size:1168            should_fragment = True1169            if fragment_size+128 > self.__max_xmit_size:1170                fragment_size = self.__max_xmit_size - 1281171        if should_fragment:1172            packet = data['pduData']1173            offset = 01174            while 1:1175                toSend = packet[offset:offset+fragment_size]1176                if not toSend:1177                    break1178                if offset == 0:1179                    data['flags'] |= PFC_FIRST_FRAG1180                else:1181                    data['flags'] &= (~PFC_FIRST_FRAG)1182                offset += len(toSend)1183                if offset >= len(packet):1184                    data['flags'] |= PFC_LAST_FRAG1185                else:1186                    data['flags'] &= (~PFC_LAST_FRAG)1187                data['pduData'] = toSend1188                self._transport_send(data, forceWriteAndx = 1, forceRecv =data['flags'] & PFC_LAST_FRAG)1189        else:1190            self._transport_send(data)1191        self.__callid += 11192    def recv(self):1193        finished = False1194        forceRecv = 01195        retAnswer = b''1196        while not finished:1197            # At least give me the MSRPCRespHeader, especially important for 1198            # TCP/UDP Transports1199            response_data = self._transport.recv(forceRecv, count=MSRPCRespHeader._SIZE)1200            response_header = MSRPCRespHeader(response_data)1201            # Ok, there might be situation, especially with large packets, that 1202            # the transport layer didn't send us the full packet's contents1203            # So we gotta check we received it all1204            while len(response_data) < response_header['frag_len']:1205               response_data += self._transport.recv(forceRecv, count=(response_header['frag_len']-len(response_data)))1206            off = response_header.get_header_size()1207            if response_header['type'] == MSRPC_FAULT and response_header['frag_len'] >= off+4:1208                status_code = unpack("<L",response_data[off:off+4])[0]1209                if status_code in rpc_status_codes:1210                    raise DCERPCException(rpc_status_codes[status_code])1211                elif status_code & 0xffff in rpc_status_codes:1212                    raise DCERPCException(rpc_status_codes[status_code & 0xffff])1213                else:1214                    if status_code in hresult_errors.ERROR_MESSAGES:1215                        error_msg_short = hresult_errors.ERROR_MESSAGES[status_code][0]1216                        error_msg_verbose = hresult_errors.ERROR_MESSAGES[status_code][1] 1217                        raise DCERPCException('%s - %s' % (error_msg_short, error_msg_verbose))1218                    else:1219                        raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code)1220            if response_header['flags'] & PFC_LAST_FRAG:1221                # No need to reassembly DCERPC1222                finished = True1223            else:1224                # Forcing Read Recv, we need more packets!1225                forceRecv = 11226            answer = response_data[off:]1227            auth_len = response_header['auth_len']1228            if auth_len:1229                auth_len += 81230                auth_data = answer[-auth_len:]1231                sec_trailer = SEC_TRAILER(data = auth_data)1232                answer = answer[:-auth_len]1233                if sec_trailer['auth_level'] == RPC_C_AUTHN_LEVEL_PKT_PRIVACY:1234                    if self.__auth_type == RPC_C_AUTHN_WINNT:1235                        if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:1236                            # TODO: FIX THIS, it's not calculating the signature well1237                            # Since I'm not testing it we don't care... yet1238                            answer, signature =  ntlm.SEAL(self.__flags, 1239                                    self.__serverSigningKey, 1240                                    self.__serverSealingKey,  1241                                    answer, 1242                                    answer, 1243                                    self.__sequence, 1244                                    self.__serverSealingHandle)1245                        else:1246                            answer, signature = ntlm.SEAL(self.__flags, 1247                                    self.__serverSigningKey, 1248                                    self.__serverSealingKey, 1249                                    answer, 1250                                    answer, 1251                                    self.__sequence, 1252                                    self.__serverSealingHandle)1253                            self.__sequence += 11254                    elif self.__auth_type == RPC_C_AUTHN_NETLOGON:1255                        from impacket.dcerpc.v5 import nrpc1256                        answer, cfounder = nrpc.UNSEAL(answer, 1257                               auth_data[len(sec_trailer):],1258                               self.__sessionKey, 1259                               False)1260                        self.__sequence += 11261                    elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:1262                        if self.__sequence > 0:1263                            answer, cfounder = self.__gss.GSS_Unwrap(self.__sessionKey, answer, self.__sequence,1264                                                                     direction='init', authData=auth_data)1265                elif sec_trailer['auth_level'] == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:1266                    if self.__auth_type == RPC_C_AUTHN_WINNT:1267                        ntlmssp = auth_data[12:]1268                        if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:1269                            signature =  ntlm.SIGN(self.__flags, 1270                                    self.__serverSigningKey, 1271                                    answer, 1272                                    self.__sequence, 1273                                    self.__serverSealingHandle)1274                        else:1275                            signature = ntlm.SIGN(self.__flags, 1276                                    self.__serverSigningKey, 1277                                    ntlmssp, 1278                                    self.__sequence, 1279                                    self.__serverSealingHandle)1280                            # Yes.. NTLM2 doesn't increment sequence when receiving1281                            # the packet :P1282                            self.__sequence += 11283                    elif self.__auth_type == RPC_C_AUTHN_NETLOGON:1284                        from impacket.dcerpc.v5 import nrpc1285                        ntlmssp = auth_data[12:]1286                        signature = nrpc.SIGN(ntlmssp, 1287                               self.__confounder, 1288                               self.__sequence, 1289                               self.__sessionKey, 1290                               False)1291                        self.__sequence += 11292                    elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:1293                        # Do NOT increment the sequence number when Signing Kerberos1294                        #self.__sequence += 11295                        pass1296                1297                if sec_trailer['auth_pad_len']:1298                    answer = answer[:-sec_trailer['auth_pad_len']]1299              1300            retAnswer += answer1301        return retAnswer1302    def alter_ctx(self, newUID, bogus_binds = 0):1303        answer = self.__class__(self._transport)1304        answer.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash,1305                               self.__aesKey, self.__TGT, self.__TGS)1306        answer.set_auth_type(self.__auth_type)1307        answer.set_auth_level(self.__auth_level)1308        answer.set_ctx_id(self._ctx+1)1309        answer.__callid = self.__callid1310        answer.bind(newUID, alter = 1, bogus_binds = bogus_binds, transfer_syntax = bin_to_uuidtup(self.transfer_syntax))1311        return answer1312class DCERPC_RawCall(MSRPCRequestHeader):1313    def __init__(self, op_num, data = b'', uuid=None):1314        MSRPCRequestHeader.__init__(self)1315        self['op_num'] = op_num1316        self['pduData'] = data1317        if uuid is not None:1318            self['flags'] |= PFC_OBJECT_UUID1319            self['uuid'] = uuid1320    def setData(self, data):1321        self['pduData'] = data1322# 2.2.6 Type Serialization Version 11323class CommonHeader(NDRSTRUCT):1324    structure = (1325        ('Version', UCHAR),1326        ('Endianness', UCHAR),1327        ('CommonHeaderLength', USHORT),1328        ('Filler', ULONG),1329    )1330    def __init__(self, data = None,isNDR64 = False):1331        NDRSTRUCT.__init__(self, data, isNDR64)1332        if data is None:1333            self['Version'] = 11334            self['Endianness'] = 0x101335            self['CommonHeaderLength'] = 81336            self['Filler'] = 0xcccccccc1337class PrivateHeader(NDRSTRUCT):1338    structure = (1339        ('ObjectBufferLength', ULONG),1340        ('Filler', ULONG),1341    )1342    def __init__(self, data = None,isNDR64 = False):1343        NDRSTRUCT.__init__(self, data, isNDR64)1344        if data is None:1345            self['Filler'] = 0xcccccccc1346class TypeSerialization1(NDRSTRUCT):1347    commonHdr = (1348        ('CommonHeader', CommonHeader),1349        ('PrivateHeader', PrivateHeader),1350    )1351    def getData(self, soFar = 0):1352        self['PrivateHeader']['ObjectBufferLength'] = len(NDRSTRUCT.getData(self, soFar)) + len(1353            NDRSTRUCT.getDataReferents(self, soFar)) - len(self['CommonHeader']) - len(self['PrivateHeader'])1354        return NDRSTRUCT.getData(self, soFar)1355class DCERPCServer(Thread):1356    """1357    A minimalistic DCERPC Server, mainly used by the smbserver, for now. Might be useful1358    for other purposes in the future, but we should do it way stronger.1359    If you want to implement a DCE Interface Server, use this class as the base class1360    """1361    def __init__(self):1362        Thread.__init__(self)1363        self._listenPort    = 01364        self._listenAddress = '127.0.0.1'1365        self._listenUUIDS   = {}1366        self._boundUUID     = b''1367        self._sock          = None1368        self._clientSock    = None1369        self._callid        = 11370        self._max_frag       = None1371        self._max_xmit_size = 42801372        self.__log = LOG1373        self._sock = socket.socket()1374        self._sock.bind((self._listenAddress,self._listenPort))1375    def log(self, msg, level=logging.INFO):1376        self.__log.log(level,msg)1377    def addCallbacks(self, ifaceUUID, secondaryAddr, callbacks):1378        """1379        adds a call back to a UUID/opnum call1380        1381        :param uuid ifaceUUID: the interface UUID1382        :param string secondaryAddr: the secondary address to answer as part of the bind request (e.g. \\\\PIPE\\\\srvsvc)1383        :param dict callbacks: the callbacks for each opnum. Format is [opnum] = callback1384        """1385        self._listenUUIDS[uuidtup_to_bin(ifaceUUID)] = {}1386        self._listenUUIDS[uuidtup_to_bin(ifaceUUID)]['SecondaryAddr'] = secondaryAddr1387        self._listenUUIDS[uuidtup_to_bin(ifaceUUID)]['CallBacks'] = callbacks1388        self.log("Callback added for UUID %s V:%s" % ifaceUUID)1389    def setListenPort(self, portNum):1390        self._listenPort = portNum1391        self._sock = socket.socket()1392        self._sock.bind((self._listenAddress,self._listenPort))1393    def getListenPort(self):1394        return self._sock.getsockname()[1]1395    def recv(self):1396        finished = False1397        retAnswer = b''1398        response_data = b''1399        while not finished:1400            # At least give me the MSRPCRespHeader, especially important for TCP/UDP Transports1401            response_data = self._clientSock.recv(MSRPCRespHeader._SIZE)1402            # No data?, connection might have closed1403            if response_data == b'':1404                return None1405            response_header = MSRPCRespHeader(response_data)1406            # Ok, there might be situation, especially with large packets, 1407            # that the transport layer didn't send us the full packet's contents1408            # So we gotta check we received it all1409            while len(response_data) < response_header['frag_len']:1410               response_data += self._clientSock.recv(response_header['frag_len']-len(response_data))1411            response_header = MSRPCRespHeader(response_data)1412            if response_header['flags'] & PFC_LAST_FRAG:1413                # No need to reassembly DCERPC1414                finished = True1415            answer = response_header['pduData']1416            auth_len = response_header['auth_len']1417            if auth_len:1418                auth_len += 81419                auth_data = answer[-auth_len:]1420                sec_trailer = SEC_TRAILER(data = auth_data)1421                answer = answer[:-auth_len]1422                if sec_trailer['auth_pad_len']:1423                    answer = answer[:-sec_trailer['auth_pad_len']]1424              1425            retAnswer += answer1426        return response_data1427    1428    def run(self):1429        self._sock.listen(10)1430        while True:1431            self._clientSock, address = self._sock.accept()1432            try:1433                while True:1434                    data = self.recv()1435                    if data is None:1436                        # No data.. connection closed1437                        break1438                    answer = self.processRequest(data)1439                    if answer is not None:1440                        self.send(answer)1441            except Exception:1442                #import traceback1443                #traceback.print_exc()1444                pass1445            self._clientSock.close()1446    def send(self, data):1447        max_frag       = self._max_frag1448        if len(data['pduData']) > self._max_xmit_size - 32:1449            max_frag   = self._max_xmit_size - 32    # XXX: 32 is a safe margin for auth data1450        if self._max_frag:1451            max_frag   = min(max_frag, self._max_frag)1452        if max_frag and len(data['pduData']) > 0:1453            packet     = data['pduData']1454            offset     = 01455            while 1:1456                toSend = packet[offset:offset+max_frag]1457                if not toSend:1458                    break1459                flags  = 01460                if offset == 0:1461                    flags |= PFC_FIRST_FRAG1462                offset += len(toSend)1463                if offset == len(packet):1464                    flags |= PFC_LAST_FRAG1465                data['flags']   = flags1466                data['pduData'] = toSend1467                self._clientSock.send(data.get_packet())1468        else:1469            self._clientSock.send(data.get_packet())1470        self._callid += 11471    def bind(self,packet, bind):1472        # Standard NDR Representation1473        NDRSyntax   = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')1474        resp = MSRPCBindAck()1475        resp['type']             = MSRPC_BINDACK1476        resp['flags']            = packet['flags']1477        resp['frag_len']         = 01478        resp['auth_len']         = 01479        resp['auth_data']        = b''1480        resp['call_id']          = packet['call_id'] 1481        resp['max_tfrag']        = bind['max_tfrag']1482        resp['max_rfrag']        = bind['max_rfrag']1483        resp['assoc_group']      = 0x12341484        resp['ctx_num']          = 01485        data      = bind['ctx_items']1486        ctx_items = b''1487        resp['SecondaryAddrLen'] = 01488        for i in range(bind['ctx_num']):1489            result = MSRPC_CONT_RESULT_USER_REJECT1490            item   = CtxItem(data)1491            data   = data[len(item):]1492            # First we check the Transfer Syntax is NDR32, what we support1493            if item['TransferSyntax'] == uuidtup_to_bin(NDRSyntax):1494                # Now Check if the interface is what we listen1495                reason = 1 # Default, Abstract Syntax not supported1496                for j in self._listenUUIDS:1497                    if item['AbstractSyntax'] == j:1498                        # Match, we accept the bind request1499                        resp['SecondaryAddr']    = self._listenUUIDS[item['AbstractSyntax']]['SecondaryAddr']1500                        resp['SecondaryAddrLen'] = len(resp['SecondaryAddr'])+11501                        reason           = 01502                        self._boundUUID = j1503            else:1504                # Fail the bind request for this context1505                reason = 2 # Transfer Syntax not supported1506            if reason == 0:1507               result = MSRPC_CONT_RESULT_ACCEPT1508            if reason == 1:1509                LOG.error('Bind request for an unsupported interface %s' % bin_to_uuidtup(item['AbstractSyntax']))1510            resp['ctx_num']             += 11511            itemResult                   = CtxItemResult()1512            itemResult['Result']         = result1513            itemResult['Reason']         = reason1514            itemResult['TransferSyntax'] = uuidtup_to_bin(NDRSyntax)1515            ctx_items                   += itemResult.getData()1516        resp['Pad']              ='A'*((4-((resp["SecondaryAddrLen"]+MSRPCBindAck._SIZE) % 4))%4)1517        resp['ctx_items'] = ctx_items1518        resp['frag_len']  = len(resp.getData())1519        self._clientSock.send(resp.getData())1520        return None1521    def processRequest(self,data):1522        packet = MSRPCHeader(data)1523        if packet['type'] == MSRPC_BIND:1524            bind   = MSRPCBind(packet['pduData'])1525            self.bind(packet, bind)1526            packet = None1527        elif packet['type'] == MSRPC_REQUEST:1528            request          = MSRPCRequestHeader(data)1529            response         = MSRPCRespHeader(data)1530            response['type'] = MSRPC_RESPONSE1531            # Serve the opnum requested, if not, fails1532            if request['op_num'] in self._listenUUIDS[self._boundUUID]['CallBacks']:1533                # Call the function 1534                returnData          = self._listenUUIDS[self._boundUUID]['CallBacks'][request['op_num']](request['pduData'])1535                response['pduData'] = returnData1536            else:1537                LOG.error('Unsupported DCERPC opnum %d called for interface %s' % (request['op_num'], bin_to_uuidtup(self._boundUUID)))1538                response['type']    = MSRPC_FAULT1539                response['pduData'] = pack('<L',0x000006E4)1540            response['frag_len'] = len(response)1541            return response1542        else:1543            # Defaults to a fault1544            packet         = MSRPCRespHeader(data)1545            packet['type'] = MSRPC_FAULT...tsch.py
Source:tsch.py  
1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.2#3# This software is provided under under a slightly modified version4# of the Apache Software License. See the accompanying LICENSE file5# for more information.6#7# Author: Alberto Solino (@agsolino)8#9# Description:10#   [MS-TSCH] ITaskSchedulerService Interface implementation11#12#   Best way to learn how to use these calls is to grab the protocol standard13#   so you understand what the call does, and then read the test case located14#   at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC15#16#   Some calls have helper functions, which makes it even easier to use.17#   They are located at the end of this file. 18#   Helper functions start with "h"<name of the call>.19#   There are test cases for them too. 20#21from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray22from impacket.dcerpc.v5.dtypes import DWORD, LPWSTR, ULONG, WSTR, NULL, GUID, PSYSTEMTIME, SYSTEMTIME23from impacket.structure import Structure24from impacket import hresult_errors, system_errors25from impacket.uuid import uuidtup_to_bin26from impacket.dcerpc.v5.rpcrt import DCERPCException27MSRPC_UUID_TSCHS  = uuidtup_to_bin(('86D35949-83C9-4044-B424-DB363231FD0C','1.0'))28class DCERPCSessionError(DCERPCException):29    def __init__(self, error_string=None, error_code=None, packet=None):30        DCERPCException.__init__(self, error_string, error_code, packet)31    def __str__( self ):32        key = self.error_code33        if key in hresult_errors.ERROR_MESSAGES:34            error_msg_short = hresult_errors.ERROR_MESSAGES[key][0]35            error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1]36            return 'TSCH SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)37        elif key & 0xffff in system_errors.ERROR_MESSAGES:38            error_msg_short = system_errors.ERROR_MESSAGES[key & 0xffff][0]39            error_msg_verbose = system_errors.ERROR_MESSAGES[key & 0xffff][1]40            return 'TSCH SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)41        else:42            return 'TSCH SessionError: unknown error code: 0x%x' % self.error_code43################################################################################44# CONSTANTS45################################################################################46# 2.3.1 Constant Values47CNLEN = 1548DNLEN = CNLEN49UNLEN = 25650MAX_BUFFER_SIZE = (DNLEN+UNLEN+1+1)51# 2.3.7 Flags52TASK_FLAG_INTERACTIVE                  = 0x153TASK_FLAG_DELETE_WHEN_DONE             = 0x254TASK_FLAG_DISABLED                     = 0x455TASK_FLAG_START_ONLY_IF_IDLE           = 0x1056TASK_FLAG_KILL_ON_IDLE_END             = 0x2057TASK_FLAG_DONT_START_IF_ON_BATTERIES   = 0x4058TASK_FLAG_KILL_IF_GOING_ON_BATTERIES   = 0x8059TASK_FLAG_RUN_ONLY_IF_DOCKED           = 0x10060TASK_FLAG_HIDDEN                       = 0x20061TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET = 0x40062TASK_FLAG_RESTART_ON_IDLE_RESUME       = 0x80063TASK_FLAG_SYSTEM_REQUIRED              = 0x100064TASK_FLAG_RUN_ONLY_IF_LOGGED_ON        = 0x200065# 2.3.9 TASK_LOGON_TYPE66TASK_LOGON_NONE                          = 067TASK_LOGON_PASSWORD                      = 168TASK_LOGON_S4U                           = 269TASK_LOGON_INTERACTIVE_TOKEN             = 370TASK_LOGON_GROUP                         = 471TASK_LOGON_SERVICE_ACCOUNT               = 572TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD = 673# 2.3.13 TASK_STATE74TASK_STATE_UNKNOWN  = 075TASK_STATE_DISABLED = 176TASK_STATE_QUEUED   = 277TASK_STATE_READY    = 378TASK_STATE_RUNNING  = 479# 2.4.1 FIXDLEN_DATA80SCHED_S_TASK_READY         = 0x0004130081SCHED_S_TASK_RUNNING       = 0x0004130182SCHED_S_TASK_NOT_SCHEDULED = 0x0004130183# 2.4.2.11 Triggers84TASK_TRIGGER_FLAG_HAS_END_DATE         = 085TASK_TRIGGER_FLAG_KILL_AT_DURATION_END = 086TASK_TRIGGER_FLAG_DISABLED             = 087# ToDo: Change this to enums88ONCE                 = 089DAILY                = 190WEEKLY               = 291MONTHLYDATE          = 392MONTHLYDOW           = 493EVENT_ON_IDLE        = 594EVENT_AT_SYSTEMSTART = 695EVENT_AT_LOGON       = 796SUNDAY    = 097MONDAY    = 198TUESDAY   = 299WEDNESDAY = 3100THURSDAY  = 4101FRIDAY    = 5102SATURDAY  = 6103JANUARY   = 1104FEBRUARY  = 2105MARCH     = 3106APRIL     = 4107MAY       = 5108JUNE      = 6109JULY      = 7110AUGUST    = 8111SEPTEMBER = 9112OCTOBER   = 10113NOVEMBER  = 11114DECEMBER  = 12115# 2.4.2.11.8 MONTHLYDOW Trigger116FIRST_WEEK  = 1117SECOND_WEEK = 2118THIRD_WEEK  = 3119FOURTH_WEEK = 4120LAST_WEEK   = 5121# 2.3.12 TASK_NAMES122TASK_NAMES = LPWSTR123# 3.2.5.4.2 SchRpcRegisterTask (Opnum 1)124TASK_VALIDATE_ONLY                = 1<<(31-31)125TASK_CREATE                       = 1<<(31-30)126TASK_UPDATE                       = 1<<(31-29)127TASK_DISABLE                      = 1<<(31-28)128TASK_DON_ADD_PRINCIPAL_ACE        = 1<<(31-27)129TASK_IGNORE_REGISTRATION_TRIGGERS = 1<<(31-26)130# 3.2.5.4.5 SchRpcSetSecurity (Opnum 4)131TASK_DONT_ADD_PRINCIPAL_ACE = 1<<(31-27)132SCH_FLAG_FOLDER             = 1<<(31-2)133SCH_FLAG_TASK               = 1<<(31-1) 134# 3.2.5.4.7 SchRpcEnumFolders (Opnum 6)135TASK_ENUM_HIDDEN = 1136# 3.2.5.4.13 SchRpcRun (Opnum 12)137TASK_RUN_AS_SELF            = 1<<(31-31)138TASK_RUN_IGNORE_CONSTRAINTS = 1<<(31-30)139TASK_RUN_USE_SESSION_ID     = 1<<(31-29)140TASK_RUN_USER_SID           = 1<<(31-28)141# 3.2.5.4.18 SchRpcGetTaskInfo (Opnum 17)142SCH_FLAG_STATE            = 1<<(31-3)143################################################################################144# STRUCTURES145################################################################################146# 2.3.12 TASK_NAMES147class TASK_NAMES_ARRAY(NDRUniConformantArray):148    item = TASK_NAMES149class PTASK_NAMES_ARRAY(NDRPOINTER):150    referent = (151        ('Data',TASK_NAMES_ARRAY),152    )153class WSTR_ARRAY(NDRUniConformantArray):154    item = WSTR155class PWSTR_ARRAY(NDRPOINTER):156    referent = (157        ('Data',WSTR_ARRAY),158    )159class GUID_ARRAY(NDRUniConformantArray):160    item = GUID161class PGUID_ARRAY(NDRPOINTER):162    referent = (163        ('Data',GUID_ARRAY),164    )165# 3.2.5.4.13 SchRpcRun (Opnum 12)166class SYSTEMTIME_ARRAY(NDRUniConformantArray):167    item = SYSTEMTIME168class PSYSTEMTIME_ARRAY(NDRPOINTER):169    referent = (170        ('Data',SYSTEMTIME_ARRAY),171    )172# 2.3.8 TASK_USER_CRED173class TASK_USER_CRED(NDRSTRUCT):174    structure =  (175        ('userId',LPWSTR),176        ('password',LPWSTR),177        ('flags',DWORD),178    )179class TASK_USER_CRED_ARRAY(NDRUniConformantArray):180    item = TASK_USER_CRED181class LPTASK_USER_CRED_ARRAY(NDRPOINTER):182    referent = (183        ('Data',TASK_USER_CRED_ARRAY),184    )185# 2.3.10 TASK_XML_ERROR_INFO186class TASK_XML_ERROR_INFO(NDRSTRUCT):187    structure =  (188        ('line',DWORD),189        ('column',DWORD),190        ('node',LPWSTR),191        ('value',LPWSTR),192    )193class PTASK_XML_ERROR_INFO(NDRPOINTER):194    referent = (195        ('Data',TASK_XML_ERROR_INFO),196    )197# 2.4.1 FIXDLEN_DATA198class FIXDLEN_DATA(Structure):199    structure = (200        ('Product Version','<H=0'),201        ('File Version','<H=0'),202        ('Job uuid','16s="'),203        ('App Name Len Offset','<H=0'),204        ('Trigger Offset','<H=0'),205        ('Error Retry Count','<H=0'),206        ('Error Retry Interval','<H=0'),207        ('Idle Deadline','<H=0'),208        ('Idle Wait','<H=0'),209        ('Priority','<L=0'),210        ('Maximum Run Time','<L=0'),211        ('Exit Code','<L=0'),212        ('Status','<L=0'),213        ('Flags','<L=0'),214    )215# 2.4.2.11 Triggers216class TRIGGERS(Structure):217    structure = (218        ('Trigger Size','<H=0'),219        ('Reserved1','<H=0'),220        ('Begin Year','<H=0'),221        ('Begin Month','<H=0'),222        ('Begin Day','<H=0'),223        ('End Year','<H=0'),224        ('End Month','<H=0'),225        ('End Day','<H=0'),226        ('Start Hour','<H=0'),227        ('Start Minute','<H=0'),228        ('Minutes Duration','<L=0'),229        ('Minutes Interval','<L=0'),230        ('Flags','<L=0'),231        ('Trigger Type','<L=0'),232        ('TriggerSpecific0','<H=0'),233        ('TriggerSpecific1','<H=0'),234        ('TriggerSpecific2','<H=0'),235        ('Padding','<H=0'),236        ('Reserved2','<H=0'),237        ('Reserved3','<H=0'),238    )239# 2.4.2.11.6 WEEKLY Trigger240class WEEKLY(Structure):241    structure = (242        ('Trigger Type','<L=0'),243        ('Weeks Interval','<H=0'),244        ('DaysOfTheWeek','<H=0'),245        ('Unused','<H=0'),246        ('Padding','<H=0'),247    )248# 2.4.2.11.7 MONTHLYDATE Trigger249class MONTHLYDATE(Structure):250    structure = (251        ('Trigger Type','<L=0'),252        ('Days','<L=0'),253        ('Months','<H=0'),254        ('Padding','<H=0'),255    )256# 2.4.2.11.8 MONTHLYDOW Trigger257class MONTHLYDOW(Structure):258    structure = (259        ('Trigger Type','<L=0'),260        ('WhichWeek','<H=0'),261        ('DaysOfTheWeek','<H=0'),262        ('Months','<H=0'),263        ('Padding','<H=0'),264        ('Reserved2','<H=0'),265        ('Reserved3','<H=0'),266    )267# 2.4.2.12 Job Signature268class JOB_SIGNATURE(Structure):269    structure = (270        ('SignatureVersion','<HH0'),271        ('MinClientVersion','<H=0'),272        ('Signature','64s="'),273    )274################################################################################275# RPC CALLS276################################################################################277# 3.2.5.4.1 SchRpcHighestVersion (Opnum 0)278class SchRpcHighestVersion(NDRCALL):279    opnum = 0280    structure = (281    )282class SchRpcHighestVersionResponse(NDRCALL):283    structure = (284        ('pVersion', DWORD),285        ('ErrorCode',ULONG),286    )287# 3.2.5.4.2 SchRpcRegisterTask (Opnum 1)288class SchRpcRegisterTask(NDRCALL):289    opnum = 1290    structure = (291        ('path', LPWSTR),292        ('xml', WSTR),293        ('flags', DWORD),294        ('sddl', LPWSTR),295        ('logonType', DWORD),296        ('cCreds', DWORD),297        ('pCreds', LPTASK_USER_CRED_ARRAY),298    )299class SchRpcRegisterTaskResponse(NDRCALL):300    structure = (301        ('pActualPath', LPWSTR),302        ('pErrorInfo', PTASK_XML_ERROR_INFO),303        ('ErrorCode',ULONG),304    )305# 3.2.5.4.3 SchRpcRetrieveTask (Opnum 2)306class SchRpcRetrieveTask(NDRCALL):307    opnum = 2308    structure = (309        ('path', WSTR),310        ('lpcwszLanguagesBuffer', WSTR),311        ('pulNumLanguages', DWORD),312    )313class SchRpcRetrieveTaskResponse(NDRCALL):314    structure = (315        ('pXml', LPWSTR),316        ('ErrorCode',ULONG),317    )318# 3.2.5.4.4 SchRpcCreateFolder (Opnum 3)319class SchRpcCreateFolder(NDRCALL):320    opnum = 3321    structure = (322        ('path', WSTR),323        ('sddl', LPWSTR),324        ('flags', DWORD),325    )326class SchRpcCreateFolderResponse(NDRCALL):327    structure = (328        ('ErrorCode',ULONG),329    )330# 3.2.5.4.5 SchRpcSetSecurity (Opnum 4)331class SchRpcSetSecurity(NDRCALL):332    opnum = 4333    structure = (334        ('path', WSTR),335        ('sddl', WSTR),336        ('flags', DWORD),337    )338class SchRpcSetSecurityResponse(NDRCALL):339    structure = (340        ('ErrorCode',ULONG),341    )342# 3.2.5.4.6 SchRpcGetSecurity (Opnum 5)343class SchRpcGetSecurity(NDRCALL):344    opnum = 5345    structure = (346        ('path', WSTR),347        ('securityInformation', DWORD),348    )349class SchRpcGetSecurityResponse(NDRCALL):350    structure = (351        ('sddl',LPWSTR),352        ('ErrorCode',ULONG),353    )354# 3.2.5.4.7 SchRpcEnumFolders (Opnum 6)355class SchRpcEnumFolders(NDRCALL):356    opnum = 6357    structure = (358        ('path', WSTR),359        ('flags', DWORD),360        ('startIndex', DWORD),361        ('cRequested', DWORD),362    )363class SchRpcEnumFoldersResponse(NDRCALL):364    structure = (365        ('startIndex', DWORD),366        ('pcNames', DWORD),367        ('pNames', PTASK_NAMES_ARRAY),368        ('ErrorCode',ULONG),369    )370# 3.2.5.4.8 SchRpcEnumTasks (Opnum 7)371class SchRpcEnumTasks(NDRCALL):372    opnum = 7373    structure = (374        ('path', WSTR),375        ('flags', DWORD),376        ('startIndex', DWORD),377        ('cRequested', DWORD),378    )379class SchRpcEnumTasksResponse(NDRCALL):380    structure = (381        ('startIndex', DWORD),382        ('pcNames', DWORD),383        ('pNames', PTASK_NAMES_ARRAY),384        ('ErrorCode',ULONG),385    )386# 3.2.5.4.9 SchRpcEnumInstances (Opnum 8)387class SchRpcEnumInstances(NDRCALL):388    opnum = 8389    structure = (390        ('path', LPWSTR),391        ('flags', DWORD),392    )393class SchRpcEnumInstancesResponse(NDRCALL):394    structure = (395        ('pcGuids', DWORD),396        ('pGuids', PGUID_ARRAY),397        ('ErrorCode',ULONG),398    )399# 3.2.5.4.10 SchRpcGetInstanceInfo (Opnum 9)400class SchRpcGetInstanceInfo(NDRCALL):401    opnum = 9402    structure = (403        ('guid', GUID),404    )405class SchRpcGetInstanceInfoResponse(NDRCALL):406    structure = (407        ('pPath', LPWSTR),408        ('pState', DWORD),409        ('pCurrentAction', LPWSTR),410        ('pInfo', LPWSTR),411        ('pcGroupInstances', DWORD),412        ('pGroupInstances', PGUID_ARRAY),413        ('pEnginePID', DWORD),414        ('ErrorCode',ULONG),415    )416# 3.2.5.4.11 SchRpcStopInstance (Opnum 10)417class SchRpcStopInstance(NDRCALL):418    opnum = 10419    structure = (420        ('guid', GUID),421        ('flags', DWORD),422    )423class SchRpcStopInstanceResponse(NDRCALL):424    structure = (425        ('ErrorCode',ULONG),426    )427# 3.2.5.4.12 SchRpcStop (Opnum 11)428class SchRpcStop(NDRCALL):429    opnum = 11430    structure = (431        ('path', LPWSTR),432        ('flags', DWORD),433    )434class SchRpcStopResponse(NDRCALL):435    structure = (436        ('ErrorCode',ULONG),437    )438# 3.2.5.4.13 SchRpcRun (Opnum 12)439class SchRpcRun(NDRCALL):440    opnum = 12441    structure = (442        ('path', WSTR),443        ('cArgs', DWORD),444        ('pArgs', PWSTR_ARRAY),445        ('flags', DWORD),446        ('sessionId', DWORD),447        ('user', LPWSTR),448    )449class SchRpcRunResponse(NDRCALL):450    structure = (451        ('pGuid', GUID),452        ('ErrorCode',ULONG),453    )454# 3.2.5.4.14 SchRpcDelete (Opnum 13)455class SchRpcDelete(NDRCALL):456    opnum = 13457    structure = (458        ('path', WSTR),459        ('flags', DWORD),460    )461class SchRpcDeleteResponse(NDRCALL):462    structure = (463        ('ErrorCode',ULONG),464    )465# 3.2.5.4.15 SchRpcRename (Opnum 14)466class SchRpcRename(NDRCALL):467    opnum = 14468    structure = (469        ('path', WSTR),470        ('newName', WSTR),471        ('flags', DWORD),472    )473class SchRpcRenameResponse(NDRCALL):474    structure = (475        ('ErrorCode',ULONG),476    )477# 3.2.5.4.16 SchRpcScheduledRuntimes (Opnum 15)478class SchRpcScheduledRuntimes(NDRCALL):479    opnum = 15480    structure = (481        ('path', WSTR),482        ('start', PSYSTEMTIME),483        ('end', PSYSTEMTIME),484        ('flags', DWORD),485        ('cRequested', DWORD),486    )487class SchRpcScheduledRuntimesResponse(NDRCALL):488    structure = (489        ('pcRuntimes',DWORD),490        ('pRuntimes',PSYSTEMTIME_ARRAY),491        ('ErrorCode',ULONG),492    )493# 3.2.5.4.17 SchRpcGetLastRunInfo (Opnum 16)494class SchRpcGetLastRunInfo(NDRCALL):495    opnum = 16496    structure = (497        ('path', WSTR),498    )499class SchRpcGetLastRunInfoResponse(NDRCALL):500    structure = (501        ('pLastRuntime',SYSTEMTIME),502        ('pLastReturnCode',DWORD),503        ('ErrorCode',ULONG),504    )505# 3.2.5.4.18 SchRpcGetTaskInfo (Opnum 17)506class SchRpcGetTaskInfo(NDRCALL):507    opnum = 17508    structure = (509        ('path', WSTR),510        ('flags', DWORD),511    )512class SchRpcGetTaskInfoResponse(NDRCALL):513    structure = (514        ('pEnabled',DWORD),515        ('pState',DWORD),516        ('ErrorCode',ULONG),517    )518# 3.2.5.4.19 SchRpcGetNumberOfMissedRuns (Opnum 18)519class SchRpcGetNumberOfMissedRuns(NDRCALL):520    opnum = 18521    structure = (522        ('path', WSTR),523    )524class SchRpcGetNumberOfMissedRunsResponse(NDRCALL):525    structure = (526        ('pNumberOfMissedRuns',DWORD),527        ('ErrorCode',ULONG),528    )529# 3.2.5.4.20 SchRpcEnableTask (Opnum 19)530class SchRpcEnableTask(NDRCALL):531    opnum = 19532    structure = (533        ('path', WSTR),534        ('enabled', DWORD),535    )536class SchRpcEnableTaskResponse(NDRCALL):537    structure = (538        ('ErrorCode',ULONG),539    )540################################################################################541# OPNUMs and their corresponding structures542################################################################################543OPNUMS = {544 0 : (SchRpcHighestVersion,SchRpcHighestVersionResponse ),545 1 : (SchRpcRegisterTask,SchRpcRegisterTaskResponse ),546 2 : (SchRpcRetrieveTask,SchRpcRetrieveTaskResponse ),547 3 : (SchRpcCreateFolder,SchRpcCreateFolderResponse ),548 4 : (SchRpcSetSecurity,SchRpcSetSecurityResponse ),549 5 : (SchRpcGetSecurity,SchRpcGetSecurityResponse ),550 6 : (SchRpcEnumFolders,SchRpcEnumFoldersResponse ),551 7 : (SchRpcEnumTasks,SchRpcEnumTasksResponse ),552 8 : (SchRpcEnumInstances,SchRpcEnumInstancesResponse ),553 9 : (SchRpcGetInstanceInfo,SchRpcGetInstanceInfoResponse ),554 10 : (SchRpcStopInstance,SchRpcStopInstanceResponse ),555 11 : (SchRpcStop,SchRpcStopResponse ),556 12 : (SchRpcRun,SchRpcRunResponse ),557 13 : (SchRpcDelete,SchRpcDeleteResponse ),558 14 : (SchRpcRename,SchRpcRenameResponse ),559 15 : (SchRpcScheduledRuntimes,SchRpcScheduledRuntimesResponse ),560 16 : (SchRpcGetLastRunInfo,SchRpcGetLastRunInfoResponse ),561 17 : (SchRpcGetTaskInfo,SchRpcGetTaskInfoResponse ),562 18 : (SchRpcGetNumberOfMissedRuns,SchRpcGetNumberOfMissedRunsResponse),563 19 : (SchRpcEnableTask,SchRpcEnableTaskResponse),564}565################################################################################566# HELPER FUNCTIONS567################################################################################568def checkNullString(string):569    if string == NULL:570        return string571    if string[-1:] != '\x00':572        return string + '\x00'573    else:574        return string575def hSchRpcHighestVersion(dce):576    return dce.request(SchRpcHighestVersion())577def hSchRpcRegisterTask(dce, path, xml, flags, sddl, logonType, pCreds = ()):578    request = SchRpcRegisterTask()579    request['path'] = checkNullString(path)580    request['xml'] = checkNullString(xml)581    request['flags'] = flags582    request['sddl'] = sddl583    request['logonType'] = logonType584    request['cCreds'] = len(pCreds)585    if len(pCreds) == 0:586        request['pCreds'] = NULL587    else:588        for cred in pCreds:589            request['pCreds'].append(cred)590    return dce.request(request)591def hSchRpcRetrieveTask(dce, path, lpcwszLanguagesBuffer = '\x00', pulNumLanguages=0 ):592    schRpcRetrieveTask = SchRpcRetrieveTask()593    schRpcRetrieveTask['path'] = checkNullString(path)594    schRpcRetrieveTask['lpcwszLanguagesBuffer'] = lpcwszLanguagesBuffer595    schRpcRetrieveTask['pulNumLanguages'] = pulNumLanguages596    return dce.request(schRpcRetrieveTask)597def hSchRpcCreateFolder(dce, path, sddl = NULL):598    schRpcCreateFolder = SchRpcCreateFolder()599    schRpcCreateFolder['path'] = checkNullString(path)600    schRpcCreateFolder['sddl'] = sddl601    schRpcCreateFolder['flags'] = 0602    return dce.request(schRpcCreateFolder)603def hSchRpcSetSecurity(dce, path, sddl, flags):604    schRpcSetSecurity = SchRpcSetSecurity()605    schRpcSetSecurity['path'] = checkNullString(path)606    schRpcSetSecurity['sddl'] = checkNullString(sddl)607    schRpcSetSecurity['flags'] = flags608    return dce.request(schRpcSetSecurity)609def hSchRpcGetSecurity(dce, path, securityInformation=0xffffffff):610    schRpcGetSecurity = SchRpcGetSecurity()611    schRpcGetSecurity['path'] = checkNullString(path)612    schRpcGetSecurity['securityInformation'] = securityInformation613    return dce.request(schRpcGetSecurity)614def hSchRpcEnumFolders(dce, path, flags=TASK_ENUM_HIDDEN, startIndex=0, cRequested=0xffffffff):615    schRpcEnumFolders = SchRpcEnumFolders()616    schRpcEnumFolders['path'] = checkNullString(path)617    schRpcEnumFolders['flags'] = flags618    schRpcEnumFolders['startIndex'] = startIndex619    schRpcEnumFolders['cRequested'] = cRequested620    return dce.request(schRpcEnumFolders)621def hSchRpcEnumTasks(dce, path, flags=TASK_ENUM_HIDDEN, startIndex=0, cRequested=0xffffffff):622    schRpcEnumTasks = SchRpcEnumTasks()623    schRpcEnumTasks['path'] = checkNullString(path)624    schRpcEnumTasks['flags'] = flags625    schRpcEnumTasks['startIndex'] = startIndex626    schRpcEnumTasks['cRequested'] = cRequested627    return dce.request(schRpcEnumTasks)628def hSchRpcEnumInstances(dce, path, flags=TASK_ENUM_HIDDEN):629    schRpcEnumInstances = SchRpcEnumInstances()630    schRpcEnumInstances['path'] = checkNullString(path)631    schRpcEnumInstances['flags'] = flags632    return dce.request(schRpcEnumInstances)633def hSchRpcGetInstanceInfo(dce, guid):634    schRpcGetInstanceInfo = SchRpcGetInstanceInfo()635    schRpcGetInstanceInfo['guid'] = guid636    return dce.request(schRpcGetInstanceInfo)637def hSchRpcStopInstance(dce, guid, flags = 0):638    schRpcStopInstance = SchRpcStopInstance()639    schRpcStopInstance['guid'] = guid640    schRpcStopInstance['flags'] = flags641    return dce.request(schRpcStopInstance)642def hSchRpcStop(dce, path, flags = 0):643    schRpcStop= SchRpcStop()644    schRpcStop['path'] = checkNullString(path)645    schRpcStop['flags'] = flags646    return dce.request(schRpcStop)647def hSchRpcRun(dce, path, pArgs=(), flags=0, sessionId=0, user = NULL):648    schRpcRun = SchRpcRun()649    schRpcRun['path'] = checkNullString(path)650    schRpcRun['cArgs'] = len(pArgs)651    for arg in pArgs:652        argn = LPWSTR()653        argn['Data'] = checkNullString(arg)654        schRpcRun['pArgs'].append(argn)655    schRpcRun['flags'] = flags656    schRpcRun['sessionId'] = sessionId657    schRpcRun['user'] = user658    return dce.request(schRpcRun)659def hSchRpcDelete(dce, path, flags = 0):660    schRpcDelete = SchRpcDelete()661    schRpcDelete['path'] = checkNullString(path)662    schRpcDelete['flags'] = flags663    return dce.request(schRpcDelete)664def hSchRpcRename(dce, path, newName, flags = 0):665    schRpcRename = SchRpcRename()666    schRpcRename['path'] = checkNullString(path)667    schRpcRename['newName'] = checkNullString(newName)668    schRpcRename['flags'] = flags669    return dce.request(schRpcRename)670def hSchRpcScheduledRuntimes(dce, path, start = NULL, end = NULL, flags = 0, cRequested = 10):671    schRpcScheduledRuntimes = SchRpcScheduledRuntimes()672    schRpcScheduledRuntimes['path'] = checkNullString(path)673    schRpcScheduledRuntimes['start'] = start674    schRpcScheduledRuntimes['end'] = end675    schRpcScheduledRuntimes['flags'] = flags676    schRpcScheduledRuntimes['cRequested'] = cRequested677    return dce.request(schRpcScheduledRuntimes)678def hSchRpcGetLastRunInfo(dce, path):679    schRpcGetLastRunInfo = SchRpcGetLastRunInfo()680    schRpcGetLastRunInfo['path'] = checkNullString(path)681    return dce.request(schRpcGetLastRunInfo)682def hSchRpcGetTaskInfo(dce, path, flags = 0):683    schRpcGetTaskInfo = SchRpcGetTaskInfo()684    schRpcGetTaskInfo['path'] = checkNullString(path)685    schRpcGetTaskInfo['flags'] = flags686    return dce.request(schRpcGetTaskInfo)687def hSchRpcGetNumberOfMissedRuns(dce, path):688    schRpcGetNumberOfMissedRuns = SchRpcGetNumberOfMissedRuns()689    schRpcGetNumberOfMissedRuns['path'] = checkNullString(path)690    return dce.request(schRpcGetNumberOfMissedRuns)691def hSchRpcEnableTask(dce, path, enabled = True):692    schRpcEnableTask = SchRpcEnableTask()693    schRpcEnableTask['path'] = checkNullString(path)694    if enabled is True:695        schRpcEnableTask['enabled'] = 1696    else:697        schRpcEnableTask['enabled'] = 0...rpc_config.py
Source:rpc_config.py  
...43    def __init__(self, retval, msg):44        super(RpcException, self).__init__(msg)45        self.retval = retval46        self.message = msg47class spdk_rpc(object):48    def __init__(self, rpc_py):49        self.rpc_py = rpc_py50    def __getattr__(self, name):51        def call(*args):52            cmd = "{} {}".format(self.rpc_py, name)53            for arg in args:54                cmd += " {}".format(arg)55            return check_output(cmd, shell=True).decode("utf-8")56        return call57def verify(expr, retcode, msg):58    if not expr:59        raise RpcException(retcode, msg)60def verify_log_flag_rpc_methods(rpc_py, rpc_param):61    rpc = spdk_rpc(rpc_py)62    output = rpc.log_get_flags()63    jsonvalue = json.loads(output)64    verify(not jsonvalue[rpc_param['log_flag']], 1,65           "log_get_flags returned {}, expected false".format(jsonvalue))66    rpc.log_set_flag(rpc_param['log_flag'])67    output = rpc.log_get_flags()68    jsonvalue = json.loads(output)69    verify(jsonvalue[rpc_param['log_flag']], 1,70           "log_get_flags returned {}, expected true".format(jsonvalue))71    rpc.log_clear_flag(rpc_param['log_flag'])72    output = rpc.log_get_flags()73    jsonvalue = json.loads(output)74    verify(not jsonvalue[rpc_param['log_flag']], 1,75           "log_get_flags returned {}, expected false".format(jsonvalue))76    print("verify_log_flag_rpc_methods passed")77def verify_iscsi_connection_rpc_methods(rpc_py):78    rpc = spdk_rpc(rpc_py)79    output = rpc.iscsi_get_connections()80    jsonvalue = json.loads(output)81    verify(not jsonvalue, 1,82           "iscsi_get_connections returned {}, expected empty".format(jsonvalue))83    rpc.bdev_malloc_create(rpc_param['malloc_bdev_size'], rpc_param['malloc_block_size'])84    rpc.iscsi_create_portal_group(portal_tag, "{}:{}".format(rpc_param['target_ip'], str(rpc_param['port'])))85    rpc.iscsi_create_initiator_group(initiator_tag, rpc_param['initiator_name'], rpc_param['netmask'])86    lun_mapping = "Malloc" + str(rpc_param['lun_total']) + ":0"87    net_mapping = portal_tag + ":" + initiator_tag88    rpc.iscsi_create_target_node(rpc_param['target_name'], rpc_param['alias_name'], lun_mapping,89                                 net_mapping, rpc_param['queue_depth'], '-d')90    check_output('iscsiadm -m discovery -t st -p {}'.format(rpc_param['target_ip']), shell=True)91    check_output('iscsiadm -m node --login', shell=True)92    name = json.loads(rpc.iscsi_get_target_nodes())[0]['name']93    output = rpc.iscsi_get_connections()94    jsonvalues = json.loads(output)95    verify(jsonvalues[0]['target_node_name'] == rpc_param['target_name'], 1,96           "target node name value is {}, expected {}".format(jsonvalues[0]['target_node_name'], rpc_param['target_name']))97    verify(jsonvalues[0]['initiator_addr'] == rpc_param['initiator_ip'], 1,98           "initiator address values is {}, expected {}".format(jsonvalues[0]['initiator_addr'], rpc_param['initiator_ip']))99    verify(jsonvalues[0]['target_addr'] == rpc_param['target_ip'], 1,100           "target address values is {}, expected {}".format(jsonvalues[0]['target_addr'], rpc_param['target_ip']))101    check_output('iscsiadm -m node --logout', shell=True)102    check_output('iscsiadm -m node -o delete', shell=True)103    rpc.iscsi_delete_initiator_group(initiator_tag)104    rpc.iscsi_delete_portal_group(portal_tag)105    rpc.iscsi_delete_target_node(name)106    output = rpc.iscsi_get_connections()107    jsonvalues = json.loads(output)108    verify(not jsonvalues, 1,109           "iscsi_get_connections returned {}, expected empty".format(jsonvalues))110    print("verify_iscsi_connection_rpc_methods passed")111def verify_scsi_devices_rpc_methods(rpc_py):112    rpc = spdk_rpc(rpc_py)113    output = rpc.scsi_get_devices()114    jsonvalue = json.loads(output)115    verify(not jsonvalue, 1,116           "scsi_get_devices returned {}, expected empty".format(jsonvalue))117    rpc.bdev_malloc_create(rpc_param['malloc_bdev_size'], rpc_param['malloc_block_size'])118    rpc.iscsi_create_portal_group(portal_tag, "{}:{}".format(rpc_param['target_ip'], str(rpc_param['port'])))119    rpc.iscsi_create_initiator_group(initiator_tag, rpc_param['initiator_name'], rpc_param['netmask'])120    lun_mapping = "Malloc" + str(rpc_param['lun_total']) + ":0"121    net_mapping = portal_tag + ":" + initiator_tag122    rpc.iscsi_create_target_node(rpc_param['target_name'], rpc_param['alias_name'], lun_mapping,123                                 net_mapping, rpc_param['queue_depth'], '-d')124    check_output('iscsiadm -m discovery -t st -p {}'.format(rpc_param['target_ip']), shell=True)125    check_output('iscsiadm -m node --login', shell=True)126    name = json.loads(rpc.iscsi_get_target_nodes())[0]['name']127    output = rpc.iscsi_get_options()128    jsonvalues = json.loads(output)129    nodebase = jsonvalues['node_base']130    output = rpc.scsi_get_devices()131    jsonvalues = json.loads(output)132    verify(jsonvalues[0]['device_name'] == nodebase + ":" + rpc_param['target_name'], 1,133           "device name value is {}, expected {}".format(jsonvalues[0]['device_name'], rpc_param['target_name']))134    verify(jsonvalues[0]['id'] == 0, 1,135           "device id value is {}, expected 0".format(jsonvalues[0]['id']))136    check_output('iscsiadm -m node --logout', shell=True)137    check_output('iscsiadm -m node -o delete', shell=True)138    rpc.iscsi_delete_initiator_group(initiator_tag)139    rpc.iscsi_delete_portal_group(portal_tag)140    rpc.iscsi_delete_target_node(name)141    output = rpc.scsi_get_devices()142    jsonvalues = json.loads(output)143    verify(not jsonvalues, 1,144           "scsi_get_devices returned {}, expected empty".format(jsonvalues))145    print("verify_scsi_devices_rpc_methods passed")146def create_malloc_bdevs_rpc_methods(rpc_py, rpc_param):147    rpc = spdk_rpc(rpc_py)148    for i in range(1, rpc_param['lun_total'] + 1):149        rpc.bdev_malloc_create(rpc_param['malloc_bdev_size'], rpc_param['malloc_block_size'])150    print("create_malloc_bdevs_rpc_methods passed")151def verify_portal_groups_rpc_methods(rpc_py, rpc_param):152    rpc = spdk_rpc(rpc_py)153    output = rpc.iscsi_get_portal_groups()154    jsonvalues = json.loads(output)155    verify(not jsonvalues, 1,156           "iscsi_get_portal_groups returned {} groups, expected empty".format(jsonvalues))157    lo_ip = (target_ip, other_ip)158    for idx, value in enumerate(lo_ip):159        # The portal group tag must start at 1160        tag = idx + 1161        rpc.iscsi_create_portal_group(tag, "{}:{}".format(value, rpc_param['port']))162        output = rpc.iscsi_get_portal_groups()163        jsonvalues = json.loads(output)164        verify(len(jsonvalues) == tag, 1,165               "iscsi_get_portal_groups returned {} groups, expected {}".format(len(jsonvalues), tag))166    tag_list = []167    for idx, value in enumerate(jsonvalues):168        verify(value['portals'][0]['host'] == lo_ip[idx], 1,169               "host value is {}, expected {}".format(value['portals'][0]['host'], rpc_param['target_ip']))170        verify(value['portals'][0]['port'] == str(rpc_param['port']), 1,171               "port value is {}, expected {}".format(value['portals'][0]['port'], str(rpc_param['port'])))172        tag_list.append(value['tag'])173        verify(value['tag'] == idx + 1, 1,174               "tag value is {}, expected {}".format(value['tag'], idx + 1))175    for idx, value in enumerate(tag_list):176        rpc.iscsi_delete_portal_group(value)177        output = rpc.iscsi_get_portal_groups()178        jsonvalues = json.loads(output)179        verify(len(jsonvalues) == (len(tag_list) - (idx + 1)), 1,180               "get_portal_group returned {} groups, expected {}".format(len(jsonvalues), (len(tag_list) - (idx + 1))))181        if not jsonvalues:182            break183        for jidx, jvalue in enumerate(jsonvalues):184            verify(jvalue['portals'][0]['host'] == lo_ip[idx + jidx + 1], 1,185                   "host value is {}, expected {}".format(jvalue['portals'][0]['host'], lo_ip[idx + jidx + 1]))186            verify(jvalue['portals'][0]['port'] == str(rpc_param['port']), 1,187                   "port value is {}, expected {}".format(jvalue['portals'][0]['port'], str(rpc_param['port'])))188            verify(jvalue['tag'] != value or jvalue['tag'] == tag_list[idx + jidx + 1], 1,189                   "tag value is {}, expected {} and not {}".format(jvalue['tag'], tag_list[idx + jidx + 1], value))190    print("verify_portal_groups_rpc_methods passed")191def verify_initiator_groups_rpc_methods(rpc_py, rpc_param):192    rpc = spdk_rpc(rpc_py)193    output = rpc.iscsi_get_initiator_groups()194    jsonvalues = json.loads(output)195    verify(not jsonvalues, 1,196           "iscsi_get_initiator_groups returned {}, expected empty".format(jsonvalues))197    for idx, value in enumerate(rpc_param['netmask']):198        # The initiator group tag must start at 1199        tag = idx + 1200        rpc.iscsi_create_initiator_group(tag, rpc_param['initiator_name'], value)201        output = rpc.iscsi_get_initiator_groups()202        jsonvalues = json.loads(output)203        verify(len(jsonvalues) == tag, 1,204               "iscsi_get_initiator_groups returned {} groups, expected {}".format(len(jsonvalues), tag))205    tag_list = []206    for idx, value in enumerate(jsonvalues):207        verify(value['initiators'][0] == rpc_param['initiator_name'], 1,208               "initiator value is {}, expected {}".format(value['initiators'][0], rpc_param['initiator_name']))209        tag_list.append(value['tag'])210        verify(value['tag'] == idx + 1, 1,211               "tag value is {}, expected {}".format(value['tag'], idx + 1))212        verify(value['netmasks'][0] == rpc_param['netmask'][idx], 1,213               "netmasks value is {}, expected {}".format(value['netmasks'][0], rpc_param['netmask'][idx]))214    for idx, value in enumerate(rpc_param['netmask']):215        tag = idx + 1216        rpc.iscsi_initiator_group_remove_initiators(tag, '-n', rpc_param['initiator_name'], '-m', value)217    output = rpc.iscsi_get_initiator_groups()218    jsonvalues = json.loads(output)219    verify(len(jsonvalues) == tag, 1,220           "iscsi_get_initiator_groups returned {} groups, expected {}".format(len(jsonvalues), tag))221    for idx, value in enumerate(jsonvalues):222        verify(value['tag'] == idx + 1, 1,223               "tag value is {}, expected {}".format(value['tag'], idx + 1))224        initiators = value.get('initiators')225        verify(len(initiators) == 0, 1,226               "length of initiator list is {}, expected 0".format(len(initiators)))227        netmasks = value.get('netmasks')228        verify(len(netmasks) == 0, 1,229               "length of netmask list is {}, expected 0".format(len(netmasks)))230    for idx, value in enumerate(rpc_param['netmask']):231        tag = idx + 1232        rpc.iscsi_initiator_group_add_initiators(tag, '-n', rpc_param['initiator_name'], '-m', value)233    output = rpc.iscsi_get_initiator_groups()234    jsonvalues = json.loads(output)235    verify(len(jsonvalues) == tag, 1,236           "iscsi_get_initiator_groups returned {} groups, expected {}".format(len(jsonvalues), tag))237    tag_list = []238    for idx, value in enumerate(jsonvalues):239        verify(value['initiators'][0] == rpc_param['initiator_name'], 1,240               "initiator value is {}, expected {}".format(value['initiators'][0], rpc_param['initiator_name']))241        tag_list.append(value['tag'])242        verify(value['tag'] == idx + 1, 1,243               "tag value is {}, expected {}".format(value['tag'], idx + 1))244        verify(value['netmasks'][0] == rpc_param['netmask'][idx], 1,245               "netmasks value is {}, expected {}".format(value['netmasks'][0], rpc_param['netmask'][idx]))246    for idx, value in enumerate(tag_list):247        rpc.iscsi_delete_initiator_group(value)248        output = rpc.iscsi_get_initiator_groups()249        jsonvalues = json.loads(output)250        verify(len(jsonvalues) == (len(tag_list) - (idx + 1)), 1,251               "iscsi_get_initiator_groups returned {} groups, expected {}".format(len(jsonvalues), (len(tag_list) - (idx + 1))))252        if not jsonvalues:253            break254        for jidx, jvalue in enumerate(jsonvalues):255            verify(jvalue['initiators'][0] == rpc_param['initiator_name'], 1,256                   "initiator value is {}, expected {}".format(jvalue['initiators'][0], rpc_param['initiator_name']))257            verify(jvalue['tag'] != value or jvalue['tag'] == tag_list[idx + jidx + 1], 1,258                   "tag value is {}, expected {} and not {}".format(jvalue['tag'], tag_list[idx + jidx + 1], value))259            verify(jvalue['netmasks'][0] == rpc_param['netmask'][idx + jidx + 1], 1,260                   "netmasks value is {}, expected {}".format(jvalue['netmasks'][0], rpc_param['netmask'][idx + jidx + 1]))261    print("verify_initiator_groups_rpc_method passed.")262def verify_target_nodes_rpc_methods(rpc_py, rpc_param):263    rpc = spdk_rpc(rpc_py)264    output = rpc.iscsi_get_options()265    jsonvalues = json.loads(output)266    nodebase = jsonvalues['node_base']267    output = rpc.iscsi_get_target_nodes()268    jsonvalues = json.loads(output)269    verify(not jsonvalues, 1,270           "iscsi_get_target_nodes returned {}, expected empty".format(jsonvalues))271    rpc.bdev_malloc_create(rpc_param['malloc_bdev_size'], rpc_param['malloc_block_size'])272    rpc.iscsi_create_portal_group(portal_tag, "{}:{}".format(rpc_param['target_ip'], str(rpc_param['port'])))273    rpc.iscsi_create_initiator_group(initiator_tag, rpc_param['initiator_name'], rpc_param['netmask'])274    lun_mapping = "Malloc" + str(rpc_param['lun_total']) + ":0"275    net_mapping = portal_tag + ":" + initiator_tag276    rpc.iscsi_create_target_node(rpc_param['target_name'], rpc_param['alias_name'], lun_mapping,277                                 net_mapping, rpc_param['queue_depth'], '-d')278    output = rpc.iscsi_get_target_nodes()279    jsonvalues = json.loads(output)280    verify(len(jsonvalues) == 1, 1,281           "iscsi_get_target_nodes returned {} nodes, expected 1".format(len(jsonvalues)))282    bdev_name = jsonvalues[0]['luns'][0]['bdev_name']283    verify(bdev_name == "Malloc" + str(rpc_param['lun_total']), 1,284           "bdev_name value is {}, expected Malloc{}".format(jsonvalues[0]['luns'][0]['bdev_name'], str(rpc_param['lun_total'])))285    name = jsonvalues[0]['name']286    verify(name == nodebase + ":" + rpc_param['target_name'], 1,287           "target name value is {}, expected {}".format(name, nodebase + ":" + rpc_param['target_name']))288    verify(jsonvalues[0]['alias_name'] == rpc_param['alias_name'], 1,289           "target alias_name value is {}, expected {}".format(jsonvalues[0]['alias_name'], rpc_param['alias_name']))290    verify(jsonvalues[0]['luns'][0]['lun_id'] == 0, 1,291           "lun id value is {}, expected 0".format(jsonvalues[0]['luns'][0]['lun_id']))292    verify(jsonvalues[0]['pg_ig_maps'][0]['ig_tag'] == int(initiator_tag), 1,293           "initiator group tag value is {}, expected {}".format(jsonvalues[0]['pg_ig_maps'][0]['ig_tag'], initiator_tag))294    verify(jsonvalues[0]['queue_depth'] == rpc_param['queue_depth'], 1,295           "queue depth value is {}, expected {}".format(jsonvalues[0]['queue_depth'], rpc_param['queue_depth']))296    verify(jsonvalues[0]['pg_ig_maps'][0]['pg_tag'] == int(portal_tag), 1,297           "portal group tag value is {}, expected {}".format(jsonvalues[0]['pg_ig_maps'][0]['pg_tag'], portal_tag))298    verify(jsonvalues[0]['disable_chap'] == rpc_param['disable_chap'], 1,299           "disable chap value is {}, expected {}".format(jsonvalues[0]['disable_chap'], rpc_param['disable_chap']))300    verify(jsonvalues[0]['mutual_chap'] == rpc_param['mutual_chap'], 1,301           "chap mutual value is {}, expected {}".format(jsonvalues[0]['mutual_chap'], rpc_param['mutual_chap']))302    verify(jsonvalues[0]['require_chap'] == rpc_param['require_chap'], 1,303           "chap required value is {}, expected {}".format(jsonvalues[0]['require_chap'], rpc_param['require_chap']))304    verify(jsonvalues[0]['chap_group'] == rpc_param['chap_group'], 1,305           "chap auth group value is {}, expected {}".format(jsonvalues[0]['chap_group'], rpc_param['chap_group']))306    verify(jsonvalues[0]['header_digest'] == rpc_param['header_digest'], 1,307           "header digest value is {}, expected {}".format(jsonvalues[0]['header_digest'], rpc_param['header_digest']))308    verify(jsonvalues[0]['data_digest'] == rpc_param['data_digest'], 1,309           "data digest value is {}, expected {}".format(jsonvalues[0]['data_digest'], rpc_param['data_digest']))310    lun_id = '1'311    rpc.iscsi_target_node_add_lun(name, bdev_name, "-i", lun_id)312    output = rpc.iscsi_get_target_nodes()313    jsonvalues = json.loads(output)314    verify(jsonvalues[0]['luns'][1]['bdev_name'] == "Malloc" + str(rpc_param['lun_total']), 1,315           "bdev_name value is {}, expected Malloc{}".format(jsonvalues[0]['luns'][0]['bdev_name'], str(rpc_param['lun_total'])))316    verify(jsonvalues[0]['luns'][1]['lun_id'] == 1, 1,317           "lun id value is {}, expected 1".format(jsonvalues[0]['luns'][1]['lun_id']))318    rpc.iscsi_delete_target_node(name)319    output = rpc.iscsi_get_target_nodes()320    jsonvalues = json.loads(output)321    verify(not jsonvalues, 1,322           "iscsi_get_target_nodes returned {}, expected empty".format(jsonvalues))323    rpc.iscsi_create_target_node(rpc_param['target_name'], rpc_param['alias_name'], lun_mapping,324                                 net_mapping, rpc_param['queue_depth'], '-d')325    rpc.iscsi_delete_portal_group(portal_tag)326    rpc.iscsi_delete_initiator_group(initiator_tag)327    rpc.iscsi_delete_target_node(name)328    output = rpc.iscsi_get_target_nodes()329    jsonvalues = json.loads(output)330    if not jsonvalues:331        print("This issue will be fixed later.")332    print("verify_target_nodes_rpc_methods passed.")333def help_get_interface_ip_list(rpc_py, nic_name):334    rpc = spdk_rpc(rpc_py)335    nics = json.loads(rpc.net_get_interfaces())336    nic = list([x for x in nics if x["name"] == nic_name])337    verify(len(nic) != 0, 1,338           "Nic name: {} is not found in {}".format(nic_name, [x["name"] for x in nics]))339    return nic[0]["ip_addr"]340if __name__ == "__main__":341    rpc_py = sys.argv[1]342    try:343        verify_log_flag_rpc_methods(rpc_py, rpc_param)344        create_malloc_bdevs_rpc_methods(rpc_py, rpc_param)345        verify_portal_groups_rpc_methods(rpc_py, rpc_param)346        verify_initiator_groups_rpc_methods(rpc_py, rpc_param)347        verify_target_nodes_rpc_methods(rpc_py, rpc_param)348        verify_scsi_devices_rpc_methods(rpc_py)...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
