Skip to content

Commit

Permalink
fixing encoding error
Browse files Browse the repository at this point in the history
  • Loading branch information
ltamaster committed May 10, 2019
1 parent f47b27e commit 5e78db3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 22 deletions.
18 changes: 3 additions & 15 deletions contents/winrm-exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import requests.packages.urllib3
import winrm_session
import threading
import traceback
import winrm
import logging
import colored_formatter
Expand Down Expand Up @@ -140,7 +139,7 @@
lastpos = 0
lasterrorpos = 0

charset = "Windows-1252"
charset = "utf-8"
if "RD_NODE_CHARSET" in os.environ:
charset = os.getenv("RD_NODE_CHARSET")

Expand All @@ -157,18 +156,6 @@

lastpos = sys.stdout.tell()

if sys.stderr.tell() != lasterrorpos:
try:
sys.stderr.seek(lasterrorpos)
errorread=session._clean_error_msg(sys.stderr.read())
if isinstance(errorread, str):
realstderr.write(errorread)
else:
realstderr.write(errorread.decode(charset))
lasterrorpos = sys.stderr.tell()
except Exception as e:
traceback.print_exc(file=sys.stdout)

if not t.is_alive():
break

Expand All @@ -178,7 +165,8 @@
sys.stderr = realstderr

if tsk.e_std:
sys.stderr.write("Execution finished with the following error")
log.error("Execution finished with the following error")
log.error(tsk.e_std)
sys.exit(1)
else:
sys.exit(tsk.stat)
55 changes: 48 additions & 7 deletions contents/winrm_session.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from __future__ import unicode_literals
from base64 import b64encode
import xml.etree.ElementTree as ET
try:
from StringIO import StringIO
Expand All @@ -11,16 +10,39 @@
from io import BytesIO

import protocol
import winrm
import base64
import sys
import types

PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3
PY34 = sys.version_info[0:2] >= (3, 4)

if PY3:
string_types = str,
integer_types = int,
class_types = type,
text_type = str
binary_type = bytes

MAXSIZE = sys.maxsize
else:
string_types = basestring,
integer_types = (int, long)
class_types = (type, types.ClassType)
text_type = unicode
binary_type = str


# TODO: this PR https://github.com/diyan/pywinrm/pull/55 will add this fix.
# when this PR is merged, this won't be needed anymore
def run_cmd(self, command, args=(), out_stream=None, err_stream=None):

self.protocol.get_command_output = protocol.get_command_output
winrm.Session._clean_error_msg = self._clean_error_msg

# TODO optimize perf. Do not call open/close shell every time
shell_id = self.protocol.open_shell()
shell_id = self.protocol.open_shell(codepage=65001)
command_id = self.protocol.run_command(shell_id, command, args)
rs = Response(self.protocol.get_command_output(self.protocol, shell_id, command_id, out_stream, err_stream))

Expand All @@ -36,17 +58,16 @@ def run_ps(self, script, out_stream=None, err_stream=None):
"""base64 encodes a Powershell script and executes the powershell
encoded script command
"""
# must use utf16 little endian on windows
encoded_ps = b64encode(script.encode('utf_16_le')).decode('ascii')
script = to_text(script)
encoded_ps = base64.b64encode(script.encode('utf_16_le')).decode('ascii')
rs = self.run_cmd('powershell -encodedcommand {0}'.format(encoded_ps),out_stream=out_stream, err_stream=err_stream)

return rs


def _clean_error_msg(self, msg):
#data=""
if isinstance(msg, bytes):
msg = msg.decode('utf-8', errors="ignore")
msg = to_text(msg)

if msg.startswith("#< CLIXML") or "<Objs Version=" in msg or "-1</PI><PC>" in msg:
# for proper xml, we need to remove the CLIXML part
Expand Down Expand Up @@ -114,3 +135,23 @@ def get_response(self):
except Exception as e:
self.e_std = e
self.stat=-1


def to_text(obj, encoding='utf-8', errors="ignore"):
if isinstance(obj, text_type):
return obj

if isinstance(obj, binary_type):
return obj.decode(encoding, errors)


def to_bytes(obj, encoding='utf-8', errors="ignore"):
if isinstance(obj, binary_type):
return obj

if isinstance(obj, text_type):
try:
# Try this first as it's the fastest
return obj.encode(encoding, errors)
except UnicodeEncodeError:
raise

0 comments on commit 5e78db3

Please sign in to comment.