Advertisement
Guest User

Untitled

a guest
Aug 17th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.13 KB | None | 0 0
  1.  
  2.  
  3.  
  4. import sys
  5. import time
  6. import itertools
  7. from xml.dom.minidom import parse, getDOMImplementation
  8.  
  9. class ElementTransformator(object):
  10.    
  11.     icon_map = dict(creditcard='66',
  12.                     cryptokey='58',
  13.                     database='43',
  14.                     door='60',
  15.                     email='19',
  16.                     ftp='49',
  17.                     generic='13',
  18.                     phone='68',
  19.                     shell='30',
  20.                     website='57')
  21.    
  22.     fields = {'generic-hostname': 'url',
  23.               'generic-certificate': 'comment',
  24.               'generic-keyfile': 'username',
  25.               'generic-password': 'password',
  26.               'generic-username': 'username',
  27.               'generic-database': 'url',
  28.               'generic-location': 'comment',
  29.               'generic-code': 'password',
  30.               'generic-email': 'comment',
  31.               'generic-port': 'comment',
  32.               'generic-url': 'url',
  33.               'generic-pin': 'password',
  34.               'generic-domain': 'comment',
  35.               'phone-phonenumber': 'comment',
  36.               'creditcard-cardtype': None,
  37.               'creditcard-cardnumber': None,
  38.               'creditcard-expirydate': None,
  39.               'creditcard-ccv': None}
  40.        
  41.        
  42.     def __init__(self, src_doc):
  43.        
  44.         self._src_doc = src_doc
  45.        
  46.         impl = getDOMImplementation()
  47.        
  48.         dt= impl.createDocumentType('KEEPASSX_DATABASE', None, None)
  49.        
  50.         self._dst_doc = impl.createDocument(None, 'database', dt)
  51.        
  52.         self._dst_doc.documentElement
  53.         self._top_element = self._dst_doc.createElement('group')
  54.         self._dst_doc.documentElement.appendChild(self._top_element)
  55.         title = self._dst_doc.createElement('title')
  56.         title.appendChild(self._dst_doc.createTextNode('Revelation Import'))
  57.         self._top_element.appendChild(title)
  58.         icon = self._dst_doc.createElement('icon')
  59.         icon.appendChild(self._dst_doc.createTextNode('48'))
  60.         self._top_element.appendChild(icon)
  61.        
  62.         self._unknown_counter = itertools.count().next
  63.        
  64.         self._make_entry_helper()
  65.    
  66.     def parse(self):
  67.         try:
  68.             dataelem = self._src_doc.getElementsByTagName('revelationdata')[0]
  69.         except IndexError:
  70.             return
  71.        
  72.         for child in dataelem.childNodes:
  73.             try:
  74.                 tagname = child.tagName
  75.             except AttributeError:
  76.                 continue
  77.            
  78.             if tagname == 'entry':
  79.                 self.parse_entry_elem(child)
  80.    
  81.     def write(self, dst):
  82.        
  83.         with open(dst, 'wb') as fout:
  84.             #self._dst_doc.writexml(fout, encoding='utf-8', addindent='  ', newl='\n')
  85.             self._dst_doc.writexml(fout, encoding='utf-8')
  86.            
  87.    
  88.     def _make_entry_helper(self):
  89.         unknown = lambda: 'unknown_%03d' % self._unknown_counter()
  90.         none = lambda: None
  91.        
  92.         formatted_time_not = self._format_epoch_time()
  93.         times = lambda: formatted_time_not
  94.        
  95.         self._entry_helper = dict(title=unknown,
  96.                                   username=none,
  97.                                   password=none,
  98.                                   url=none,
  99.                                   comment=none,
  100.                                   icon=lambda: '0',
  101.                                   creation=times,
  102.                                   lastaccess=times,
  103.                                   lastmod=times,
  104.                                   expire=lambda: 'Nie')
  105.    
  106.    
  107.     def parse_entry_elem(self, entry):
  108.        
  109.         enytry_type = entry.attributes['type'].value
  110.         if enytry_type == 'folder':
  111.             self._handle_folder(entry)
  112.             return
  113.        
  114.        
  115.         param_dict = {}
  116.        
  117.         e_title = e_comment = e_updated = None
  118.        
  119.         for c in entry.childNodes:
  120.             try:
  121.                 tagname = c.tagName
  122.             except AttributeError:
  123.                 # text node
  124.                 continue
  125.            
  126.             if tagname == 'name':
  127.                 e_title = self._textchilddata(c)
  128.            
  129.             if tagname == 'description':
  130.                 e_comment = self._textchilddata(c)
  131.                    
  132.             if tagname == 'updated':
  133.                 e_updated = self._format_epoch_time(self._textchilddata(c))
  134.                
  135.             if tagname == 'field':
  136.                 self._parse_field(c, param_dict)
  137.                
  138.         if e_comment:
  139.             try:
  140.                 from_field = param_dict['comment']
  141.             except KeyError:
  142.                 from_field = ''
  143.            
  144.             param_dict['comment'] = '%s\n%s' % (e_comment, from_field)
  145.        
  146.         param_dict.update(dict(title=e_title,
  147.                                icon=self.icon_map[enytry_type],
  148.                                creation=e_updated,
  149.                                lastaccess=e_updated,
  150.                                lastmod=e_updated,
  151.                                expire=None))
  152.        
  153.         self._dump_entry(param_dict)
  154.  
  155.     def _format_epoch_time(self, epoch=None):
  156.         if not epoch:
  157.             epoch = time.time()
  158.         return time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(float(epoch)))
  159.    
  160.     def _textchilddata(self, elem):
  161.         try:
  162.             data = elem.childNodes[0].data
  163.         except IndexError:
  164.             return None
  165.        
  166.         return data.encode(self._src_doc.encoding)
  167.    
  168.     def _dump_entry(self, edict):
  169.        
  170.         entry = self._dst_doc.createElement('entry')
  171.         self._top_element.appendChild(entry)
  172.        
  173.         for membername, defaults in self._entry_helper.iteritems():
  174.            
  175.             value = edict.get(membername, None)
  176.                
  177.             if value is None:
  178.                 value = defaults()
  179.            
  180.             member = self._dst_doc.createElement(membername)
  181.             if value:
  182.                 member.appendChild(self._dst_doc.createTextNode(value))
  183.             entry.appendChild(member)
  184.    
  185.     def _parse_field(self, fieldelem, param=None):
  186.  
  187.         if param is None:
  188.             param = {}
  189.        
  190.         try:
  191.             field_id = fieldelem.attributes['id'].value
  192.         except KeyError:
  193.             print 'illegal field'
  194.             return param
  195.            
  196.         try:
  197.             key = self.fields[field_id]
  198.         except KeyError:
  199.             print 'unknown field: %s' % field_id
  200.             return param
  201.        
  202.         if key:
  203.             param[key] = self._textchilddata(fieldelem)
  204.        
  205.        
  206.     def _handle_folder(self, elem):
  207.         group = self._dst_doc.createElement('group')
  208.         self._top_element.appendChild(group)
  209.         parentgroup = self._top_element
  210.         self._top_element = group
  211.        
  212.         groupname = None
  213.         for c in elem.childNodes:
  214.             try:
  215.                 tagname = c.tagName
  216.             except AttributeError:
  217.                 # text node
  218.                 continue
  219.            
  220.             if tagname == 'name':
  221.                 groupname = self._textchilddata(c)
  222.            
  223.             elif tagname == 'entry':
  224.                 self.parse_entry_elem(c)
  225.            
  226.         if not groupname:
  227.             groupname = 'unknown_%03d' % self._unknown_counter()
  228.        
  229.         title = self._dst_doc.createElement('title')
  230.         title.appendChild(self._dst_doc.createTextNode(groupname))
  231.         group.appendChild(title)
  232.  
  233.         icon = self._dst_doc.createElement('icon')
  234.         icon.appendChild(self._dst_doc.createTextNode('48'))
  235.         group.appendChild(icon)
  236.        
  237.         self._top_element = parentgroup
  238.        
  239.  
  240. def main(src, dst):
  241.    
  242.     with open(src) as inf:
  243.         src_doc = parse(inf)
  244.    
  245.     et = ElementTransformator(src_doc)
  246.     et.parse()
  247.     et.write(dst)
  248.  
  249. if __name__ == '__main__':
  250.     try:
  251.         s, d = sys.argv[1:3]
  252.     except ValueError:
  253.         print 'usage: %s <source Revelation XML DB path> <target KeePassX XML DB path>' % sys.argv[0]
  254.         sys.exit(1)
  255.    
  256.     main(s, d)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement