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

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

Issue 9270031: Enable V2 authentication for Me2Me host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 8 years, 11 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/protocol/me2me_host_authenticator_factory.cc ('k') | remoting/tools/register_host.py » ('j') | 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.
11 11
12 import atexit 12 import atexit
13 import base64
13 import getpass 14 import getpass
14 import hashlib 15 import hashlib
16 import hmac
15 import json 17 import json
16 import logging 18 import logging
17 import optparse 19 import optparse
18 import os 20 import os
19 import random 21 import random
20 import signal 22 import signal
21 import socket 23 import socket
22 import subprocess 24 import subprocess
23 import sys 25 import sys
24 import time 26 import time
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 settings_file.close() 110 settings_file.close()
109 os.umask(old_umask) 111 os.umask(old_umask)
110 112
111 113
112 class Host: 114 class Host:
113 """This manages the configuration for a host. 115 """This manages the configuration for a host.
114 116
115 Callers should instantiate a Host object (passing in a filename where the 117 Callers should instantiate a Host object (passing in a filename where the
116 config will be kept), then should call either of the methods: 118 config will be kept), then should call either of the methods:
117 119
118 * create_config(auth): Create a new Host configuration and register it with 120 * register(auth): Create a new Host configuration and register it
119 the Directory Service (the "auth" parameter is used to authenticate with the 121 with the Directory Service (the "auth" parameter is used to
120 Service). 122 authenticate with the Service).
121 * load_config(): Load a config from disk, with details of an existing Host 123 * load_config(): Load a config from disk, with details of an existing Host
122 registration. 124 registration.
123 125
124 After calling create_config() (or making any config changes) the method 126 After calling register() (or making any config changes) the method
125 save_config() should be called to save the details to disk. 127 save_config() should be called to save the details to disk.
126 """ 128 """
127 129
128 server = 'www.googleapis.com' 130 server = 'www.googleapis.com'
129 url = 'https://' + server + '/chromoting/v1/@me/hosts' 131 url = 'https://' + server + '/chromoting/v1/@me/hosts'
130 132
131 def __init__(self, config_file): 133 def __init__(self, config_file):
132 self.config_file = config_file 134 self.config_file = config_file
135 self.host_id = str(uuid.uuid1())
136 self.host_name = socket.gethostname()
137 self.host_secret_hash = None
138 self.private_key = None
133 139
134 def create_config(self, auth): 140 def register(self, auth):
135 self.host_id = str(uuid.uuid1())
136 logging.info("HostId: " + self.host_id) 141 logging.info("HostId: " + self.host_id)
137 self.host_name = socket.gethostname()
138 logging.info("HostName: " + self.host_name) 142 logging.info("HostName: " + self.host_name)
139 143
140 logging.info("Generating RSA key pair...") 144 logging.info("Generating RSA key pair...")
141 (self.private_key, public_key) = keygen.generateRSAKeyPair() 145 (self.private_key, public_key) = keygen.generateRSAKeyPair()
142 logging.info("Done") 146 logging.info("Done")
143 147
144 json_data = { 148 json_data = {
145 "data": { 149 "data": {
146 "hostId": self.host_id, 150 "hostId": self.host_id,
147 "hostName": self.host_name, 151 "hostName": self.host_name,
(...skipping 13 matching lines...) Expand all
161 logging.info("Registering host with directory service...") 165 logging.info("Registering host with directory service...")
162 try: 166 try:
163 res = urllib2.urlopen(request) 167 res = urllib2.urlopen(request)
164 data = res.read() 168 data = res.read()
165 except urllib2.HTTPError, err: 169 except urllib2.HTTPError, err:
166 logging.error("Directory returned error: " + str(err)) 170 logging.error("Directory returned error: " + str(err))
167 logging.error(err.read()) 171 logging.error(err.read())
168 sys.exit(1) 172 sys.exit(1)
169 logging.info("Done") 173 logging.info("Done")
170 174
175 def ask_pin(self):
176 while 1:
177 pin = getpass.getpass("Host PIN (can be empty): ")
178 if len(pin) > 0 and len(pin) < 4:
179 print "PIN must be at least 4 characters long."
180 continue
181 break
182 if pin == "":
183 self.host_secret_hash = None
184 else:
185 self.host_secret_hash = "hmac:" + base64.b64encode(
186 hmac.new(str(self.host_id), pin, hashlib.sha256).digest())
187
171 def load_config(self): 188 def load_config(self):
172 try: 189 try:
173 settings_file = open(self.config_file, 'r') 190 settings_file = open(self.config_file, 'r')
174 data = json.load(settings_file) 191 data = json.load(settings_file)
175 settings_file.close() 192 settings_file.close()
176 self.host_id = data["host_id"]
177 self.host_name = data["host_name"]
178 self.private_key = data["private_key"]
179 except: 193 except:
194 logging.info("Failed to load: " + self.config_file)
180 return False 195 return False
196 self.host_id = data["host_id"]
197 self.host_name = data["host_name"]
198 self.host_secret_hash = data.get("host_secret_hash")
199 self.private_key = data["private_key"]
181 return True 200 return True
182 201
183 def save_config(self): 202 def save_config(self):
184 data = { 203 data = {
185 "host_id": self.host_id, 204 "host_id": self.host_id,
186 "host_name": self.host_name, 205 "host_name": self.host_name,
187 "private_key": self.private_key, 206 "private_key": self.private_key,
188 } 207 }
208 if self.host_secret_hash:
209 data["host_secret_hash"] = self.host_secret_hash,
210
189 old_umask = os.umask(0066) 211 old_umask = os.umask(0066)
190 settings_file = open(self.config_file, 'w') 212 settings_file = open(self.config_file, 'w')
191 settings_file.write(json.dumps(data, indent=2)) 213 settings_file.write(json.dumps(data, indent=2))
192 settings_file.close() 214 settings_file.close()
193 os.umask(old_umask) 215 os.umask(old_umask)
194 216
195 217
196 class Desktop: 218 class Desktop:
197 """Manage a single virtual desktop""" 219 """Manage a single virtual desktop"""
198 220
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 try: 518 try:
497 auth.refresh_tokens() 519 auth.refresh_tokens()
498 except: 520 except:
499 logging.error("Authentication failed.") 521 logging.error("Authentication failed.")
500 return 1 522 return 1
501 auth.save_config() 523 auth.save_config()
502 524
503 host = Host(os.path.join(CONFIG_DIR, "host#%s.json" % host_hash)) 525 host = Host(os.path.join(CONFIG_DIR, "host#%s.json" % host_hash))
504 526
505 if not host.load_config(): 527 if not host.load_config():
506 host.create_config(auth) 528 host.ask_pin()
529 host.register(auth)
507 host.save_config() 530 host.save_config()
508 531
509 global g_pidfile 532 global g_pidfile
510 g_pidfile = PidFile(pid_filename) 533 g_pidfile = PidFile(pid_filename)
511 running, pid = g_pidfile.check() 534 running, pid = g_pidfile.check()
512 535
513 if running: 536 if running:
514 if pid == 0: 537 if pid == 0:
515 pid = 'unknown' 538 pid = 'unknown'
516 539
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 desktop.session_proc = None 611 desktop.session_proc = None
589 612
590 if desktop.host_proc is not None and pid == desktop.host_proc.pid: 613 if desktop.host_proc is not None and pid == desktop.host_proc.pid:
591 logging.info("Host process terminated") 614 logging.info("Host process terminated")
592 desktop.host_proc = None 615 desktop.host_proc = None
593 616
594 617
595 if __name__ == "__main__": 618 if __name__ == "__main__":
596 logging.basicConfig(level=logging.DEBUG) 619 logging.basicConfig(level=logging.DEBUG)
597 sys.exit(main()) 620 sys.exit(main())
OLDNEW
« no previous file with comments | « remoting/protocol/me2me_host_authenticator_factory.cc ('k') | remoting/tools/register_host.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698