improve keepalive, logging and output

This commit is contained in:
fluzzi 2022-05-25 17:25:02 -03:00
parent 38eb2e2d37
commit 2aa4934288
3 changed files with 144 additions and 154 deletions

View File

@ -1,2 +1,2 @@
__version__ = "2.1.2" __version__ = "2.1.3"

View File

@ -6,12 +6,13 @@ import pexpect
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP from Crypto.Cipher import PKCS1_OAEP
import ast import ast
from time import sleep from time import sleep,time
import datetime import datetime
import sys import sys
import threading import threading
from pathlib import Path from pathlib import Path
from copy import deepcopy from copy import deepcopy
import io
#functions and classes #functions and classes
@ -154,6 +155,22 @@ class node:
else: else:
return t return t
def _filter(self, a):
#Set time for last input when using interact
self.lastinput = time()
return a
def _keepalive(self):
#Send keepalive ctrl+e when idletime passed without new inputs on interact
self.lastinput = time()
t = threading.currentThread()
while True:
if time() - self.lastinput >= self.idletime:
self.child.sendcontrol("e")
self.lastinput = time()
sleep(1)
def interact(self, debug = False): def interact(self, debug = False):
''' '''
Allow user to interact with the node directly, mostly used by connection manager. Allow user to interact with the node directly, mostly used by connection manager.
@ -169,14 +186,24 @@ class node:
self.child.setwinsize(int(size.group(2)),int(size.group(1))) self.child.setwinsize(int(size.group(2)),int(size.group(1)))
print("Connected to " + self.unique + " at " + self.host + (":" if self.port != '' else '') + self.port + " via: " + self.protocol) print("Connected to " + self.unique + " at " + self.host + (":" if self.port != '' else '') + self.port + " via: " + self.protocol)
if 'logfile' in dir(self): if 'logfile' in dir(self):
self.child.logfile_read = open(self.logfile, "wb") if not 'mylog' in dir(self):
elif debug: self.mylog = io.BytesIO()
self.child.logfile_read = None self.child.logfile_read = self.mylog
if 'missingtext' in dir(self): if 'missingtext' in dir(self):
print(self.child.after.decode(), end='') print(self.child.after.decode(), end='')
self.child.interact() if self.idletime > 0:
if "logfile" in dir(self) and not debug: x = threading.Thread(target=self._keepalive)
self._logclean(self.logfile) x.daemon = True
x.start()
if debug:
print(self.mylog.getvalue().decode())
self.child.interact(input_filter=self._filter)
if "logfile" in dir(self):
output = self._logclean(self.mylog.getvalue().decode(), True)
with open(self.logfile, "w") as f:
f.write(output)
f.close()
else: else:
print(connect) print(connect)
exit(1) exit(1)
@ -229,30 +256,19 @@ class node:
status = '' status = ''
if not isinstance(commands, list): if not isinstance(commands, list):
commands = [commands] commands = [commands]
self.mylog = io.BytesIO()
self.child.logfile_read = self.mylog
for c in commands: for c in commands:
if vars is not None: if vars is not None:
c = c.format(**vars) c = c.format(**vars)
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c) self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2: if result == 2:
output = output + self.child.before.decode()
status = 2
break break
if not status == 2: if not result == 2:
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2:
output = output + self.child.before.decode()
status = 2
self.child.close() self.child.close()
output = self._logclean(output, True) output = self._logclean(self.mylog.getvalue().decode(), True)
if stdout == True: if stdout == True:
print(output) print(output)
if folder != '': if folder != '':
@ -260,7 +276,7 @@ class node:
f.write(output) f.write(output)
f.close() f.close()
self.output = output self.output = output
if status == 2: if result == 2:
self.status = 2 self.status = 2
else: else:
self.status = 0 self.status = 0
@ -321,48 +337,34 @@ class node:
output = '' output = ''
if not isinstance(commands, list): if not isinstance(commands, list):
commands = [commands] commands = [commands]
self.mylog = io.BytesIO()
self.child.logfile_read = self.mylog
for c in commands: for c in commands:
if vars is not None: if vars is not None:
c = c.format(**vars) c = c.format(**vars)
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c) self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2: if result == 2:
output = output + self.child.before.decode() result = 3
self.result = None break
self.output = self._logclean(output, True) if not result == 3:
self.status = 2 if vars is not None:
return self.output expected = expected.format(**vars)
if vars is not None: expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
expected = expected.format(**vars) result = self.child.expect(expects, timeout = timeout)
expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
results = self.child.expect(expects, timeout = timeout)
self.child.close() self.child.close()
if results == 0: output = self._logclean(self.mylog.getvalue().decode(), True)
self.output = output
if result == 0:
self.result = True self.result = True
output = output + self.child.before.decode() + self.child.after.decode()
output = self._logclean(output, True)
self.output = output
self.status = 0 self.status = 0
return True return True
if results in [1, 2]: if result in [1, 2]:
self.result = False self.result = False
if results == 1:
output = output + self.child.before.decode() + self.child.after.decode()
elif results == 2:
output = output + self.child.before.decode()
output = self._logclean(output, True)
self.output = output
self.status = 0 self.status = 0
return False return False
if results == 3: if result == 3:
self.result = None self.result = None
output = output + self.child.before.decode()
output = self._logclean(output, True)
self.output = output
self.status = 2 self.status = 2
return output return output
else: else:
@ -410,7 +412,8 @@ class node:
child = pexpect.spawn(cmd) child = pexpect.spawn(cmd)
if debug: if debug:
print(cmd) print(cmd)
child.logfile_read = sys.stdout.buffer self.mylog = io.BytesIO()
child.logfile_read = self.mylog
if len(passwords) > 0: if len(passwords) > 0:
loops = len(passwords) loops = len(passwords)
else: else:

View File

@ -2000,6 +2000,22 @@ tasks:
else: else:
return t return t
def _filter(self, a):
#Set time for last input when using interact
self.lastinput = time()
return a
def _keepalive(self):
#Send keepalive ctrl+e when idletime passed without new inputs on interact
self.lastinput = time()
t = threading.currentThread()
while True:
if time() - self.lastinput >= self.idletime:
self.child.sendcontrol("e")
self.lastinput = time()
sleep(1)
def interact(self, debug = False): def interact(self, debug = False):
''' '''
Allow user to interact with the node directly, mostly used by connection manager. Allow user to interact with the node directly, mostly used by connection manager.
@ -2015,14 +2031,24 @@ tasks:
self.child.setwinsize(int(size.group(2)),int(size.group(1))) self.child.setwinsize(int(size.group(2)),int(size.group(1)))
print("Connected to " + self.unique + " at " + self.host + (":" if self.port != '' else '') + self.port + " via: " + self.protocol) print("Connected to " + self.unique + " at " + self.host + (":" if self.port != '' else '') + self.port + " via: " + self.protocol)
if 'logfile' in dir(self): if 'logfile' in dir(self):
self.child.logfile_read = open(self.logfile, "wb") if not 'mylog' in dir(self):
elif debug: self.mylog = io.BytesIO()
self.child.logfile_read = None self.child.logfile_read = self.mylog
if 'missingtext' in dir(self): if 'missingtext' in dir(self):
print(self.child.after.decode(), end='') print(self.child.after.decode(), end='')
self.child.interact() if self.idletime > 0:
if "logfile" in dir(self) and not debug: x = threading.Thread(target=self._keepalive)
self._logclean(self.logfile) x.daemon = True
x.start()
if debug:
print(self.mylog.getvalue().decode())
self.child.interact(input_filter=self._filter)
if "logfile" in dir(self):
output = self._logclean(self.mylog.getvalue().decode(), True)
with open(self.logfile, "w") as f:
f.write(output)
f.close()
else: else:
print(connect) print(connect)
exit(1) exit(1)
@ -2075,30 +2101,19 @@ tasks:
status = '' status = ''
if not isinstance(commands, list): if not isinstance(commands, list):
commands = [commands] commands = [commands]
self.mylog = io.BytesIO()
self.child.logfile_read = self.mylog
for c in commands: for c in commands:
if vars is not None: if vars is not None:
c = c.format(**vars) c = c.format(**vars)
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c) self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2: if result == 2:
output = output + self.child.before.decode()
status = 2
break break
if not status == 2: if not result == 2:
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2:
output = output + self.child.before.decode()
status = 2
self.child.close() self.child.close()
output = self._logclean(output, True) output = self._logclean(self.mylog.getvalue().decode(), True)
if stdout == True: if stdout == True:
print(output) print(output)
if folder != '': if folder != '':
@ -2106,7 +2121,7 @@ tasks:
f.write(output) f.write(output)
f.close() f.close()
self.output = output self.output = output
if status == 2: if result == 2:
self.status = 2 self.status = 2
else: else:
self.status = 0 self.status = 0
@ -2167,48 +2182,34 @@ tasks:
output = '' output = ''
if not isinstance(commands, list): if not isinstance(commands, list):
commands = [commands] commands = [commands]
self.mylog = io.BytesIO()
self.child.logfile_read = self.mylog
for c in commands: for c in commands:
if vars is not None: if vars is not None:
c = c.format(**vars) c = c.format(**vars)
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c) self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2: if result == 2:
output = output + self.child.before.decode() result = 3
self.result = None break
self.output = self._logclean(output, True) if not result == 3:
self.status = 2 if vars is not None:
return self.output expected = expected.format(**vars)
if vars is not None: expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
expected = expected.format(**vars) result = self.child.expect(expects, timeout = timeout)
expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
results = self.child.expect(expects, timeout = timeout)
self.child.close() self.child.close()
if results == 0: output = self._logclean(self.mylog.getvalue().decode(), True)
self.output = output
if result == 0:
self.result = True self.result = True
output = output + self.child.before.decode() + self.child.after.decode()
output = self._logclean(output, True)
self.output = output
self.status = 0 self.status = 0
return True return True
if results in [1, 2]: if result in [1, 2]:
self.result = False self.result = False
if results == 1:
output = output + self.child.before.decode() + self.child.after.decode()
elif results == 2:
output = output + self.child.before.decode()
output = self._logclean(output, True)
self.output = output
self.status = 0 self.status = 0
return False return False
if results == 3: if result == 3:
self.result = None self.result = None
output = output + self.child.before.decode()
output = self._logclean(output, True)
self.output = output
self.status = 2 self.status = 2
return output return output
else: else:
@ -2256,7 +2257,8 @@ tasks:
child = pexpect.spawn(cmd) child = pexpect.spawn(cmd)
if debug: if debug:
print(cmd) print(cmd)
child.logfile_read = sys.stdout.buffer self.mylog = io.BytesIO()
child.logfile_read = self.mylog
if len(passwords) > 0: if len(passwords) > 0:
loops = len(passwords) loops = len(passwords)
else: else:
@ -2326,14 +2328,24 @@ tasks:
self.child.setwinsize(int(size.group(2)),int(size.group(1))) self.child.setwinsize(int(size.group(2)),int(size.group(1)))
print("Connected to " + self.unique + " at " + self.host + (":" if self.port != '' else '') + self.port + " via: " + self.protocol) print("Connected to " + self.unique + " at " + self.host + (":" if self.port != '' else '') + self.port + " via: " + self.protocol)
if 'logfile' in dir(self): if 'logfile' in dir(self):
self.child.logfile_read = open(self.logfile, "wb") if not 'mylog' in dir(self):
elif debug: self.mylog = io.BytesIO()
self.child.logfile_read = None self.child.logfile_read = self.mylog
if 'missingtext' in dir(self): if 'missingtext' in dir(self):
print(self.child.after.decode(), end='') print(self.child.after.decode(), end='')
self.child.interact() if self.idletime > 0:
if "logfile" in dir(self) and not debug: x = threading.Thread(target=self._keepalive)
self._logclean(self.logfile) x.daemon = True
x.start()
if debug:
print(self.mylog.getvalue().decode())
self.child.interact(input_filter=self._filter)
if "logfile" in dir(self):
output = self._logclean(self.mylog.getvalue().decode(), True)
with open(self.logfile, "w") as f:
f.write(output)
f.close()
else: else:
print(connect) print(connect)
exit(1)</code></pre> exit(1)</code></pre>
@ -2427,30 +2439,19 @@ tasks:
status = &#39;&#39; status = &#39;&#39;
if not isinstance(commands, list): if not isinstance(commands, list):
commands = [commands] commands = [commands]
self.mylog = io.BytesIO()
self.child.logfile_read = self.mylog
for c in commands: for c in commands:
if vars is not None: if vars is not None:
c = c.format(**vars) c = c.format(**vars)
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c) self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2: if result == 2:
output = output + self.child.before.decode()
status = 2
break break
if not status == 2: if not result == 2:
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2:
output = output + self.child.before.decode()
status = 2
self.child.close() self.child.close()
output = self._logclean(output, True) output = self._logclean(self.mylog.getvalue().decode(), True)
if stdout == True: if stdout == True:
print(output) print(output)
if folder != &#39;&#39;: if folder != &#39;&#39;:
@ -2458,7 +2459,7 @@ tasks:
f.write(output) f.write(output)
f.close() f.close()
self.output = output self.output = output
if status == 2: if result == 2:
self.status = 2 self.status = 2
else: else:
self.status = 0 self.status = 0
@ -2560,48 +2561,34 @@ tasks:
output = &#39;&#39; output = &#39;&#39;
if not isinstance(commands, list): if not isinstance(commands, list):
commands = [commands] commands = [commands]
self.mylog = io.BytesIO()
self.child.logfile_read = self.mylog
for c in commands: for c in commands:
if vars is not None: if vars is not None:
c = c.format(**vars) c = c.format(**vars)
result = self.child.expect(expects, timeout = timeout) result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c) self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
if result == 2: if result == 2:
output = output + self.child.before.decode() result = 3
self.result = None break
self.output = self._logclean(output, True) if not result == 3:
self.status = 2 if vars is not None:
return self.output expected = expected.format(**vars)
if vars is not None: expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
expected = expected.format(**vars) result = self.child.expect(expects, timeout = timeout)
expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
results = self.child.expect(expects, timeout = timeout)
self.child.close() self.child.close()
if results == 0: output = self._logclean(self.mylog.getvalue().decode(), True)
self.output = output
if result == 0:
self.result = True self.result = True
output = output + self.child.before.decode() + self.child.after.decode()
output = self._logclean(output, True)
self.output = output
self.status = 0 self.status = 0
return True return True
if results in [1, 2]: if result in [1, 2]:
self.result = False self.result = False
if results == 1:
output = output + self.child.before.decode() + self.child.after.decode()
elif results == 2:
output = output + self.child.before.decode()
output = self._logclean(output, True)
self.output = output
self.status = 0 self.status = 0
return False return False
if results == 3: if result == 3:
self.result = None self.result = None
output = output + self.child.before.decode()
output = self._logclean(output, True)
self.output = output
self.status = 2 self.status = 2
return output return output
else: else: