Home | History | Annotate | Download | only in tools
      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