From cadf7da18ee19b7cdc0f998a3c3d75f500686eba Mon Sep 17 00:00:00 2001 From: "skrul@google.com" Date: Tue, 10 Nov 2009 00:46:45 +0000 Subject: [PATCH] Script to send credentials into the cookie pipe, emulating the login manager. This was previously reviewed but checked into the wrong repo. Review URL: http://chromereview.prom.corp.google.com/1187016 git-svn-id: svn://chrome-svn/chromeos/trunk@196 06c00378-0e64-4dae-be16-12b19f9950a1 --- test_cookie_pipe.py | 117 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100755 test_cookie_pipe.py diff --git a/test_cookie_pipe.py b/test_cookie_pipe.py new file mode 100755 index 0000000000..5a93e6ef2a --- /dev/null +++ b/test_cookie_pipe.py @@ -0,0 +1,117 @@ +#!/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): + 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()