CMB now uses browser2 instead of hellhttp

This commit is contained in:
Johann Broudin 2014-03-13 18:24:44 +01:00 committed by Romain Bignon
commit 0fe6358f59
2 changed files with 19 additions and 206 deletions

View file

@ -23,6 +23,7 @@ from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import ValueBackendPassword, ValueBool
from weboob.capabilities.base import NotAvailable
from weboob.tools.browser import BrowserIncorrectPassword, BrokenPageError
from weboob.tools.browser2 import BaseBrowser
from re import match, compile, sub
from urllib import urlencode
@ -31,16 +32,8 @@ from lxml import etree
from datetime import date
from StringIO import StringIO
from ssl import DER_cert_to_PEM_cert
from hashlib import sha256
import os
# import a library that adds certificate verification and proxy support to
# HTTPSConnection
from hellhttp import HellHTTPS
__all__ = ['CmbBackend']
@ -53,7 +46,8 @@ class CmbBackend(BaseBackend, ICapBank):
LICENSE = 'AGPLv3+'
AUTH_CERT = os.path.dirname(__file__)
AUTH_CERT += '/Verisign_Class_3_Public_Primary_Certification_Authority.pem'
CERTHASH = '684d79eb02f59497b5a9c5dcc4c26db1ee637db12f29d703fdf6a80aafef892d'
# CERTHASH is not used anymore
# CERTHASH = '684d79eb02f59497b5a9c5dcc4c26db1ee637db12f29d703fdf6a80aafef892d'
DESCRIPTION = u'Crédit Mutuel de Bretagne'
CONFIG = BackendConfig(
ValueBackendPassword('login', label='Identifiant', masked=False),
@ -97,7 +91,9 @@ class CmbBackend(BaseBackend, ICapBank):
)
]
BROWSER = BaseBrowser
cookie = None
islogged = False
headers = {
'User-Agent':
'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OSX; en-us) ' +
@ -110,55 +106,28 @@ class CmbBackend(BaseBackend, ICapBank):
return certhash == self.CERTHASH
def login(self):
params = urlencode({
data = {
'codeEspace': 'NO',
'codeEFS': '01',
'codeSi': '001',
'noPersonne': self.config['login'].get(),
'motDePasse': self.config['password'].get()
})
if 'no_check' in self.config and self.config['no_check'].get() == "y":
conn = HellHTTPS("www.cmb.fr")
else:
conn = HellHTTPS("www.cmb.fr", ca_file=self.AUTH_CERT, callBack=self.sslCallBack)
conn.connect()
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
conn.request("POST",
"/domiweb/servlet/Identification",
params,
headers)
response = conn.getresponse()
conn.close()
if response.status == 302:
self.cookie = response.getheader('Set-Cookie').split(';')[0]
self.cookie += ';'
return True
}
response = self.browser.open("https://www.cmb.fr/domiweb/servlet/Identification", None, False, data=data)
if response.status_code == 302:
self.islogged=True
return True
else:
raise BrowserIncorrectPassword()
return False
def iter_accounts(self):
if not self.cookie:
if not self.islogged:
self.login()
def do_http():
if 'no_check' in self.config and self.config['no_check'].get() == "y":
conn = HellHTTPS("www.cmb.fr")
else:
conn = HellHTTPS("www.cmb.fr", ca_file=self.AUTH_CERT, callBack=self.sslCallBack)
conn.connect()
headers = self.headers
headers['Cookie'] = self.cookie
conn.request("GET",
'/domiweb/prive/particulier/releve/0-releve.act',
{},
headers)
response = conn.getresponse()
data = response.read()
conn.close()
return data
data = do_http()
data = self.browser.open("https://www.cmb.fr/domiweb/prive/particulier/releve/0-releve.act").content
parser = etree.HTMLParser()
tree = etree.parse(StringIO(data), parser)
@ -167,7 +136,7 @@ class CmbBackend(BaseBackend, ICapBank):
title = tree.xpath('/html/head/title')[0].text
if title == u"Utilisateur non identifié":
self.login()
data = do_http()
data = self.browser.open("https://www.cmb.fr/domiweb/prive/particulier/releve/0-releve.act").content
parser = etree.HTMLParser()
tree = etree.parse(StringIO(data), parser)
@ -216,7 +185,7 @@ class CmbBackend(BaseBackend, ICapBank):
raise AccountNotFound()
def iter_history(self, account):
if not self.cookie:
if not self.islogged:
self.login()
page = "/domiweb/prive/particulier/releve/"
@ -230,21 +199,7 @@ class CmbBackend(BaseBackend, ICapBank):
page += account._cmbvaleur2
page += "&deviseOrigineEcran=EUR"
def do_http():
if 'no_check' in self.config and self.config['no_check'].get() == "y":
conn = HellHTTPS("www.cmb.fr")
else:
conn = HellHTTPS("www.cmb.fr", ca_file=self.AUTH_CERT, callBack=self.sslCallBack)
conn.connect()
headers = self.headers
headers['Cookie'] = self.cookie
conn.request("GET", page, {}, headers)
response = conn.getresponse()
data = response.read()
conn.close
return data
data = do_http()
data = self.browser.open(page).content
parser = etree.HTMLParser()
tree = etree.parse(StringIO(data), parser)
@ -253,7 +208,7 @@ class CmbBackend(BaseBackend, ICapBank):
title = tree.xpath('/html/head/title')[0].text
if title == u"Utilisateur non identifié":
self.login()
data = do_http()
data = self.browser.open(page).content
parser = etree.HTMLParser()
tree = etree.parse(StringIO(data), parser)

View file

@ -1,142 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2012 Johann Broudin
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import httplib
import socket
import ssl
import hashlib
from urlparse import urlsplit
__all__ = ['HTTPSVerifiedConnection', 'HellHTTPS']
PROXY_PORT = 8080
class HTTPSVerifiedConnection(httplib.HTTPSConnection):
"""
This class allows communication via SSL, and will checks certificates
"""
def __init__(self, host, port=None, key_file=None, cert_file=None,
ca_file=None, strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
callBack=None):
httplib.HTTPSConnection.__init__(self, host, port, key_file,
cert_file, strict, timeout)
self.ca_file = ca_file
self.callBack = callBack
self.certificate = None
def connect(self):
"""
Connect to a host on a given port and check the certificate
This is almost the same than the conect of HTTPSConnection, but adds
some function for SSL certificate verification
"""
sock = socket.create_connection((self.host, self.port), self.timeout)
if self._tunnel_host:
self.sock = sock
self._tunnel()
if self.ca_file:
self.sock = ssl.wrap_socket(sock,
self.key_file,
self.cert_file,
ca_certs = self.ca_file,
cert_reqs=ssl.CERT_REQUIRED)
else:
self.sock = ssl.wrap_socket(sock,
self.key_file,
self.cert_file,
cert_reqs=ssl.CERT_NONE)
self.certificate = self.sock.getpeercert(True)
if self.callBack:
if not self.callBack(self.certificate):
raise ssl.SSLError(1, "Call back verification failed")
class HellHTTPS(object):
"This class is the library used by the weboob's CMB module"
def __init__(self, host, port=None, proxy=None, proxy_port=None,
key_file=None, cert_file=None, ca_file=None, strict=None,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT, callBack=None):
self.proxy = proxy
self.proxy_port = proxy_port
if not self.proxy:
import os
if 'http_proxy' in os.environ:
o = urlsplit(os.environ['http_proxy'])
self.proxy = o.hostname
if o.port:
self.proxy_port = o.port
else:
self.proxy_port = PROXY_PORT
self.host = host
self.port = port
if self.proxy:
if self.proxy_port:
pport = self.proxy_port
else:
pport = PROXY_PORT
self.conn = HTTPSVerifiedConnection(proxy, pport, key_file,
cert_file, ca_file, strict, timeout, callBack)
else:
self.conn = HTTPSVerifiedConnection(host, port, key_file, cert_file,
ca_file, strict, timeout, callBack)
def request(self, *args, **kwargs):
self.conn.request(*args, **kwargs)
def connect(self):
# set the proxy
# python 2.6 needs _set_tunnel, 2.7 needs set_tunnel
if self.proxy:
self.conn._set_tunnel(self.host, self.port)
self.conn.connect()
def getresponse(self, *args):
return self.conn.getresponse(*args)
def close(self):
self.conn.close
# A script to find the hash that has to be used in the call back function
if __name__ == '__main__':
import sys
if len(sys.argv) > 5 or len(sys.argv) < 1:
print 'usage: python %s host [port [proxy [proxy_port]]]' % sys.argv[0]
sys.exit(1)
conn = HellHTTPS(*sys.argv[1:])
conn.connect()
conn.request('GET', '/')
response = conn.getresponse()
print response.status, response.reason
pemcert = ssl.DER_cert_to_PEM_cert(conn.conn.certificate)
certhash = hashlib.sha256(pemcert).hexdigest()
print "Hash: %s" % certhash
conn.close()