0
|
1 |
#
|
|
2 |
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
# All rights reserved.
|
|
4 |
# This component and the accompanying materials are made available
|
|
5 |
# under the terms of "Eclipse Public License v1.0"
|
|
6 |
# which accompanies this distribution, and is available
|
|
7 |
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
#
|
|
9 |
# Initial Contributors:
|
|
10 |
# Nokia Corporation - initial contribution.
|
|
11 |
#
|
|
12 |
# Contributors:
|
|
13 |
#
|
|
14 |
# Description:
|
|
15 |
#
|
|
16 |
|
|
17 |
"""
|
|
18 |
|
|
19 |
"""
|
|
20 |
|
|
21 |
|
|
22 |
import getpass
|
|
23 |
import urllib, urllib2
|
|
24 |
import urlparse
|
|
25 |
from HTMLParser import HTMLParser
|
|
26 |
import sys
|
|
27 |
import os
|
|
28 |
import logging
|
|
29 |
import re
|
|
30 |
|
|
31 |
|
|
32 |
class SSOHTMLParser(HTMLParser):
|
|
33 |
"""
|
|
34 |
Simple html parser which understand what is needed to show the current
|
|
35 |
version of the SSO login page. End parsing at <\html>, which is in
|
|
36 |
current version of login page inside <noscript> before other stuff on page.
|
|
37 |
Asks form inputs of types text and password from the user.
|
|
38 |
The data is saved in varables inside class
|
|
39 |
"""
|
|
40 |
def __init__(self, *argv, **kwargs):
|
|
41 |
HTMLParser.__init__(self, *argv, **kwargs)
|
|
42 |
self.html_end = False
|
|
43 |
self.httpdata = {}
|
|
44 |
self.input_requested = False
|
|
45 |
self.input_entered = False
|
|
46 |
self.method = ''
|
|
47 |
self.action = ''
|
|
48 |
self.username = kwargs.get('username')
|
|
49 |
self.password = kwargs.get('password')
|
|
50 |
|
|
51 |
def handle_starttag(self, tag, attrs):
|
|
52 |
attrs = dict(attrs)
|
|
53 |
if self.html_end:
|
|
54 |
return
|
|
55 |
if tag == 'br':
|
|
56 |
print
|
|
57 |
elif tag == 'form':
|
|
58 |
self.action = attrs.get('action')
|
|
59 |
self.method = attrs.get('method')
|
|
60 |
elif tag == 'input':
|
|
61 |
inputtype = attrs.get('type', 'text')
|
|
62 |
if inputtype == 'hidden':
|
|
63 |
# Should the username be also overridable
|
|
64 |
self.httpdata[attrs.get('name')] = attrs.get('value')
|
|
65 |
if inputtype == 'password':
|
|
66 |
self.input_requested = True
|
|
67 |
data = self.password
|
|
68 |
if data:
|
|
69 |
self.input_entered = True
|
|
70 |
self.httpdata[attrs.get('name')] = data
|
|
71 |
if inputtype == 'text':
|
|
72 |
self.input_requested = True
|
|
73 |
data = raw_input()
|
|
74 |
if data:
|
|
75 |
self.input_entered = True
|
|
76 |
self.httpdata[attrs.get('name')] = data
|
|
77 |
if inputtype == 'submit':
|
|
78 |
self.httpdata['submit'] = attrs.get('value')
|
|
79 |
|
|
80 |
def handle_endtag(self, tag):
|
|
81 |
if self.html_end:
|
|
82 |
return
|
|
83 |
if tag == 'tr':
|
|
84 |
print
|
|
85 |
if tag == 'title':
|
|
86 |
print
|
|
87 |
if tag == 'html':
|
|
88 |
self.html_end = True
|
|
89 |
|
|
90 |
def handle_data(self, data):
|
|
91 |
if self.html_end:
|
|
92 |
return
|
|
93 |
if data.strip():
|
|
94 |
print data.strip(),
|
|
95 |
|
|
96 |
class CarbonAuthHandler(urllib2.AbstractHTTPHandler):
|
|
97 |
handler_order = 600
|
|
98 |
|
|
99 |
def add_password(self, username, password):
|
|
100 |
"""
|
|
101 |
Add username and password
|
|
102 |
"""
|
|
103 |
self.username = username
|
|
104 |
self.password = password
|
|
105 |
|
|
106 |
def https_response(self, request, response):
|
|
107 |
"""
|
|
108 |
Catches responses which are from sso login page and asks for the
|
|
109 |
information from the command line and posts it.
|
|
110 |
After posting urllib2 takes care of following redirects back to
|
|
111 |
original page.
|
|
112 |
"""
|
|
113 |
if (re.match('login.*\.europe\.nokia\.com', request.get_host())):
|
|
114 |
sso_parser = SSOHTMLParser(username=self.username, password=self.password)
|
|
115 |
sso_parser.feed(response.read())
|
|
116 |
# !sso_parser.input_requested when we have posted the form and
|
|
117 |
# are reading the redirect back. We don't want to handle that
|
|
118 |
if sso_parser.input_requested:
|
|
119 |
if not sso_parser.input_entered:
|
|
120 |
# By entering empty username and password you get
|
|
121 |
# out of infinite invalid login loop
|
|
122 |
# Only bad thing that the SSO login page doesen't
|
|
123 |
# tell you that login failed, only shows the same text
|
|
124 |
# again
|
|
125 |
raise urllib2.URLError("No login data entered")
|
|
126 |
newurl = urlparse.urljoin(request.get_full_url(), sso_parser.action)
|
|
127 |
ssoreq = urllib2.Request(newurl,
|
|
128 |
urllib.urlencode(sso_parser.httpdata),
|
|
129 |
origin_req_host=request.get_origin_req_host(),
|
|
130 |
unverifiable=True,
|
|
131 |
)
|
|
132 |
return self.parent.open(ssoreq)
|
|
133 |
return response
|
|
134 |
|
|
135 |
def http_response(self, request, response):
|
|
136 |
"""
|
|
137 |
Catches responses which are from normal carbon authenticatoin page and uses set password if found
|
|
138 |
or asks for the information from the command line and posts it.
|
|
139 |
After posting urllib2 takes care of following redirects back to
|
|
140 |
original page.
|
|
141 |
"""
|
|
142 |
if response.code == 200 and (re.match('.*/extauth/login/?.*', request.get_full_url())):
|
|
143 |
loginreq = urllib2.Request(request.get_full_url(),
|
|
144 |
urllib.urlencode({ 'username' : self.username,
|
|
145 |
'password' : self.password,
|
|
146 |
'submit' : 'login'}
|
|
147 |
),
|
|
148 |
origin_req_host=request.get_origin_req_host(),
|
|
149 |
unverifiable=True,
|
|
150 |
)
|
|
151 |
return self.parent.open(loginreq)
|
|
152 |
else:
|
|
153 |
return response
|