|
|
@ -50,7 +50,25 @@ def disable_echo(fd):
|
|
|
|
termios.tcsetattr(fd, tcsetattr_flags, new)
|
|
|
|
termios.tcsetattr(fd, tcsetattr_flags, new)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def close_nonstandard_fds():
|
|
|
|
|
|
|
|
for fd in xrange(3, 1024):
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
os.close(fd)
|
|
|
|
|
|
|
|
except OSError:
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def tty_create_child(*args):
|
|
|
|
def tty_create_child(*args):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Return a file descriptor connected to the master end of a pseudo-terminal,
|
|
|
|
|
|
|
|
whose slave end is connected to stdin/stdout/stderr of a new child process.
|
|
|
|
|
|
|
|
The child is created such that the pseudo-terminal becomes its controlling
|
|
|
|
|
|
|
|
TTY, ensuring access to /dev/tty returns a new file descriptor open on the
|
|
|
|
|
|
|
|
slave end.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param args:
|
|
|
|
|
|
|
|
execl() arguments.
|
|
|
|
|
|
|
|
"""
|
|
|
|
master_fd, slave_fd = os.openpty()
|
|
|
|
master_fd, slave_fd = os.openpty()
|
|
|
|
import econtext.core
|
|
|
|
import econtext.core
|
|
|
|
#econtext.core.set_nonblocking(master_fd)
|
|
|
|
#econtext.core.set_nonblocking(master_fd)
|
|
|
@ -62,9 +80,8 @@ def tty_create_child(*args):
|
|
|
|
os.dup2(slave_fd, 0)
|
|
|
|
os.dup2(slave_fd, 0)
|
|
|
|
os.dup2(slave_fd, 1)
|
|
|
|
os.dup2(slave_fd, 1)
|
|
|
|
os.dup2(slave_fd, 2)
|
|
|
|
os.dup2(slave_fd, 2)
|
|
|
|
os.close(slave_fd)
|
|
|
|
close_nonstandard_fds()
|
|
|
|
os.close(master_fd)
|
|
|
|
os.setsid()
|
|
|
|
#os.setsid()
|
|
|
|
|
|
|
|
os.close(os.open(os.ttyname(1), os.O_RDWR))
|
|
|
|
os.close(os.open(os.ttyname(1), os.O_RDWR))
|
|
|
|
os.execvp(args[0], args)
|
|
|
|
os.execvp(args[0], args)
|
|
|
|
raise SystemExit
|
|
|
|
raise SystemExit
|
|
|
@ -81,7 +98,7 @@ class Stream(econtext.master.Stream):
|
|
|
|
password = None
|
|
|
|
password = None
|
|
|
|
|
|
|
|
|
|
|
|
def get_boot_command(self):
|
|
|
|
def get_boot_command(self):
|
|
|
|
bits = [self.sudo_path, '-S', '-u', self._context.username]
|
|
|
|
bits = [self.sudo_path, '-u', self._context.username]
|
|
|
|
return bits + super(Stream, self).get_boot_command()
|
|
|
|
return bits + super(Stream, self).get_boot_command()
|
|
|
|
|
|
|
|
|
|
|
|
password_incorrect_msg = 'sudo password is incorrect'
|
|
|
|
password_incorrect_msg = 'sudo password is incorrect'
|
|
|
@ -91,6 +108,7 @@ class Stream(econtext.master.Stream):
|
|
|
|
password_sent = False
|
|
|
|
password_sent = False
|
|
|
|
for buf in econtext.master.iter_read(self.receive_side.fd,
|
|
|
|
for buf in econtext.master.iter_read(self.receive_side.fd,
|
|
|
|
time.time() + 10.0):
|
|
|
|
time.time() + 10.0):
|
|
|
|
|
|
|
|
LOG.debug('%r: received %r', self, buf)
|
|
|
|
if buf.endswith('EC0\n'):
|
|
|
|
if buf.endswith('EC0\n'):
|
|
|
|
return self._ec0_received()
|
|
|
|
return self._ec0_received()
|
|
|
|
elif PASSWORD_PROMPT in buf.lower():
|
|
|
|
elif PASSWORD_PROMPT in buf.lower():
|
|
|
|