OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # Virtual Me2Me implementation. This script runs and manages the processes | 6 # Virtual Me2Me implementation. This script runs and manages the processes |
7 # required for a Virtual Me2Me desktop, which are: X server, X desktop | 7 # required for a Virtual Me2Me desktop, which are: X server, X desktop |
8 # session, and Host process. | 8 # session, and Host process. |
9 # This script is intended to run continuously as a background daemon | 9 # This script is intended to run continuously as a background daemon |
10 # process, running under an ordinary (non-root) user account. | 10 # process, running under an ordinary (non-root) user account. |
11 | 11 |
12 import atexit | 12 import atexit |
13 import errno | 13 import errno |
14 import fcntl | 14 import fcntl |
15 import getpass | 15 import getpass |
16 import grp | 16 import grp |
17 import hashlib | 17 import hashlib |
18 import json | 18 import json |
19 import logging | 19 import logging |
20 import optparse | 20 import optparse |
21 import os | 21 import os |
22 import pipes | 22 import pipes |
23 import platform | 23 import platform |
24 import psutil | 24 import psutil |
25 import platform | 25 import platform |
26 import pwd | |
26 import re | 27 import re |
27 import signal | 28 import signal |
28 import socket | 29 import socket |
29 import subprocess | 30 import subprocess |
30 import sys | 31 import sys |
31 import tempfile | 32 import tempfile |
32 import time | 33 import time |
33 import uuid | 34 import uuid |
34 | 35 |
35 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" | 36 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" |
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1026 action="store_true", | 1027 action="store_true", |
1027 help="Return 0 if the daemon is running, or 1 otherwise.") | 1028 help="Return 0 if the daemon is running, or 1 otherwise.") |
1028 parser.add_option("", "--config", dest="config", action="store", | 1029 parser.add_option("", "--config", dest="config", action="store", |
1029 help="Use the specified configuration file.") | 1030 help="Use the specified configuration file.") |
1030 parser.add_option("", "--reload", dest="reload", default=False, | 1031 parser.add_option("", "--reload", dest="reload", default=False, |
1031 action="store_true", | 1032 action="store_true", |
1032 help="Signal currently running host to reload the config.") | 1033 help="Signal currently running host to reload the config.") |
1033 parser.add_option("", "--add-user", dest="add_user", default=False, | 1034 parser.add_option("", "--add-user", dest="add_user", default=False, |
1034 action="store_true", | 1035 action="store_true", |
1035 help="Add current user to the chrome-remote-desktop group.") | 1036 help="Add current user to the chrome-remote-desktop group.") |
1037 parser.add_option("", "--add-user-as-root", dest="add_user_as_root", | |
1038 action="store", metavar="USER", | |
1039 help="Adds the specified user to the chrome-remote-desktop " | |
1040 "group (must be run as root).") | |
1036 parser.add_option("", "--host-version", dest="host_version", default=False, | 1041 parser.add_option("", "--host-version", dest="host_version", default=False, |
1037 action="store_true", | 1042 action="store_true", |
1038 help="Prints version of the host.") | 1043 help="Prints version of the host.") |
1039 parser.add_option("", "--watch-resolution", dest="watch_resolution", | 1044 parser.add_option("", "--watch-resolution", dest="watch_resolution", |
1040 type="int", nargs=2, default=False, action="store", | 1045 type="int", nargs=2, default=False, action="store", |
1041 help=optparse.SUPPRESS_HELP) | 1046 help=optparse.SUPPRESS_HELP) |
1042 (options, args) = parser.parse_args() | 1047 (options, args) = parser.parse_args() |
1043 | 1048 |
1044 # Determine the filename of the host configuration and PID files. | 1049 # Determine the filename of the host configuration and PID files. |
1045 if not options.config: | 1050 if not options.config: |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1078 | 1083 |
1079 if options.reload: | 1084 if options.reload: |
1080 proc = get_daemon_proc() | 1085 proc = get_daemon_proc() |
1081 if proc is None: | 1086 if proc is None: |
1082 return 1 | 1087 return 1 |
1083 proc.send_signal(signal.SIGHUP) | 1088 proc.send_signal(signal.SIGHUP) |
1084 return 0 | 1089 return 0 |
1085 | 1090 |
1086 if options.add_user: | 1091 if options.add_user: |
1087 user = getpass.getuser() | 1092 user = getpass.getuser() |
1093 | |
1088 try: | 1094 try: |
1089 if user in grp.getgrnam(CHROME_REMOTING_GROUP_NAME).gr_mem: | 1095 if user in grp.getgrnam(CHROME_REMOTING_GROUP_NAME).gr_mem: |
1090 logging.info("User '%s' is already a member of '%s'." % | 1096 logging.info("User '%s' is already a member of '%s'." % |
1091 (user, CHROME_REMOTING_GROUP_NAME)) | 1097 (user, CHROME_REMOTING_GROUP_NAME)) |
1092 return 0 | 1098 return 0 |
1093 except KeyError: | 1099 except KeyError: |
1094 logging.info("Group '%s' not found." % CHROME_REMOTING_GROUP_NAME) | 1100 logging.info("Group '%s' not found." % CHROME_REMOTING_GROUP_NAME) |
1095 | 1101 |
1102 command = [SCRIPT_PATH, '--add-user-as-root', user] | |
1096 if os.getenv("DISPLAY"): | 1103 if os.getenv("DISPLAY"): |
1097 sudo_command = "gksudo --description \"Chrome Remote Desktop\"" | 1104 command = ["/usr/bin/pkexec"] + command |
Sergey Ulanov
2015/02/09 22:00:25
add TODO to add Polkit policy
rickyz (no longer on Chrome)
2015/02/13 05:03:52
Done.
| |
1098 else: | 1105 else: |
1099 sudo_command = "sudo" | 1106 command = ["/usr/bin/sudo", "-k", "--"] + command |
1100 command = ("sudo -k && exec %(sudo)s -- sh -c " | 1107 |
1101 "\"groupadd -f %(group)s && gpasswd --add %(user)s %(group)s\"" % | 1108 # Run with an empty environment out of paranoia, though if an attacker |
1102 { 'group': CHROME_REMOTING_GROUP_NAME, | 1109 # controls the environment this script is run under, we're already screwed |
1103 'user': user, | 1110 # anyway. |
1104 'sudo': sudo_command }) | 1111 os.execve(command[0], command, {}) |
1105 os.execv("/bin/sh", ["/bin/sh", "-c", command]) | |
1106 return 1 | 1112 return 1 |
1107 | 1113 |
1114 if options.add_user_as_root is not None: | |
1115 if os.getuid() != 0: | |
1116 logging.error("--add-user-as-root can only be specified as root.") | |
1117 return 1; | |
1118 | |
1119 user = options.add_user_as_root | |
1120 try: | |
1121 pwd.getpwnam(user) | |
1122 except KeyError: | |
1123 logging.error("user '%s' does not exist." % user) | |
1124 return 1 | |
1125 | |
1126 try: | |
1127 subprocess.check_call(["/usr/sbin/groupadd", "-f", | |
1128 CHROME_REMOTING_GROUP_NAME]) | |
1129 subprocess.check_call(["/usr/bin/gpasswd", "--add", user, | |
1130 CHROME_REMOTING_GROUP_NAME]) | |
1131 except (ValueError, OSError, subprocess.CalledProcessError) as e: | |
1132 logging.error("Command failed: " + str(e)) | |
1133 return 1 | |
1134 | |
1135 return 0 | |
1136 | |
1108 if options.host_version: | 1137 if options.host_version: |
1109 # TODO(sergeyu): Also check RPM package version once we add RPM package. | 1138 # TODO(sergeyu): Also check RPM package version once we add RPM package. |
1110 return os.system(locate_executable(HOST_BINARY_NAME) + " --version") >> 8 | 1139 return os.system(locate_executable(HOST_BINARY_NAME) + " --version") >> 8 |
1111 | 1140 |
1112 if options.watch_resolution: | 1141 if options.watch_resolution: |
1113 watch_for_resolution_changes(options.watch_resolution) | 1142 watch_for_resolution_changes(options.watch_resolution) |
1114 return 0 | 1143 return 0 |
1115 | 1144 |
1116 if not options.start: | 1145 if not options.start: |
1117 # If no modal command-line options specified, print an error and exit. | 1146 # If no modal command-line options specified, print an error and exit. |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1311 else: | 1340 else: |
1312 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) | 1341 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) |
1313 elif os.WIFSIGNALED(status): | 1342 elif os.WIFSIGNALED(status): |
1314 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) | 1343 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) |
1315 | 1344 |
1316 | 1345 |
1317 if __name__ == "__main__": | 1346 if __name__ == "__main__": |
1318 logging.basicConfig(level=logging.DEBUG, | 1347 logging.basicConfig(level=logging.DEBUG, |
1319 format="%(asctime)s:%(levelname)s:%(message)s") | 1348 format="%(asctime)s:%(levelname)s:%(message)s") |
1320 sys.exit(main()) | 1349 sys.exit(main()) |
OLD | NEW |