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