【发布时间】:2017-07-29 05:54:31
【问题描述】:
我有一个 paramiko 交互式 shell,我试图用它来登录远程 linux 主机:
class SSH_wrapper(object):
"""
A SSH Client powered by Paramiko.
"""
def __init__(self, hostname, port=22, username=None, password=None,
key=None, key_passphrase=None, encoding='UTF-8', timeout=300, prompts = None):
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.passphrase = key_passphrase
self.key = key
self.timeout = timeout
self.encoding = encoding
self.prompts = prompts
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
def connect(self):
conninfo = {'hostname': self.hostname,
'port': self.port,
'username': self.username,
'allow_agent': False,
'look_for_keys': False}
if self.password:
conninfo['password'] = self.password
elif self.key:
conninfo['key_filename'] = self.key
conninfo['password'] = self.passphrase
else:
conninfo['allow_agent'] = True
conninfo['look_for_keys'] = True
if self.timeout:
conninfo['timeout'] = self.timeout
else:
conninfo['timeout'] = 180
try:
self.client.connect(**conninfo)
except paramiko.ssh_exception.AuthenticationException:
print("Authentication failed for user name \"" + str(self.username) + "\".")
return False
except paramiko.ssh_exception.SSHException:
print("SSHException found. Could not connect to \"" + str(self.hostname) + "\".")
return False
except:
e = sys.exc_info()[0]
print("Could not connect to host \"" + str(self.hostname) + "\". Found exception: " + str(e) + ".")
return False
banner = self.client._transport.get_banner()
#print(str(banner, 'utf-8'))
return True
def open_shell_session(self, prompts=None, timeout=None):
if (timeout != None) and (type(timeout) is int):
open_timeout = timeout
else:
open_timeout = self.timeout
no_prompts = 0
if (prompts != None and self.prompts == None):
no_prompts = 1
elif (prompts != None and self.prompts != None):
prompts = self.prompts
channel_data = b""
try:
self.shell = self.client.invoke_shell(term='vt100')
except paramiko.ssh_exception.SSHException:
print("SSHException found. Could not open SSH shell to \"" + str(self.hostname) + "\".")
return [False, ""]
except:
e = sys.exc_info()[0]
print("Could not open SSH shell to \"" + str(self.hostname) + "\". Found exception: " + str(e) + ".")
return [False, ""]
start_time = time.time()
# when testing be sure to test with session where prompt is not recognized.
while True and (time.time() - start_time <= open_timeout):
print("loop " + str(time.time() - start_time))
self.shell.settimeout(5000)
try:
channel_data += self.shell.recv(9999)
print(str(channel_data, 'utf-8'))
except:
e = sys.exc_info()[0]
print("Found exception: " + str(e) + ".")
if self.shell.exit_status_ready() == True:
print("exit status received.")
print("received channel data.")
if no_prompts == 1:
time.sleep(4)
break
elif (prompts != None) and (re.search("|".join(prompts), str(channel_data, 'utf-8'))):
break
print("end of while loop.")
else:
print("Time out connecting to host \"" + str(self.hostname) + "\".")
return [False, str(channel_data, self.encoding)]
# return [status, banner]
print("exiting")
return [True, str(channel_data, self.encoding)]
我不知道为什么,但是当我尝试登录到提示我更改密码的主机时,“open_shell_session()”在“channel_data += self.shell.recv(9999)”处冻结。
这是我尝试打开交互式 shell 时 linux shell 的提示符/横幅示例:
|________________________________________________________________|
WARNING: Your password has expired. You must change your password now and login again!
Changing password for user xxxx.
Changing password for xxxx.
(current) UNIX password:
关于问题的任何建议(recv(9999) 是否仍然打开)?如何处理?
【问题讨论】:
-
您的密码已过期。您必须更改密码才能
invoke_shell()。 -
是的,我明白 :)。但我想让我的脚本执行此操作。
-
什么是 that 就像 我想让我的脚本执行那个?
-
如果脚本发现密码过期,它会识别它并输入新密码。