Merge remote-tracking branch 'flapflap/de-network_configuration'
[tails-test.git] / config / chroot_local-includes / usr / local / sbin / autotest_remote_shell.py
blob8778ddd18f64da78f636bd058ced181dcbcfe6d1
1 #!/usr/bin/python
3 # ATTENTION: Yes, this can be used as a backdoor, but only for an
4 # adversary with access to you *physical* serial port, which means
5 # that you are screwed any way.
7 from subprocess import Popen, PIPE
8 from sys import argv
9 from json import dumps, loads
10 from pwd import getpwnam
11 from os import setgid, setuid, environ
12 from glob import glob
13 import serial
15 def mk_switch_user_fn(uid, gid):
16 def switch_user():
17 setgid(gid)
18 setuid(uid)
19 return switch_user
21 def run_cmd_as_user(cmd, user):
22 env = environ.copy()
23 pwd_user = getpwnam(user)
24 switch_user_fn = mk_switch_user_fn(pwd_user.pw_uid,
25 pwd_user.pw_gid)
26 env['USER'] = user
27 env['LOGNAME'] = user
28 env['USERNAME'] = user
29 env['HOME'] = pwd_user.pw_dir
30 env['MAIL'] = "/var/mail/" + user
31 env['PWD'] = env['HOME']
32 env['DISPLAY'] = ':0.0'
33 try:
34 env['XAUTHORITY'] = glob("/var/run/gdm3/auth-for-amnesia-*/database")[0]
35 except IndexError:
36 pass
37 cwd = env['HOME']
38 return Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, env=env, cwd=cwd,
39 preexec_fn=switch_user_fn)
41 def main():
42 dev = argv[1]
43 port = serial.Serial(port = dev, baudrate = 4000000)
44 port.open()
45 while True:
46 try:
47 line = port.readline()
48 except Exception as e:
49 # port must be opened wrong, so we restart everything and pray
50 # that it works.
51 print str(e)
52 port.close()
53 return main()
54 try:
55 cmd_type, user, cmd = loads(line)
56 except Exception as e:
57 # We had a parse/pack error, so we just send a \0 as an ACK,
58 # releasing the client from blocking.
59 print str(e)
60 port.write("\0")
61 continue
62 p = run_cmd_as_user(cmd, user)
63 if cmd_type == "spawn":
64 returncode, stdout, stderr = 0, "", ""
65 else:
66 stdout, stderr = p.communicate()
67 returncode = p.returncode
68 port.write(dumps([returncode, stdout, stderr]) + "\0")
70 if __name__ == "__main__":
71 main()