| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 | |
| 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | |
| 4 # Use of this source code is governed by a BSD-style license that can be | |
| 5 # found in the LICENSE file. | |
| 6 | |
| 7 """Generates and passes authentication credentials to Chromium. | |
| 8 | |
| 9 This script can be used to simulate the login manager's process of | |
| 10 passing authentication credentials to Chromium. Running this script | |
| 11 will authenticate with Google Accounts with the provided login | |
| 12 credentials and then write the result to the specified pipe. The | |
| 13 script will then block until the pipe is read. To launch Chromium, | |
| 14 use the command: | |
| 15 | |
| 16 ./chrome --cookie-pipe=/tmp/cookie_pipe | |
| 17 | |
| 18 """ | |
| 19 | |
| 20 from optparse import OptionParser | |
| 21 import getpass | |
| 22 import os | |
| 23 import sys | |
| 24 import urllib | |
| 25 import urllib2 | |
| 26 | |
| 27 DEFAULT_COOKIE_PIPE = '/tmp/cookie_pipe' | |
| 28 GOOGLE_ACCOUNTS_URL = 'https://www.google.com/accounts' | |
| 29 LOGIN_SOURCE = 'test_harness' | |
| 30 | |
| 31 | |
| 32 class CookieCollectorRedirectHandler(urllib2.HTTPRedirectHandler): | |
| 33 def __init__(self): | |
| 34 self.__cookie_headers = [] | |
| 35 | |
| 36 @property | |
| 37 def cookie_headers(self): | |
| 38 return self.__cookie_headers | |
| 39 | |
| 40 def http_error_302(self, req, fp, code, msg, headers): | |
| 41 self.__cookie_headers.extend(fp.info().getallmatchingheaders('Set-Cookie')) | |
| 42 result = urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, | |
| 43 code, msg, headers) | |
| 44 return result | |
| 45 | |
| 46 | |
| 47 def Authenticate(email, password): | |
| 48 opener = urllib2.build_opener() | |
| 49 payload = urllib.urlencode({'Email': email, | |
| 50 'Passwd': password, | |
| 51 'PersistentCookie': 'true', | |
| 52 'accountType' : 'HOSTED_OR_GOOGLE', | |
| 53 'source' : LOGIN_SOURCE}) | |
| 54 request = urllib2.Request(GOOGLE_ACCOUNTS_URL + '/ClientLogin', payload) | |
| 55 response = opener.open(request) | |
| 56 data = response.read().rstrip() | |
| 57 | |
| 58 # Convert the SID=xxx\nLSID=yyy\n response into a dict. | |
| 59 l = [p.split('=') for p in data.split('\n')] | |
| 60 cookies = dict((i[0], i[1]) for i in l) | |
| 61 | |
| 62 payload = urllib.urlencode({'SID': cookies['SID'], | |
| 63 'LSID': cookies['LSID'], | |
| 64 'source': LOGIN_SOURCE, | |
| 65 'service': 'gaia'}) | |
| 66 request = urllib2.Request(GOOGLE_ACCOUNTS_URL + '/IssueAuthToken', payload) | |
| 67 response = opener.open(request) | |
| 68 auth_token = response.read().rstrip() | |
| 69 | |
| 70 url = '/TokenAuth?continue=http://www.google.com/&source=%s&auth=%s' % \ | |
| 71 (LOGIN_SOURCE, auth_token) | |
| 72 | |
| 73 # Install a custom redirect handler here so we can catch all the | |
| 74 # cookies served as the redirects get processed. | |
| 75 cookie_collector = CookieCollectorRedirectHandler() | |
| 76 opener = urllib2.build_opener(cookie_collector) | |
| 77 request = urllib2.Request(GOOGLE_ACCOUNTS_URL + url) | |
| 78 response = opener.open(request) | |
| 79 | |
| 80 cookie_headers = cookie_collector.cookie_headers | |
| 81 cookie_headers.extend(response.info().getallmatchingheaders('Set-Cookie')) | |
| 82 cookies = [s.replace('Set-Cookie: ', '') for s in cookie_headers] | |
| 83 return cookies | |
| 84 | |
| 85 def WriteToPipe(pipe_path, data): | |
| 86 if os.path.exists(pipe_path): | |
| 87 os.remove(pipe_path) | |
| 88 os.mkfifo(pipe_path) | |
| 89 f = open(pipe_path, 'w') | |
| 90 f.write(data) | |
| 91 f.close() | |
| 92 | |
| 93 def main(): | |
| 94 usage = "usage: %prog [options]" | |
| 95 parser = OptionParser(usage) | |
| 96 parser.add_option('--email', dest='email', | |
| 97 help='email address used for login') | |
| 98 parser.add_option('--password', dest='password', | |
| 99 help='password used for login (will prompt if omitted)') | |
| 100 parser.add_option('--cookie-pipe', dest='cookiepipe', | |
| 101 default=DEFAULT_COOKIE_PIPE, | |
| 102 help='path of cookie pipe [default: %default]') | |
| 103 (options, args) = parser.parse_args() | |
| 104 | |
| 105 if options.email is None: | |
| 106 parser.error("You must supply an email address.") | |
| 107 | |
| 108 if options.password is None: | |
| 109 options.password = getpass.getpass() | |
| 110 | |
| 111 cookies = Authenticate(options.email, options.password) | |
| 112 data = ''.join(cookies) | |
| 113 print 'Writing to "%s":' % options.cookiepipe | |
| 114 print data | |
| 115 WriteToPipe(options.cookiepipe, data) | |
| 116 | |
| 117 if __name__ == '__main__': | |
| 118 main() | |
| OLD | NEW |