def _run_cancelable(self, ps_code):
        """
        :type ps_code: str
        """
        self.logger.debug('PowerShellScript:' + ps_code)

        bat_code = 'powershell -encodedcommand %s' % base64.b64encode(ps_code.encode('utf_16_le')).decode('ascii')
        shell_id = self.session.protocol.open_shell()
        command_id = self.session.protocol.run_command(shell_id, bat_code)

        async_result = self.pool.apply_async(self.session.protocol.get_command_output, kwds={'shell_id': shell_id, 'command_id': command_id})
        try:
            while not async_result.ready():
                if self.cancel_sampler.is_cancelled():
                    self.cancel_sampler.throw()
                time.sleep(1)
            result = winrm.Response(async_result.get())
        finally:
            self.session.protocol.cleanup_command(shell_id, command_id)
            self.session.protocol.close_shell(shell_id)

        self.logger.debug('ReturnedCode:' + str(result.status_code))
        self.logger.debug('Stdout:' + result.std_out)
        self.logger.debug('Stderr:' + result.std_err)
        result.std_err = self._try_decode_error_xml(result.std_err)
        self.logger.debug('Stderr(Decoded):' + result.std_err)
        return result
Exemple #2
0
 def run_cmd(self, command, args=(), env=None):
     shell_id = self.protocol.open_shell(env_vars=env)
     command_id = self.protocol.run_command(shell_id, command, args)
     rs = winrm.Response(self.protocol.get_command_output(shell_id, command_id))
     self.protocol.cleanup_command(shell_id, command_id)
     self.protocol.close_shell(shell_id)
     return rs
 def test_cat_on_windows(self):
     env = JujuData("an-env", {"type": "nonlocal"})
     client = ModelClient(env, None, None)
     unit = "a-application/0"
     with patch.object(client, "get_status", autospec=True) as st:
         st.return_value = Status.from_text(self.win2012hvr2_status_output)
         response = winrm.Response(("contents of /a/file", "", 0))
         remote = remote_from_unit(client, unit)
         with patch.object(remote.session,
                           "run_cmd",
                           autospec=True,
                           return_value=response) as mock_run:
             output = remote.cat("/a/file")
             self.assertEqual(output, "contents of /a/file")
     st.assert_called_once_with()
     mock_run.assert_called_once_with("type", ["/a/file"])
 def _run_cmd(self,
              action_result,
              cmd,
              args=None,
              parse_callback=pc.basic,
              additional_data=None,
              async_=False,
              command_id=None,
              shell_id=None):
     # The parser callback should have the function signature (ActionResult, winrm.Result) -> bool
     # The additional_data is a dictionary which will be passed to the parser, in which case the signature should be
     #  (ActionResult, winrm.Result, **kwargs) -> bool
     # async_ will start the command and return what you need to get the results later (command_id and shell_id)
     # you /could/ pass a command_id and shell_id from an async powershell script run here (and vice versa),
     #  but there is some additional data
     #  cleanup which goes on after running a powershell script which wont happen here, so its best not to
     if additional_data is None:
         additional_data = {}
     resp = None
     try:
         if command_id:
             if shell_id is None:
                 return action_result.set_status(
                     phantom.APP_ERROR,
                     "Must specify shell_id with command_id")
             resp = winrm.Response(
                 self._protocol.get_command_output(shell_id, command_id))
             self._protocol.close_shell(shell_id)
         elif async_:
             shell_id = self._protocol.open_shell()
             command_id = self._protocol.run_command(shell_id, cmd, args)
             summary = action_result.set_summary({})
             summary['shell_id'] = shell_id
             summary['command_id'] = command_id
             return phantom.APP_SUCCESS
         else:
             resp = self._session.run_cmd(cmd, args)
     except Exception as e:
         return action_result.set_status(
             phantom.APP_ERROR, "Error running command: {}".format(str(e)))
     if resp is None:
         # The exception will probably catch this
         self.debug_print("Error: _run_cmd is missing parameters")
         return action_result.set_status(
             phantom.APP_ERROR, "Unknown error while running command")
     return parse_callback(action_result, resp, **additional_data)
 def _run_ps(self,
             action_result,
             script,
             parse_callback=pc.basic,
             additional_data=None,
             async_=False,
             command_id=None,
             shell_id=None):
     if additional_data is None:
         additional_data = {}
     resp = None
     try:
         if command_id:
             if shell_id is None:
                 return action_result.set_status(
                     phantom.APP_ERROR,
                     "Must specify shell_id with command_id")
             resp = winrm.Response(
                 self._protocol.get_command_output(shell_id, command_id))
             self._protocol.close_shell(shell_id)
             if len(resp.std_err):
                 resp.std_err = self._session._clean_error_msg(resp.std_err)
         elif async_:
             encoded_ps = b64encode(
                 script.encode('utf_16_le')).decode('ascii')
             shell_id = self._protocol.open_shell()
             command_id = self._protocol.run_command(
                 shell_id,
                 'powershell -encodedcommand {0}'.format(encoded_ps))
             summary = action_result.set_summary({})
             summary['shell_id'] = shell_id
             summary['command_id'] = command_id
             return phantom.APP_SUCCESS
         else:
             resp = self._session.run_ps(script)
     except Exception as e:
         return action_result.set_status(
             phantom.APP_ERROR,
             "Error running PowerShell script: {}".format(str(e)))
     if resp is None:
         self.debug_print("Error: _run_ps is missing parameters")
         return action_result.set_status(
             phantom.APP_ERROR,
             "Unknown error while running PowerShell script")
     return parse_callback(action_result, resp, **additional_data)
 def test_run_cmd(self):
     env = JujuData("an-env", {"type": "nonlocal"})
     client = ModelClient(env, None, None)
     unit = "a-application/0"
     with patch.object(client, "get_status", autospec=True) as st:
         st.return_value = Status.from_text(self.win2012hvr2_status_output)
         response = winrm.Response(("some out", "some err", 0))
         remote = remote_from_unit(client, unit)
         with patch.object(remote.session,
                           "run_cmd",
                           autospec=True,
                           return_value=response) as mock_run:
             output = remote.run_cmd(
                 ["C:\\Program Files\\bin.exe", "/IN", "Bob's Stuff"])
             self.assertEqual(output, response)
     st.assert_called_once_with()
     mock_run.assert_called_once_with('"C:\\Program Files\\bin.exe"',
                                      ['/IN "Bob\'s Stuff"'])
 def test_copy_on_windows(self):
     env = JujuData("an-env", {"type": "nonlocal"})
     client = ModelClient(env, None, None)
     unit = "a-application/0"
     dest = "/local/path"
     with patch.object(client, "get_status", autospec=True) as st:
         st.return_value = Status.from_text(self.win2012hvr2_status_output)
         response = winrm.Response(("fake output", "", 0))
         remote = remote_from_unit(client, unit)
         with patch.object(remote.session,
                           "run_ps",
                           autospec=True,
                           return_value=response) as mock_run:
             with patch.object(remote,
                               "_encoded_copy_to_dir",
                               autospec=True) as mock_cpdir:
                 remote.copy(dest, ["C:\\logs\\*", "%APPDATA%\\*.log"])
     mock_cpdir.assert_called_once_with(dest, "fake output")
     st.assert_called_once_with()
     self.assertEquals(mock_run.call_count, 1)
     self.assertRegexpMatches(mock_run.call_args[0][0],
                              r'.*"C:\\logs\\[*]","%APPDATA%\\[*].log".*')
Exemple #8
0
 def cmd(self, cmd, *args):
     command_id = self.protocol.run_command(self.shell_id, cmd, args)
     result = winrm.Response(
         self.protocol.get_command_output(self.shell_id, command_id))
     self.protocol.cleanup_command(self.shell_id, command_id)
     return result