class ReauthenticatingKerberosSession: """ Wrapper around WinRM Session object that automatically tries to generate a new Kerberos token and session if authentication fails """ def _generate_kerberos_ticket(self): """ Tries to generate a new Kerberos ticket, through a call to kinit Raises an exception if the subprocess has non-zero exit code """ cmd = ["kinit", self._username] try: subprocess.run( cmd, check=True, input=self._password.encode(), stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, ) except subprocess.CalledProcessError as e: print(e.stderr.decode("utf-8")) raise def _create_new_session(self): """ Generate new internal session XXX: Session is not properly cleaned up when a command fails so we have to create a new internal session object each time """ self._session = Session(target=self._target, transport="kerberos", auth=(None, None)) def __init__(self, target: str, username: str, password: str): self._username = username self._password = password self._target = target self._create_new_session() def run_cmd(self, *args, **kwargs): try: rs = self._session.run_cmd(*args, **kwargs) except KerberosExchangeError: self._generate_kerberos_ticket() self._create_new_session() rs = self._session.run_cmd(*args, **kwargs) return rs def run_ps(self, *args, **kwargs): try: rs = self._session.run_ps(*args, **kwargs) except KerberosExchangeError: self._generate_kerberos_ticket() self._create_new_session() rs = self._session.run_ps(*args, **kwargs) return rs
def test_run_cmd(protocol_fake): s = Session('windows-host', auth=('john.smith', 'secret')) r = s.run_cmd('ipconfig', ['/all']) assert r.status_code == 0 assert 'Windows IP Configuration' in r.std_out assert len(r.std_err) == 0
def test_run_cmd(protocol_fake): # TODO this test should cover __init__ method s = Session('windows-host', auth=('john.smith', 'secret')) s.protocol = protocol_fake r = s.run_cmd('ipconfig', ['/all']) assert r.status_code == 0 assert b'Windows IP Configuration' in r.std_out assert len(r.std_err) == 0
#! /usr/bin/python from winrm import Session, Protocol print("Starting PyWinRM Script") host = input("hostname of windows with port: ") user = input("username of windows: ") password = input("password of windows: ") print("Running High Level API Test") s = Session(host, auth=(user, password)) r = s.run_cmd('ipconfig', ['/all']) print(r.std_out, r.std_err) print("Running Low Level API Test") p = Protocol(endpoint='http://' + host + '/wsman', transport='ntlm', username=user, password=password, server_cert_validation='ignore') shell_id = p.open_shell() command_id = p.run_command(shell_id, 'ipconfig', ['/all']) std_out, std_err, status_code = p.get_command_output(shell_id, command_id) p.cleanup_command(shell_id, command_id) p.close_shell(shell_id) print(std_out, std_err, status_code) print("Stopping PyWinRM Script")