Просмотр исходного кода

Fix case when sudo requires a password.

Aurelien 5 лет назад
Родитель
Сommit
f4c3007f30
1 измененных файлов с 27 добавлено и 10 удалено
  1. 27 10
      byrd/main.py

+ 27 - 10
byrd/main.py

@@ -187,17 +187,10 @@ def run_helper(client, cmd, env=None, in_buff=None, sudo=False):
     Helper function to run `cmd` command on remote host
     '''
     chan = client.get_transport().open_session()
+    chan.get_pty()
     if env:
         chan.update_environment(env)
 
-    stdin = chan.makefile('wb')
-    stdout = chan.makefile('r')
-    stderr = chan.makefile_stderr('r')
-    out_buff = io.StringIO()
-    err_buff = io.StringIO()
-    out_thread = log_stream(stdout, out_buff)
-    err_thread = log_stream(stderr, err_buff)
-
     if sudo:
         assert not in_buff, 'in_buff and sudo can not be combined'
         if isinstance(sudo, str):
@@ -205,12 +198,36 @@ def run_helper(client, cmd, env=None, in_buff=None, sudo=False):
         else:
             sudo_cmd = 'sudo -s'
         chan.exec_command(sudo_cmd)
+        msg = chan.recv(1024)
+        while msg and b'[sudo] password for' in msg:
+            pw = getpass(msg.decode())
+            chan.send(pw + '\n')
+            msg = chan.recv(1024)
+            msg += chan.recv(1024)
+            if b'root@' in msg:
+                break
+            else:
+                if b'sudo: 3 incorrect password attempts' in msg:
+                    raise RemoteException(msg)
+                if b'Sorry' in msg:  # Failure message in in two parts in bash on Debian anyway.
+                    msg += chan.recv(1024)
+
         in_buff = cmd
-    else:
+
+    stdin = chan.makefile('wb')
+    stdout = chan.makefile('r')
+    stderr = chan.makefile_stderr('r')
+    out_buff = io.StringIO()
+    err_buff = io.StringIO()
+    out_thread = log_stream(stdout, out_buff)
+    err_thread = log_stream(stderr, err_buff)
+
+    if not sudo:
         chan.exec_command(cmd)
+
     if in_buff:
         # XXX use a real buff (not a simple str) ?
-        stdin.write(in_buff)
+        stdin.write(in_buff.replace('\n', '') + ' && exit $?\n')
         stdin.flush()
         stdin.close()
         chan.shutdown_write()