hacks/dump-imessages/iphone-dataprotection/python_scripts/demo_backup_keychain.py

157 lines
5.3 KiB
Python

#!/usr/bin/env python
import sys, os
from PyQt4 import QtGui, QtCore
from backups.backup4 import MBDB
from keychain.keychain4 import Keychain4
from util.bplist import BPlistReader
from keystore.keybag import Keybag
from util import readPlist
class KeychainTreeWidget(QtGui.QTreeWidget):
def __init__(self, parent=None):
QtGui.QTreeWidget.__init__(self, parent)
self.setGeometry(10, 10, 780, 380)
self.header().hide()
self.setColumnCount(2)
class KeychainTreeWidgetItem(QtGui.QTreeWidgetItem):
def __init__(self, title):
QtGui.QTreeWidgetItem.__init__(self, [title])
fnt = self.font(0)
fnt.setBold(True)
self.setFont(0, fnt)
self.setColors()
def setText(self, column, title):
QtGui.QTreeWidgetItem.setText(self, column, title)
def setColors(self):
self.setForeground(0, QtGui.QBrush(QtGui.QColor(80, 80, 80)))
self.setBackground(0, QtGui.QBrush(QtGui.QColor(230, 230, 230)))
self.setBackground(1, QtGui.QBrush(QtGui.QColor(230, 230, 230)))
class LockedKeychainTreeWidgetItem(KeychainTreeWidgetItem):
def setColors(self):
self.setForeground(0, QtGui.QBrush(QtGui.QColor(255, 80, 80)))
self.setBackground(0, QtGui.QBrush(QtGui.QColor(255, 230, 230)))
self.setBackground(1, QtGui.QBrush(QtGui.QColor(255, 230, 230)))
class KeychainWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(100, 100, 800, 400)
self.setWindowTitle('Keychain Explorer')
self.passwordTree = KeychainTreeWidget(parent=self)
def setGenericPasswords(self, pwds):
self.genericPasswords = pwds
self.passwordItems = KeychainTreeWidgetItem('Generic Passwords')
for pwd in self.genericPasswords:
if not pwd.has_key('acct'):
continue
if len(pwd['acct']) > 0:
item_title = '%s (%s)' % (pwd['svce'], pwd['acct'])
else:
item_title = pwd['svce']
if pwd['data'] is None:
item = LockedKeychainTreeWidgetItem(item_title)
else:
item = KeychainTreeWidgetItem(item_title)
item.addChild(QtGui.QTreeWidgetItem(['Service', pwd['svce']]))
item.addChild(QtGui.QTreeWidgetItem(['Account', pwd['acct']]))
if pwd['data'] is not None:
item.addChild(QtGui.QTreeWidgetItem(['Data', pwd['data']]))
else:
item.addChild(QtGui.QTreeWidgetItem(['Data', 'N/A']))
item.addChild(QtGui.QTreeWidgetItem(['Access Group', pwd['agrp']]))
self.passwordItems.addChild(item)
self.passwordTree.addTopLevelItem(self.passwordItems)
self.passwordTree.expandAll()
self.passwordTree.resizeColumnToContents(0)
def setInternetPasswords(self, pwds):
self.internetPasswords = pwds
self.internetPasswordItems = KeychainTreeWidgetItem('Internet Passwords')
for pwd in pwds:
item_title = '%s (%s)' % (pwd['srvr'], pwd['acct'])
item = KeychainTreeWidgetItem(item_title)
item.addChild(QtGui.QTreeWidgetItem(['Server', pwd['srvr']]))
item.addChild(QtGui.QTreeWidgetItem(['Account', pwd['acct']]))
if pwd['data'] is not None:
item.addChild(QtGui.QTreeWidgetItem(['Data', pwd['data']]))
else:
item.addChild(QtGui.QTreeWidgetItem(['Data', 'N/A']))
item.addChild(QtGui.QTreeWidgetItem(['Port', str(pwd['port'])]))
item.addChild(QtGui.QTreeWidgetItem(['Access Group', pwd['agrp']]))
self.internetPasswordItems.addChild(item)
self.passwordTree.addTopLevelItem(self.internetPasswordItems)
self.passwordTree.expandAll()
self.passwordTree.resizeColumnToContents(0)
def warn(msg):
print "WARNING: %s" % msg
def getBackupKeyBag(backupfolder, passphrase):
manifest = readPlist(backupfolder + "/Manifest.plist")
kb = Keybag(manifest["BackupKeyBag"].data)
if kb.unlockBackupKeybagWithPasscode(passphrase):
print "BackupKeyBag unlock OK"
return kb
else:
return None
def main():
app = QtGui.QApplication(sys.argv)
init_path = "{0:s}/Apple Computer/MobileSync/Backup".format(os.getenv('APPDATA'))
dirname = QtGui.QFileDialog.getExistingDirectory(None, "Select iTunes backup directory", init_path)
kb = getBackupKeyBag(dirname, 'pouet') #XXX: hardcoded password for demo
if not kb:
warn("Backup keybag unlock fail : wrong passcode?")
return
db = MBDB(dirname)
db.keybag = kb
filename, record = db.get_file_by_name("keychain-backup.plist")
keychain_data = db.read_file(filename, record)
f = file('keychain.tmp', 'wb')
f.write(keychain_data)
f.close()
kc = Keychain4('keychain.tmp', kb)
pwds = kc.get_passwords()
inet_pwds = kc.get_inet_passwords()
qb = KeychainWindow()
qb.setGenericPasswords(pwds)
qb.setInternetPasswords(inet_pwds)
qb.show()
sys.exit(app.exec_())
pass
if __name__ == '__main__':
main()