Skip to content

Commit

Permalink
clawsmails added
Browse files Browse the repository at this point in the history
  • Loading branch information
Alessandro ZANNI committed Jul 2, 2016
1 parent 658a1a5 commit 6efadd8
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Linux/src/config/manageModules.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
# chats
from softwares.chats.pidgin import Pidgin
from softwares.chats.jitsi import Jitsi
# mails
from softwares.mails.clawsmail import ClawsMail
# wifi
from softwares.wifi.wifi import Wifi
from softwares.wifi.wpa_supplicant import Wpa_supplicant
Expand All @@ -33,6 +35,7 @@ def get_categories():

def get_modules():
moduleNames = [
ClawsMail(),
DbVisualizer(),
Env_variable(),
Filezilla(),
Expand Down
Empty file.
92 changes: 92 additions & 0 deletions Linux/src/softwares/mails/clawsmail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Thanks to https://github.com/b4n/clawsmail-password-decrypter
from Crypto.Cipher import DES
from base64 import standard_b64decode as b64decode
from ConfigParser import ConfigParser
from config.moduleInfo import ModuleInfo
from config.header import Header
from config.write_output import print_debug, print_output
import platform, os

class ClawsMail(ModuleInfo):
def __init__(self):
options = {'command': '-c', 'action': 'store_true', 'dest': 'clawsmail', 'help': 'clawsmail'}
ModuleInfo.__init__(self, 'clawsmail', 'mails', options)

def run(self):
# print the title
Header().title_info('ClawsMail')

path = self.get_path()
if not path:
print_debug('INFO', 'ClawsMail not installed.')

mode = DES.MODE_CFB
if 'FreeBSD' in platform.system():
mode = DES.MODE_ECB

pwdFound = self.accountrc_decrypt(path, self.get_passcrypt_key(), mode)

# print the results
print_output('ClawsMail', pwdFound)

def get_path(self):
file = '~/.claws-mail/accountrc'
file = os.path.expanduser(file)
if os.path.exists(file):
return file
else:
return None

def get_passcrypt_key(self):
PASSCRYPT_KEY = b'passkey0'
return PASSCRYPT_KEY

def pass_decrypt(self, p, key, mode=DES.MODE_CFB):
""" Decrypts a password from ClawsMail. """
if p[0] == '!': # encrypted password
buf = b64decode(p[1:])

"""
If mode is ECB or CBC and the length of the data is wrong, do nothing
as would the libc algorithms (as they fail early). Yes, this means the
password wasn't actually encrypted but only base64-ed.
"""
if (mode in (DES.MODE_ECB, DES.MODE_CBC)) and ((len(buf) % 8) != 0 or
len(buf) > 8192):
return buf

c = DES.new(key, mode=mode, IV=b'\0'*8)
return c.decrypt(buf)
else: # raw password
return p


def accountrc_decrypt(self, filename, key, mode=DES.MODE_CFB):
""" Reads passwords from ClawsMail's accountrc file """
p = ConfigParser()
p.read(filename)

pwdFound = []
for s in p.sections():
values = {}
try:
try:
address = p.get(s, 'address')
account = p.get(s, 'account_name')
except:
address = '<unknown>'
account = '<unknown>'

password = self.pass_decrypt(p.get(s, 'password'), key, mode=mode)
# print('password for %s, %s is "%s"' % (account, address, password))
values = {'Account' : account, 'Address': address, 'Password': password}
except Exception as e:
print_debug('ERROR', 'Error resolving password for account "%s": %s' % (s, e))

# write credentials into a text file
if len(values) != 0:
pwdFound.append(values)

return pwdFound

0 comments on commit 6efadd8

Please sign in to comment.