Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: remoting/tools/me2me_virtual_host.py

Issue 10824286: Fix DaemonControllerLinux::SetConfigAndStart() to reload config automatically. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/plugin/daemon_controller_mac.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env 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.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 return self.data[key] 111 return self.data[key]
112 112
113 def __setitem__(self, key, value): 113 def __setitem__(self, key, value):
114 self.data[key] = value 114 self.data[key] = value
115 self.changed = True 115 self.changed = True
116 116
117 def clear_auth(self): 117 def clear_auth(self):
118 del self.data["xmpp_login"] 118 del self.data["xmpp_login"]
119 del self.data["chromoting_auth_token"] 119 del self.data["chromoting_auth_token"]
120 del self.data["xmpp_auth_token"] 120 del self.data["xmpp_auth_token"]
121 del self.data["oauth_refresh_token"]
121 122
122 def clear_host_info(self): 123 def clear_host_info(self):
123 del self.data["host_id"] 124 del self.data["host_id"]
124 del self.data["host_name"] 125 del self.data["host_name"]
125 del self.data["host_secret_hash"] 126 del self.data["host_secret_hash"]
126 del self.data["private_key"] 127 del self.data["private_key"]
127 128
128 class Authentication: 129 class Authentication:
129 """Manage authentication tokens for Chromoting/xmpp""" 130 """Manage authentication tokens for Chromoting/xmpp"""
130 131
131 def __init__(self): 132 def __init__(self):
132 pass 133 self.login = None
134 self.chromoting_auth_token = None
135 self.xmpp_auth_token = None
136 self.oauth_refresh_token = None
133 137
134 def generate_tokens(self): 138 def generate_tokens(self):
135 """Prompt for username/password and use them to generate new authentication 139 """Prompt for username/password and use them to generate new authentication
136 tokens. 140 tokens.
137 141
138 Raises: 142 Raises:
139 Exception: Failed to get new authentication tokens. 143 Exception: Failed to get new authentication tokens.
140 """ 144 """
141 print "Email:", 145 print "Email:",
142 self.login = raw_input() 146 self.login = raw_input()
143 password = getpass.getpass("App-specific password: ") 147 password = getpass.getpass("App-specific password: ")
144 148
145 chromoting_auth = gaia_auth.GaiaAuthenticator('chromoting') 149 chromoting_auth = gaia_auth.GaiaAuthenticator('chromoting')
146 self.chromoting_auth_token = chromoting_auth.authenticate(self.login, 150 self.chromoting_auth_token = chromoting_auth.authenticate(self.login,
147 password) 151 password)
148 152
149 xmpp_authenticator = gaia_auth.GaiaAuthenticator('chromiumsync') 153 xmpp_authenticator = gaia_auth.GaiaAuthenticator('chromiumsync')
150 self.xmpp_auth_token = xmpp_authenticator.authenticate(self.login, 154 self.xmpp_auth_token = xmpp_authenticator.authenticate(self.login,
151 password) 155 password)
152 156
157 def has_chromoting_credentials(self):
158 """Returns True if we have credentials for the directory"""
159 return self.chromoting_auth_token != None
160
161 def has_xmpp_credentials(self):
162 """Returns True if we have credentials to authenticate XMPP connection"""
163 # XMPP connection can be authenticated using either OAuth or XMPP token.
164 return self.oauth_refresh_token != None or self.xmpp_auth_token != None
165
153 def load_config(self, config): 166 def load_config(self, config):
167 """Loads the config and returns false if the config is invalid. After
168 config is loaded caller must use has_xmpp_credentials() and
169 has_chromoting_credentials() to check that the credentials it needs are
170 present in the config."""
171
172 # Host can use different types of auth tokens depending on how the config
173 # was generated. E.g. if the config was created by the webapp it will have
174 # only oauth token. We still consider config to be valid in this case.
175 self.chromoting_auth_token = config.get("chromoting_auth_token")
176 self.oauth_refresh_token = config.get("oauth_refresh_token")
177 self.xmpp_auth_token = config.get("xmpp_auth_token")
178
154 try: 179 try:
155 self.login = config["xmpp_login"] 180 self.login = config["xmpp_login"]
156 self.chromoting_auth_token = config["chromoting_auth_token"]
157 self.xmpp_auth_token = config["xmpp_auth_token"]
158 except KeyError: 181 except KeyError:
159 return False 182 return False
160 return True 183 return True
161 184
162 def save_config(self, config): 185 def save_config(self, config):
163 config["xmpp_login"] = self.login 186 config["xmpp_login"] = self.login
164 config["chromoting_auth_token"] = self.chromoting_auth_token 187 if self.chromoting_auth_token:
165 config["xmpp_auth_token"] = self.xmpp_auth_token 188 config["chromoting_auth_token"] = self.chromoting_auth_token
189 if self.xmpp_auth_token:
190 config["xmpp_auth_token"] = self.xmpp_auth_token
191
166 192
167 class Host: 193 class Host:
168 """This manages the configuration for a host. 194 """This manages the configuration for a host.
169 195
170 Callers should instantiate a Host object (passing in a filename where the 196 Callers should instantiate a Host object (passing in a filename where the
171 config will be kept), then should call either of the methods: 197 config will be kept), then should call either of the methods:
172 198
173 * register(auth): Create a new Host configuration and register it 199 * register(auth): Create a new Host configuration and register it
174 with the Directory Service (the "auth" parameter is used to 200 with the Directory Service (the "auth" parameter is used to
175 authenticate with the Service). 201 authenticate with the Service).
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 help="stop the daemon currently running") 680 help="stop the daemon currently running")
655 parser.add_option("-p", "--new-pin", dest="new_pin", default=False, 681 parser.add_option("-p", "--new-pin", dest="new_pin", default=False,
656 action="store_true", 682 action="store_true",
657 help="set new PIN before starting the host") 683 help="set new PIN before starting the host")
658 parser.add_option("", "--check-running", dest="check_running", default=False, 684 parser.add_option("", "--check-running", dest="check_running", default=False,
659 action="store_true", 685 action="store_true",
660 help="return 0 if the daemon is running, or 1 otherwise") 686 help="return 0 if the daemon is running, or 1 otherwise")
661 parser.add_option("", "--silent", dest="silent", default=False, 687 parser.add_option("", "--silent", dest="silent", default=False,
662 action="store_true", 688 action="store_true",
663 help="Start the host without trying to configure it.") 689 help="Start the host without trying to configure it.")
690 parser.add_option("", "--reload", dest="reload", default=False,
691 action="store_true",
692 help="Signal currently running host to reload the config.")
664 (options, args) = parser.parse_args() 693 (options, args) = parser.parse_args()
665 694
666 host_hash = hashlib.md5(socket.gethostname()).hexdigest() 695 host_hash = hashlib.md5(socket.gethostname()).hexdigest()
667 pid_filename = os.path.join(CONFIG_DIR, "host#%s.pid" % host_hash) 696 pid_filename = os.path.join(CONFIG_DIR, "host#%s.pid" % host_hash)
668 697
669 if options.check_running: 698 if options.check_running:
670 running, pid = PidFile(pid_filename).check() 699 running, pid = PidFile(pid_filename).check()
671 return 0 if (running and pid != 0) else 1 700 return 0 if (running and pid != 0) else 1
672 701
673 if options.stop: 702 if options.stop:
674 running, pid = PidFile(pid_filename).check() 703 running, pid = PidFile(pid_filename).check()
675 if not running: 704 if not running:
676 print "The daemon currently is not running" 705 print "The daemon currently is not running"
677 else: 706 else:
678 print "Killing process %s" % pid 707 print "Killing process %s" % pid
679 os.kill(pid, signal.SIGTERM) 708 os.kill(pid, signal.SIGTERM)
680 return 0 709 return 0
681 710
711 if options.reload:
712 running, pid = PidFile(pid_filename).check()
713 if not running:
714 return 1
715 os.kill(pid, signal.SIGUSR1)
716 return 0
717
682 if not options.size: 718 if not options.size:
683 options.size = [DEFAULT_SIZE] 719 options.size = [DEFAULT_SIZE]
684 720
685 sizes = [] 721 sizes = []
686 for size in options.size: 722 for size in options.size:
687 size_components = size.split("x") 723 size_components = size.split("x")
688 if len(size_components) != 2: 724 if len(size_components) != 2:
689 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size) 725 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size)
690 726
691 try: 727 try:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 # If we were able to read auth.json then copy its content to the host 772 # If we were able to read auth.json then copy its content to the host
737 # config. 773 # config.
738 if auth_config_loaded: 774 if auth_config_loaded:
739 auth.save_config(host_config) 775 auth.save_config(host_config)
740 host_config.save() 776 host_config.save()
741 777
742 host = Host(auth) 778 host = Host(auth)
743 host_config_loaded = host.load_config(host_config) 779 host_config_loaded = host.load_config(host_config)
744 780
745 if options.silent: 781 if options.silent:
782 # Just validate the config when run with --silent.
746 if not host_config_loaded or not auth_config_loaded: 783 if not host_config_loaded or not auth_config_loaded:
747 logging.error("Failed to load host configuration.") 784 logging.error("Failed to load host configuration.")
748 return 1 785 return 1
786 if not auth.has_xmpp_credentials():
787 logging.error("Auth tokens are not configured.")
788 return 1
749 else: 789 else:
750 need_auth_tokens = not auth_config_loaded 790 need_auth_tokens = (
791 not auth_config_loaded or not auth.has_chromoting_credentials())
751 need_register_host = not host_config_loaded 792 need_register_host = not host_config_loaded
752 # Outside the loop so user doesn't get asked twice. 793 # Outside the loop so user doesn't get asked twice.
753 if need_register_host: 794 if need_register_host:
754 host.ask_pin() 795 host.ask_pin()
755 elif options.new_pin or not host.is_pin_set(): 796 elif options.new_pin or not host.is_pin_set():
756 host.ask_pin() 797 host.ask_pin()
757 host.save_config(host_config) 798 host.save_config(host_config)
758 running, pid = PidFile(pid_filename).check() 799 running, pid = PidFile(pid_filename).check()
759 if running and pid != 0: 800 if running and pid != 0:
760 os.kill(pid, signal.SIGUSR1) 801 os.kill(pid, signal.SIGUSR1)
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 host_config.save() 954 host_config.save()
914 return 0 955 return 0
915 elif os.WEXITSTATUS(status) == 5: 956 elif os.WEXITSTATUS(status) == 5:
916 logging.info("Host domain is blocked by policy - exiting.") 957 logging.info("Host domain is blocked by policy - exiting.")
917 os.remove(host.config_file) 958 os.remove(host.config_file)
918 return 0 959 return 0
919 960
920 if __name__ == "__main__": 961 if __name__ == "__main__":
921 logging.basicConfig(level=logging.DEBUG) 962 logging.basicConfig(level=logging.DEBUG)
922 sys.exit(main()) 963 sys.exit(main())
OLDNEW
« no previous file with comments | « remoting/host/plugin/daemon_controller_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698