Implement ssh connection handling as a state machine

The event loop (even after it was brought into one place in _run in the
previous commit) was hard to follow. The states and transitions weren't
clear or documented, and the privilege escalation code was non-blocking
while the rest was blocking.

Now we have a state machine with four states: awaiting_prompt,
awaiting_escalation, ready_to_send (initial data), and awaiting_exit.
The actions in each state and the transitions between then are clearly
documented.

The check_incorrect_password() method no longer checks for empty strings
(since they will always match), and check_become_success() uses equality
rather than a substring match to avoid thinking an echoed command is an
indication of successful escalation. Also adds a check_missing_password
connection method to detect the error from sudo -n/doas -n.
This commit is contained in:
Abhijit Menon-Sen 2015-09-06 18:30:39 +05:30 committed by James Cammarata
parent 840a32bc08
commit ac98fe9e89
4 changed files with 213 additions and 105 deletions

View file

@ -171,6 +171,9 @@ class PlayContext(Base):
self.password = passwords.get('conn_pass','')
self.become_pass = passwords.get('become_pass','')
self.prompt = ''
self.success_key = ''
# a file descriptor to be used during locking operations
self.connection_lockfd = connection_lockfd