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 |