blob: d3d2e4d575ec8ab9e50ca7e715fbe73d4760fc73 [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generates and passes authentication credentials to Chromium.
This script can be used to simulate the login manager's process of
passing authentication credentials to Chromium. Running this script
will authenticate with Google Accounts with the provided login
credentials and then write the result to the specified pipe. The
script will then block until the pipe is read. To launch Chromium,
use the command:
./chrome --cookie-pipe=/tmp/cookie_pipe
"""
from optparse import OptionParser
import getpass
import os
import sys
import urllib
import urllib2
DEFAULT_COOKIE_PIPE = '/tmp/cookie_pipe'
GOOGLE_ACCOUNTS_URL = 'https://www.google.com/accounts'
LOGIN_SOURCE = 'test_harness'
class CookieCollectorRedirectHandler(urllib2.HTTPRedirectHandler):
def __init__(self):
self.__cookie_headers = []
@property
def cookie_headers(self):
return self.__cookie_headers
def http_error_302(self, req, fp, code, msg, headers):
self.__cookie_headers.extend(fp.info().getallmatchingheaders('Set-Cookie'))
result = urllib2.HTTPRedirectHandler.http_error_302(self, req, fp,
code, msg, headers)
return result
def Authenticate(email, password):
opener = urllib2.build_opener()
payload = urllib.urlencode({'Email': email,
'Passwd': password,
'PersistentCookie': 'true',
'accountType' : 'HOSTED_OR_GOOGLE',
'source' : LOGIN_SOURCE})
request = urllib2.Request(GOOGLE_ACCOUNTS_URL + '/ClientLogin', payload)
response = opener.open(request)
data = response.read().rstrip()
# Convert the SID=xxx\nLSID=yyy\n response into a dict.
l = [p.split('=') for p in data.split('\n')]
cookies = dict((i[0], i[1]) for i in l)
payload = urllib.urlencode({'SID': cookies['SID'],
'LSID': cookies['LSID'],
'source': LOGIN_SOURCE,
'service': 'gaia'})
request = urllib2.Request(GOOGLE_ACCOUNTS_URL + '/IssueAuthToken', payload)
response = opener.open(request)
auth_token = response.read().rstrip()
url = '/TokenAuth?continue=http://www.google.com/&source=%s&auth=%s' % \
(LOGIN_SOURCE, auth_token)
# Install a custom redirect handler here so we can catch all the
# cookies served as the redirects get processed.
cookie_collector = CookieCollectorRedirectHandler()
opener = urllib2.build_opener(cookie_collector)
request = urllib2.Request(GOOGLE_ACCOUNTS_URL + url)
response = opener.open(request)
cookie_headers = cookie_collector.cookie_headers
cookie_headers.extend(response.info().getallmatchingheaders('Set-Cookie'))
cookies = [s.replace('Set-Cookie: ', '') for s in cookie_headers]
return cookies
def WriteToPipe(pipe_path, data):
if os.path.exists(pipe_path):
os.remove(pipe_path)
os.mkfifo(pipe_path)
f = open(pipe_path, 'w')
f.write(data)
f.close()
def main():
usage = "usage: %prog [options]"
parser = OptionParser(usage)
parser.add_option('--email', dest='email',
help='email address used for login')
parser.add_option('--password', dest='password',
help='password used for login (will prompt if omitted)')
parser.add_option('--cookie-pipe', dest='cookiepipe',
default=DEFAULT_COOKIE_PIPE,
help='path of cookie pipe [default: %default]')
(options, args) = parser.parse_args()
if options.email is None:
parser.error("You must supply an email address.")
if options.password is None:
options.password = getpass.getpass()
cookies = Authenticate(options.email, options.password)
data = ''.join(cookies)
print 'Writing to "%s":' % options.cookiepipe
print data
WriteToPipe(options.cookiepipe, data)
if __name__ == '__main__':
main()