Python + SSH Password auth (sin bibliotecas externas o claves públicas / privadas)?
Así que soy consciente de que puedes usarPexpect
para resolver el problema, pero me gustaría no confiar en bibliotecas adicionales para resolver el problema que no sean las suministradas con Python3.
También soy consciente de que generar claves públicas y permitirlas en el host remoto es ideal, pero eso es algo para lo que pretendo usar este script (configurar claves en el lugar correcto, etc.).
Esto es todo lo que he conseguido en "mío" con un montón de ayuda de la comunidad de SO. Estoy bastante atascado comprobando si el pseudo terminal hijo bifurcado se hace ejecutando lo que se supone que debe o no. Lo que significa que puedo decir si el SSH ha terminado de ejecutarse o no, ya que se mantendrá durante tanto tiempo como elrun()
La función está operando.
(mipid_exists
volveráTrue
durante el tiempo que esté dentro de la operación run (). Y si salgorun()
para que la sesión SSH no tenga tiempo suficiente para hacer lo que se supone que debe hacer)
#!/usr/bin/python
import pty, sys
from subprocess import Popen, PIPE, STDOUT
from time import sleep
from os.path import expanduser, abspath
from os import walk, setsid, fork, waitpid, execv, read, write, kill
def pid_exists(pid):
"""Check whether pid exists in the current process table."""
if pid < 0:
return False
try:
kill(pid, 0)
except (OSError, e):
return e.errno == errno.EPERMRM
else:
return True
class ssh():
def __init__(self, host, execute='echo "done" > /root/testing.txt', user='root', password=b'SuperPassword'):
self.exec = execute
self.host = host
self.user = user
self.password = password
self.run()
def run(self):
command = [
'/usr/bin/ssh',
self.user+'@'+self.host,
'-o', 'NumberOfPasswordPrompts=1',
self.exec,
]
# PID = 0 for child, and the PID of the child for the parent
pid, child_fd = pty.fork()
if not pid: # Child process
# Replace child process with our SSH process
execv(command[0], command)
while True:
output = read(child_fd, 1024).strip()
print(output)
lower = output.lower()
# Write the password
if b'password:' in lower:
write(child_fd, self.password + b'\n')
break
elif 'are you sure you want to continue connecting' in lower:
# Adding key to known_hosts
write(child_fd, b'yes\n')
elif 'company privacy warning' in lower:
pass # This is an understood message
else:
print('Error:',output)
sleep(5)
print(pid_exists(pid))
ssh('10.10.10.1')
No puedo encontrar mucha (o ninguna) información sobre cómo obtener el proceso de ejecución del pseudo-pseudo terminal que Python abre y canaliza hacia mí. ¿Puedo o debo involucrar al subproceso como se explica aquí?https://stackoverflow.com/a/12235442/929999 ¿O hay otra manera?