From 4f7fe4f8432665bc047a6b2e0ce4feb7937778c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20Mazi=C3=A8re?= Date: Sun, 30 Oct 2011 01:30:48 +0200 Subject: [PATCH] LCL: fit the new authentification scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pierre Mazière Signed-off-by: Romain Bignon --- weboob/backends/lcl/browser.py | 5 ++- weboob/backends/lcl/pages.py | 73 ++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/weboob/backends/lcl/browser.py b/weboob/backends/lcl/browser.py index 6d3dcc87..d99bd0ab 100644 --- a/weboob/backends/lcl/browser.py +++ b/weboob/backends/lcl/browser.py @@ -33,7 +33,7 @@ class LCLBrowser(BaseBrowser): ENCODING = 'utf-8' USER_AGENT = BaseBrowser.USER_AGENTS['wget'] PAGES = { - 'https://particuliers.secure.lcl.fr/index.html': LoginPage, + 'https://particuliers.secure.lcl.fr/everest/UWBI/UWBIAccueil\?DEST=PAGEIDENT': LoginPage, 'https://particuliers.secure.lcl.fr/everest/UWBI/UWBIAccueil\?DEST=IDENTIFICATION': LoginResultPage, 'https://particuliers.secure.lcl.fr/outil/UWSP/Synthese/accesSynthese': AccountsPage, 'https://particuliers.secure.lcl.fr/outil/UWB2/Accueil\?DEST=INIT': FramePage, @@ -55,7 +55,8 @@ class LCLBrowser(BaseBrowser): assert self.agency.isdigit() if not self.is_on_page(LoginPage): - self.location('%s://%s/index.html' % (self.PROTOCOL, self.DOMAIN),\ + self.location('%s://%s/everest/UWBI/UWBIAccueil?DEST=PAGEIDENT' \ + % (self.PROTOCOL, self.DOMAIN), no_login=True) if not self.page.login(self.agency, self.username, self.password) or \ diff --git a/weboob/backends/lcl/pages.py b/weboob/backends/lcl/pages.py index d6191ece..6c09ffd8 100644 --- a/weboob/backends/lcl/pages.py +++ b/weboob/backends/lcl/pages.py @@ -17,18 +17,83 @@ # You should have received a copy of the GNU Affero General Public License # along with weboob. If not, see . - +import base64 from datetime import date from weboob.capabilities.bank import Operation from weboob.capabilities.bank import Account from weboob.tools.browser import BasePage, BrowserUnavailable +from weboob.tools.virtkeyboard import VirtKeyboard, VirtKeyboardError +from logging import error class LoginPage(BasePage): + def myXOR(self,value,seed): + s='' + for i in xrange(len(value)): + s+=chr(seed^ord(value[i])) + return s + def login(self, agency, login, passwd): + symbols={'0':'9da2724133f2221482013151735f033c', + '1':'873ab0087447610841ae1332221be37b', + '2':'93ce6c330393ff5980949d7b6c800f77', + '3':'b2d70c69693784e1bf1f0973d81223c0', + '4':'498c8f5d885611938f94f1c746c32978', + '5':'359bcd60a9b8565917a7bf34522052c3', + '6':'aba912172f21f78cd6da437cfc4cdbd0', + '7':'f710190d6b947869879ec02d8e851dfa', + '8':'b42cc25e1539a15f767aa7a641f3bfec', + '9':'cc60e5894a9d8e12ee0c2c104c1d5490' + } + + map=self.document.find("//map[@id='claviermap']") + + coords={} + for area in map.getiterator("area"): + code=area.attrib.get("onclick")[-5:-3] + area_coords=[] + for coord in area.attrib.get("coords").split(','): + area_coords.append(int(coord)) + coords[code]=tuple(area_coords) + try: + vk=VirtKeyboard(self.browser.openurl("/UWBI/UWBIAccueil?DEST=GENERATION_CLAVIER"), + coords,(255,255,255,255)) + except VirtKeyboardError,err: + error("Error: %s"%err) + return False + + for s in symbols.keys(): + try: + value=vk.get_symbol_code(symbols[s]) + except VirtKeyboardError: + if self.browser.responses_dirname is None: + self.browser.responses_dirname = \ + tempfile.mkdtemp(prefix='weboob_session_') + vk.generate_MD5(self.browser.responses_dirname) + error("Error: Symbol '%s' not found; all symbol hashes are available in %s" \ + % (s,self.browser.responses_dirname)) + return False + + password='' + for c in passwd: + password+=vk.get_symbol_code(symbols[c]) + seed=-1 + str="var aleatoire = " + for script in self.document.findall("/head/script"): + if(script.text is None or len(script.text)==0): + continue + offset=script.text.find(str) + if offset!=-1: + seed=int(script.text[offset+len(str):offset+len(str)+1]) + break + if seed==-1: + error("Variable 'aleatoire' not found") + return False + self.browser.select_form(nr=0) - self.browser['agenceId'] = agency - self.browser['compteId'] = login - self.browser['CodeId'] = passwd + self.browser.form.set_all_readonly(False) + self.browser['agenceId'] = base64.b64encode(self.myXOR(agency,seed)) + self.browser['compteId'] = base64.b64encode(self.myXOR(login,seed)) + self.browser['postClavier'] = base64.b64encode(self.myXOR(password,seed)) try: self.browser.submit() except BrowserUnavailable: