summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlive/config/chroot_local-includes/lib/live/config/9999-autotest11
-rw-r--r--live/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py71
2 files changed, 82 insertions, 0 deletions
diff --git a/live/config/chroot_local-includes/lib/live/config/9999-autotest b/live/config/chroot_local-includes/lib/live/config/9999-autotest
new file mode 100755
index 00000000..508c8ce8
--- /dev/null
+++ b/live/config/chroot_local-includes/lib/live/config/9999-autotest
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+SCRIPT=/usr/local/sbin/autotest_remote_shell.py
+
+if grep -qw "autotest_never_use_this_option" /proc/cmdline; then
+ # FIXME: more beautiful solution
+ sed -i 's/^exit.*$//' /etc/rc.local
+ echo "( while true ; do python ${SCRIPT} /dev/ttyS0 ; done ) &" >> \
+ /etc/rc.local
+ echo "exit 0" >> /etc/rc.local
+fi
diff --git a/live/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py b/live/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py
new file mode 100644
index 00000000..8778ddd1
--- /dev/null
+++ b/live/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+
+# ATTENTION: Yes, this can be used as a backdoor, but only for an
+# adversary with access to you *physical* serial port, which means
+# that you are screwed any way.
+
+from subprocess import Popen, PIPE
+from sys import argv
+from json import dumps, loads
+from pwd import getpwnam
+from os import setgid, setuid, environ
+from glob import glob
+import serial
+
+def mk_switch_user_fn(uid, gid):
+ def switch_user():
+ setgid(gid)
+ setuid(uid)
+ return switch_user
+
+def run_cmd_as_user(cmd, user):
+ env = environ.copy()
+ pwd_user = getpwnam(user)
+ switch_user_fn = mk_switch_user_fn(pwd_user.pw_uid,
+ pwd_user.pw_gid)
+ env['USER'] = user
+ env['LOGNAME'] = user
+ env['USERNAME'] = user
+ env['HOME'] = pwd_user.pw_dir
+ env['MAIL'] = "/var/mail/" + user
+ env['PWD'] = env['HOME']
+ env['DISPLAY'] = ':0.0'
+ try:
+ env['XAUTHORITY'] = glob("/var/run/gdm3/auth-for-amnesia-*/database")[0]
+ except IndexError:
+ pass
+ cwd = env['HOME']
+ return Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, env=env, cwd=cwd,
+ preexec_fn=switch_user_fn)
+
+def main():
+ dev = argv[1]
+ port = serial.Serial(port = dev, baudrate = 4000000)
+ port.open()
+ while True:
+ try:
+ line = port.readline()
+ except Exception as e:
+ # port must be opened wrong, so we restart everything and pray
+ # that it works.
+ print str(e)
+ port.close()
+ return main()
+ try:
+ cmd_type, user, cmd = loads(line)
+ except Exception as e:
+ # We had a parse/pack error, so we just send a \0 as an ACK,
+ # releasing the client from blocking.
+ print str(e)
+ port.write("\0")
+ continue
+ p = run_cmd_as_user(cmd, user)
+ if cmd_type == "spawn":
+ returncode, stdout, stderr = 0, "", ""
+ else:
+ stdout, stderr = p.communicate()
+ returncode = p.returncode
+ port.write(dumps([returncode, stdout, stderr]) + "\0")
+
+if __name__ == "__main__":
+ main()