OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 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 """Registers new hosts in chromoting directory. | 6 """Registers new hosts in chromoting directory. |
7 | 7 |
8 It asks for username/password and then writes these settings to config file. | 8 It asks for username/password and then writes these settings to config file. |
9 """ | 9 """ |
10 | 10 |
| 11 import base64 |
11 import getpass | 12 import getpass |
| 13 import hashlib |
| 14 import hmac |
| 15 import json |
12 import os | 16 import os |
13 import urllib | |
14 import urllib2 | |
15 import random | 17 import random |
16 import socket | 18 import socket |
17 import sys | 19 import sys |
| 20 import urllib |
| 21 import urllib2 |
18 | 22 |
19 import gaia_auth | 23 import gaia_auth |
20 import keygen | 24 import keygen |
21 | 25 |
22 def random_uuid(): | 26 def random_uuid(): |
23 return ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x" % | 27 return ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x" % |
24 tuple(map(lambda x: random.randrange(0,65536), range(8)))) | 28 tuple(map(lambda x: random.randrange(0,65536), range(8)))) |
25 | 29 |
26 | 30 |
27 def main(): | 31 def main(): |
(...skipping 12 matching lines...) Expand all Loading... |
40 | 44 |
41 host_id = random_uuid() | 45 host_id = random_uuid() |
42 print "HostId:", host_id | 46 print "HostId:", host_id |
43 host_name = socket.gethostname() | 47 host_name = socket.gethostname() |
44 print "HostName:", host_name | 48 print "HostName:", host_name |
45 | 49 |
46 print "Generating RSA key pair...", | 50 print "Generating RSA key pair...", |
47 (private_key, public_key) = keygen.generateRSAKeyPair() | 51 (private_key, public_key) = keygen.generateRSAKeyPair() |
48 print "Done" | 52 print "Done" |
49 | 53 |
50 params = ('{"data":{' + | 54 while 1: |
51 '"hostId": "%(hostId)s",' + | 55 pin = getpass.getpass("Host PIN (can be empty): ") |
52 '"hostName": "%(hostName)s",' + | 56 if len(pin) > 0 and len(pin) < 4: |
53 '"publicKey": "%(publicKey)s"}}') % \ | 57 print "PIN must be at least 4 characters long." |
54 {'hostId': host_id, 'hostName': host_name, | 58 continue |
55 'publicKey': public_key} | 59 break |
| 60 if pin == "": |
| 61 host_secret_hash = None |
| 62 else: |
| 63 host_secret_hash = "hmac:" + base64.b64encode( |
| 64 hmac.new(str(host_id), pin, hashlib.sha256).digest()) |
| 65 |
| 66 params = { "data": { |
| 67 "hostId": host_id, |
| 68 "hostName": host_name, |
| 69 "publicKey": public_key, |
| 70 } } |
56 headers = {"Authorization": "GoogleLogin auth=" + auth_token, | 71 headers = {"Authorization": "GoogleLogin auth=" + auth_token, |
57 "Content-Type": "application/json" } | 72 "Content-Type": "application/json" } |
58 request = urllib2.Request(url, params, headers) | 73 request = urllib2.Request(url, json.dumps(params), headers) |
59 | 74 |
60 opener = urllib2.OpenerDirector() | 75 opener = urllib2.OpenerDirector() |
61 opener.add_handler(urllib2.HTTPDefaultErrorHandler()) | 76 opener.add_handler(urllib2.HTTPDefaultErrorHandler()) |
62 | 77 |
63 print | 78 print |
64 print "Registering host with directory service..." | 79 print "Registering host with directory service..." |
65 try: | 80 try: |
66 res = urllib2.urlopen(request) | 81 res = urllib2.urlopen(request) |
67 data = res.read() | 82 data = res.read() |
68 except urllib2.HTTPError, err: | 83 except urllib2.HTTPError, err: |
69 print >> sys.stderr, "Directory returned error:", err | 84 print >> sys.stderr, "Directory returned error:", err |
70 print >> sys.stderr, err.fp.read() | 85 print >> sys.stderr, err.fp.read() |
71 return 1 | 86 return 1 |
72 | 87 |
73 print "Done" | 88 print "Done" |
74 | 89 |
75 # Get token that the host will use to athenticate in talk network. | 90 # Get token that the host will use to athenticate in talk network. |
76 authenticator = gaia_auth.GaiaAuthenticator('chromiumsync'); | 91 authenticator = gaia_auth.GaiaAuthenticator('chromiumsync'); |
77 auth_token = authenticator.authenticate(email, password) | 92 auth_token = authenticator.authenticate(email, password) |
78 | 93 |
79 # Write settings file. | 94 # Write settings file. |
80 os.umask(0066) # Set permission mask for created file. | 95 os.umask(0066) # Set permission mask for created file. |
81 settings_file = open(settings_filepath, 'w') | 96 settings_file = open(settings_filepath, 'w') |
82 settings_file.write('{\n'); | 97 config = { |
83 settings_file.write(' "xmpp_login" : "' + email + '",\n') | 98 "xmpp_login" : email, |
84 settings_file.write(' "xmpp_auth_token" : "' + auth_token + '",\n') | 99 "xmpp_auth_token" : auth_token, |
85 settings_file.write(' "host_id" : "' + host_id + '",\n') | 100 "host_id" : host_id, |
86 settings_file.write(' "host_name" : "' + host_name + '",\n') | 101 "host_name" : host_name, |
87 settings_file.write(' "private_key" : "' + private_key + '",\n') | 102 "private_key" : private_key, |
88 settings_file.write('}\n') | 103 } |
| 104 |
| 105 if host_secret_hash: |
| 106 config["host_secret_hash"] = host_secret_hash; |
| 107 |
| 108 settings_file.write(json.dumps(config, indent=2)) |
89 settings_file.close() | 109 settings_file.close() |
90 | 110 |
91 print 'Configuration saved in', settings_filepath | 111 print 'Configuration saved in', settings_filepath |
92 return 0 | 112 return 0 |
93 | 113 |
94 | 114 |
95 if __name__ == '__main__': | 115 if __name__ == '__main__': |
96 sys.exit(main()) | 116 sys.exit(main()) |
OLD | NEW |