diff --git a/confluent_server/confluent/exceptions.py b/confluent_server/confluent/exceptions.py index a2c67b68..80f5337e 100644 --- a/confluent_server/confluent/exceptions.py +++ b/confluent_server/confluent/exceptions.py @@ -106,6 +106,7 @@ class PubkeyInvalid(ConfluentException): super(PubkeyInvalid, self).__init__(self, text) self.fingerprint = fingerprint self.attrname = attribname + self.message = text bodydata = {'message': text, 'event': event, 'fingerprint': fingerprint, diff --git a/confluent_server/confluent/plugins/shell/ssh.py b/confluent_server/confluent/plugins/shell/ssh.py index 9f693b30..2e44e9f8 100644 --- a/confluent_server/confluent/plugins/shell/ssh.py +++ b/confluent_server/confluent/plugins/shell/ssh.py @@ -1,6 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2015 Lenovo +# Copyright 2015-2018 Lenovo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -113,13 +113,48 @@ class SshShell(conapi.Console): self.password = '' self.datacallback('\r\nlogin as: ') return + except cexc.PubkeyInvalid as pi: + self.keyaction = '' + self.candidatefprint = pi.fingerprint + self.datacallback(pi.message) + self.keyattrname = pi.attrname + self.datacallback('\r\nNew fingerprint: ' + pi.fingerprint) + self.inputmode = -1 + self.datacallback('\r\nEnter "disconnect" or "accept": ') + return self.inputmode = 2 self.connected = True self.shell = self.ssh.invoke_shell() self.rxthread = eventlet.spawn(self.recvdata) def write(self, data): - if self.inputmode == 0: + if self.inputmode == -1: + while len(data) and data[0] == b'\x7f' and len(self.keyaction): + self.datacallback('\b \b') # erase previously echoed value + self.keyaction = self.keyaction[:-1] + data = data[1:] + while len(data) and data[0] == b'\x7f': + data = data[1:] + while b'\x7f' in data: + delidx = data.index(b'\x7f') + data = data[:delidx - 1] + data[delidx + 1:] + self.keyaction += data + if '\r' in self.keyaction: + action = self.keyaction.split('\r')[0] + if action.lower() == 'accept': + self.nodeconfig.set_node_attributes( + {self.node: + {self.keyattrname: self.candidatefprint}}) + self.datacallback('\r\n') + self.logon() + elif action.lower() == 'disconnect': + self.datacallback(conapi.ConsoleEvent.Disconnect) + else: + self.keyaction = '' + self.datacallback('\r\nEnter "disconnect" or "accept": ') + elif len(data) > 0: + self.datacallback(data) + elif self.inputmode == 0: while len(data) and data[0] == b'\x7f' and len(self.username): self.datacallback('\b \b') # erase previously echoed value self.username = self.username[:-1]