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

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
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 pin = getpass.getpass("Host PIN (can be empty): ")
Wez 2012/01/23 23:53:49 nit: Verify that the PIN is either empty or at lea
Sergey Ulanov 2012/01/24 06:32:22 Done.
177 self.host_secret_hash = "hmac;" + base64.b64encode(
178 hmac.new(str(self.host_id), pin, hashlib.sha256).digest())
Wez 2012/01/23 23:53:49 nit: It will make changes to inform the client of
Sergey Ulanov 2012/01/24 06:32:22 Done.
179
180 def ask_pin_if_unknown(self):
181 if not self.host_secret_hash:
182 self.ask_pin()
183 return True
184 return False
185
171 def load_config(self): 186 def load_config(self):
172 try: 187 try:
173 settings_file = open(self.config_file, 'r') 188 settings_file = open(self.config_file, 'r')
174 data = json.load(settings_file) 189 data = json.load(settings_file)
175 settings_file.close() 190 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: 191 except:
192 logging.info("Failed to load: " + self.config_file)
180 return False 193 return False
194 self.host_id = data["host_id"]
195 self.host_name = data["host_name"]
196 self.host_secret_hash = data.get("host_secret_hash")
197 self.private_key = data["private_key"]
181 return True 198 return True
182 199
183 def save_config(self): 200 def save_config(self):
184 data = { 201 data = {
185 "host_id": self.host_id, 202 "host_id": self.host_id,
186 "host_name": self.host_name, 203 "host_name": self.host_name,
204 "host_secret_hash": self.host_secret_hash,
187 "private_key": self.private_key, 205 "private_key": self.private_key,
188 } 206 }
189 old_umask = os.umask(0066) 207 old_umask = os.umask(0066)
190 settings_file = open(self.config_file, 'w') 208 settings_file = open(self.config_file, 'w')
191 settings_file.write(json.dumps(data, indent=2)) 209 settings_file.write(json.dumps(data, indent=2))
192 settings_file.close() 210 settings_file.close()
193 os.umask(old_umask) 211 os.umask(old_umask)
194 212
195 213
196 class Desktop: 214 class Desktop:
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 try: 514 try:
497 auth.refresh_tokens() 515 auth.refresh_tokens()
498 except: 516 except:
499 logging.error("Authentication failed.") 517 logging.error("Authentication failed.")
500 return 1 518 return 1
501 auth.save_config() 519 auth.save_config()
502 520
503 host = Host(os.path.join(CONFIG_DIR, "host#%s.json" % host_hash)) 521 host = Host(os.path.join(CONFIG_DIR, "host#%s.json" % host_hash))
504 522
505 if not host.load_config(): 523 if not host.load_config():
506 host.create_config(auth) 524 host.ask_pin()
525 host.register(auth)
526 host.save_config()
527
528 if host.ask_pin_if_unknown():
507 host.save_config() 529 host.save_config()
508 530
509 global g_pidfile 531 global g_pidfile
510 g_pidfile = PidFile(pid_filename) 532 g_pidfile = PidFile(pid_filename)
511 running, pid = g_pidfile.check() 533 running, pid = g_pidfile.check()
512 534
513 if running: 535 if running:
514 if pid == 0: 536 if pid == 0:
515 pid = 'unknown' 537 pid = 'unknown'
516 538
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 desktop.session_proc = None 610 desktop.session_proc = None
589 611
590 if desktop.host_proc is not None and pid == desktop.host_proc.pid: 612 if desktop.host_proc is not None and pid == desktop.host_proc.pid:
591 logging.info("Host process terminated") 613 logging.info("Host process terminated")
592 desktop.host_proc = None 614 desktop.host_proc = None
593 615
594 616
595 if __name__ == "__main__": 617 if __name__ == "__main__":
596 logging.basicConfig(level=logging.DEBUG) 618 logging.basicConfig(level=logging.DEBUG)
597 sys.exit(main()) 619 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698