Class: PSRP::WSMV::CommandOutputProcessor
- Inherits:
-
Object
- Object
- PSRP::WSMV::CommandOutputProcessor
- Defined in:
- lib/wsmv/command_output_processor.rb
Overview
Class to handle getting all the output of a command until it completes
Constant Summary collapse
- INPUT_REQUIRED =
[ PSRP::Message::MESSAGE_TYPES[:PIPELINE_HOST_CALL], PSRP::Message::MESSAGE_TYPES[:RUNSPACEPOOL_HOST_CALL] ]
Instance Attribute Summary collapse
-
#msgs ⇒ Object
readonly
Returns the value of attribute msgs.
Instance Method Summary collapse
- #command_done? ⇒ Boolean
-
#command_output(shell_id, command_id, reset = false) ⇒ Object
Gets the command output from the remote shell.
- #command_output_message(shell_id, command_id) ⇒ Object
-
#decode(raw_output) ⇒ String
The decoded output.
-
#defragmented ⇒ Object
Defragment Messages.
- #exit_code(resp_doc) ⇒ Object
- #has_error? ⇒ Boolean
-
#initialize(connection_opts, transport, out_opts = {}) ⇒ CommandOutputProcessor
constructor
Creates a new command output processor.
- #input_required? ⇒ Boolean
- #send_get_output_message(message) ⇒ Object
- #streams(resp_doc) ⇒ Object
Constructor Details
#initialize(connection_opts, transport, out_opts = {}) ⇒ CommandOutputProcessor
Creates a new command output processor
37 38 39 40 41 42 43 44 45 |
# File 'lib/wsmv/command_output_processor.rb', line 37 def initialize(connection_opts, transport, out_opts = {}) @connection_opts = connection_opts @transport = transport @out_opts = out_opts @has_error = false @command_done = false @input_required = false @msgs = {} end |
Instance Attribute Details
#msgs ⇒ Object (readonly)
Returns the value of attribute msgs.
26 27 28 |
# File 'lib/wsmv/command_output_processor.rb', line 26 def msgs @msgs end |
Instance Method Details
#command_done? ⇒ Boolean
139 140 141 |
# File 'lib/wsmv/command_output_processor.rb', line 139 def command_done? @command_done end |
#command_output(shell_id, command_id, reset = false) ⇒ Object
Gets the command output from the remote shell
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/wsmv/command_output_processor.rb', line 51 def command_output(shell_id, command_id, reset = false) if reset == true @has_error = false @command_done = false @input_required = false end = (shell_id, command_id) resp_doc = () streams(resp_doc) @command_done = REXML::XPath.match( resp_doc, "//*[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/" \ "CommandState/Done']").any? resp_doc end |
#command_output_message(shell_id, command_id) ⇒ Object
68 69 70 71 72 73 74 75 76 |
# File 'lib/wsmv/command_output_processor.rb', line 68 def (shell_id, command_id) cmd_out_opts = { shell_id: shell_id }.merge(@out_opts) if command_id cmd_out_opts[:command_id] = command_id end PSRP::WSMV::ReceiveOutput.new(@connection_opts, cmd_out_opts).build end |
#decode(raw_output) ⇒ String
Returns The decoded output.
147 148 149 150 |
# File 'lib/wsmv/command_output_processor.rb', line 147 def decode(raw_output) # TODO: Add better decoding based on MS-PSRP 2.2.5 PSRP::MessageDecoder.new(raw_output) end |
#defragmented ⇒ Object
Defragment Messages
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/wsmv/command_output_processor.rb', line 114 def defragmented datas = {} @msgs.each do |msg_id, msg_list| msg_list.sort do |a, b| a.fragment_id <=> b.fragment_id end unfragmented = msg_list.inject('') do |data, msg| data += msg.data end datas[msg_id] = { message_type: msg_list[0]., data: unfragmented, } end datas end |
#exit_code(resp_doc) ⇒ Object
93 94 95 |
# File 'lib/wsmv/command_output_processor.rb', line 93 def exit_code(resp_doc) REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:ExitCode").text.to_i end |
#has_error? ⇒ Boolean
131 132 133 |
# File 'lib/wsmv/command_output_processor.rb', line 131 def has_error? @has_error end |
#input_required? ⇒ Boolean
135 136 137 |
# File 'lib/wsmv/command_output_processor.rb', line 135 def input_required? @input_required end |
#send_get_output_message(message) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/wsmv/command_output_processor.rb', line 78 def () resp_doc = @transport.send_request() rescue PSRP::WSManFault => e # If no output is available before the wsman:OperationTimeout expires, # the server MUST return a WSManFault with the Code attribute equal to # 2150858793. When the client receives this fault, it SHOULD issue # another Receive request. # http://msdn.microsoft.com/en-us/library/cc251676.aspx if e.fault_code == '2150858793' retry else raise end end |
#streams(resp_doc) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/wsmv/command_output_processor.rb', line 97 def streams(resp_doc) REXML::XPath.match(resp_doc, "//#{PSRP::WSMV::NS_WIN_SHELL}:Stream").each do |n| next if n.text.nil? || n.text.empty? msg = decode(n.text) if not @msgs.has_key? msg. @msgs[msg.] = [] end @msgs[msg.].push(msg) if INPUT_REQUIRED.include? msg. @input_required = true elsif msg. == PSRP::Message::MESSAGE_TYPES[:ERROR_RECORD] @has_error = true end end end |