🔃 Sync Hub v0.4
This commit is contained in:
@@ -13,7 +13,7 @@ ENV PATH="/opt/venv/bin:$PATH"
|
|||||||
COPY . ${INSTALL_DIR}/
|
COPY . ${INSTALL_DIR}/
|
||||||
|
|
||||||
|
|
||||||
RUN pip install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython \
|
RUN pip install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython pycryptodome \
|
||||||
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
|
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
|
||||||
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
|
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
|
||||||
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ RUN phpenmod -v 8.2 sqlite3
|
|||||||
RUN apt-get install -y python3-venv
|
RUN apt-get install -y python3-venv
|
||||||
RUN python3 -m venv myenv
|
RUN python3 -m venv myenv
|
||||||
|
|
||||||
RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython"
|
RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython pycryptodome"
|
||||||
|
|
||||||
# Create a buildtimestamp.txt to later check if a new version was released
|
# Create a buildtimestamp.txt to later check if a new version was released
|
||||||
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt
|
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt
|
||||||
|
|||||||
@@ -432,6 +432,26 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"function": "encryption_key",
|
||||||
|
"type": "text",
|
||||||
|
"maxLength": 50,
|
||||||
|
"default_value": "",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Encryption Key"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Encryption key used to encrypt the sent data. The key needs to be the same on the hub and on the nodes."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"function": "CMD",
|
"function": "CMD",
|
||||||
"type": "readonly",
|
"type": "readonly",
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
// External files
|
// External files
|
||||||
require '/app/front/php/server/init.php';
|
require '/app/front/php/server/init.php';
|
||||||
|
|
||||||
|
|
||||||
|
function decrypt_data($encoded_data) {
|
||||||
|
// Base64 decode the encoded data
|
||||||
|
$decoded_data = base64_decode($encoded_data);
|
||||||
|
|
||||||
|
// Extract the initialization vector (IV) from the decoded data
|
||||||
|
$iv = substr($decoded_data, 0, 16);
|
||||||
|
|
||||||
|
// Extract the actual encrypted data
|
||||||
|
$encrypted_data = substr($decoded_data, 16);
|
||||||
|
|
||||||
|
// Get the encryption key from the settings
|
||||||
|
$key = hash('sha256', getSettingValue('SYNC_encryption_key'), true);
|
||||||
|
|
||||||
|
// Decrypt the data
|
||||||
|
$decrypted_data = openssl_decrypt($encrypted_data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
|
||||||
|
|
||||||
|
if ($decrypted_data === false) {
|
||||||
|
return null; // Decryption failed
|
||||||
|
}
|
||||||
|
|
||||||
|
return $decrypted_data;
|
||||||
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
// Retrieve the authorization header
|
// Retrieve the authorization header
|
||||||
$headers = apache_request_headers();
|
$headers = apache_request_headers();
|
||||||
@@ -22,7 +46,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$plugin_folder = $_POST['plugin_folder'] ?? '';
|
$plugin_folder = $_POST['plugin_folder'] ?? '';
|
||||||
$node_name = $_POST['node_name'] ?? '';
|
$node_name = $_POST['node_name'] ?? '';
|
||||||
|
|
||||||
$decoded_data = hex2bin($data);
|
$decoded_data = decrypt_data($data);
|
||||||
|
|
||||||
|
if ($decrypted_data === false or $decrypted_data === null) {
|
||||||
|
write_notification("[Plugin: Sync hub API] Bad Request: Decryption failed", "alert");
|
||||||
|
http_response_code(400);
|
||||||
|
echo 'Bad Request: Decryption failed';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$storage_path = "/app/front/plugins/{$plugin_folder}";
|
$storage_path = "/app/front/plugins/{$plugin_folder}";
|
||||||
|
|
||||||
// Create the storage directory if it doesn't exist
|
// Create the storage directory if it doesn't exist
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
|||||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||||
from plugin_utils import get_plugins_configs
|
from plugin_utils import get_plugins_configs
|
||||||
from logger import mylog
|
from logger import mylog
|
||||||
from helper import timeNowTZ, get_setting_value
|
from helper import timeNowTZ, get_setting_value, encrypt_data
|
||||||
|
|
||||||
# Define the current path and log file paths
|
# Define the current path and log file paths
|
||||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||||
@@ -23,12 +23,6 @@ RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
|
|||||||
|
|
||||||
pluginName = 'SYNC'
|
pluginName = 'SYNC'
|
||||||
|
|
||||||
# Function to encrypt data using a password
|
|
||||||
def encrypt_data(data, password):
|
|
||||||
key = hashlib.sha256(password.encode()).digest()
|
|
||||||
cipher = hashlib.pbkdf2_hmac('sha256', data.encode(), key, 100000)
|
|
||||||
return cipher.hex()
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
mylog('verbose', [f'[{pluginName}] In script'])
|
mylog('verbose', [f'[{pluginName}] In script'])
|
||||||
|
|
||||||
@@ -38,7 +32,8 @@ def main():
|
|||||||
|
|
||||||
# Retrieve configuration settings
|
# Retrieve configuration settings
|
||||||
plugins_to_sync = get_setting_value('SYNC_plugins')
|
plugins_to_sync = get_setting_value('SYNC_plugins')
|
||||||
api_token = get_setting_value('SYNC_api_token') # Use an API token instead of a password
|
api_token = get_setting_value('SYNC_api_token')
|
||||||
|
encryption_key = get_setting_value('SYNC_encryption_key')
|
||||||
hub_url = get_setting_value('SYNC_hub_url')
|
hub_url = get_setting_value('SYNC_hub_url')
|
||||||
node_name = get_setting_value('SYNC_node_name')
|
node_name = get_setting_value('SYNC_node_name')
|
||||||
|
|
||||||
@@ -63,9 +58,14 @@ def main():
|
|||||||
if os.path.exists(file_path):
|
if os.path.exists(file_path):
|
||||||
# Read the content of the log file
|
# Read the content of the log file
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'r') as f:
|
||||||
newLines = f.read()
|
file_content = f.read()
|
||||||
# Encrypt the log data using the API token
|
|
||||||
encrypted_data = encrypt_data(newLines, api_token)
|
mylog('verbose', [f'[{pluginName}] Sending file_content: "{file_content}"'])
|
||||||
|
|
||||||
|
# Encrypt the log data using the encryption_key
|
||||||
|
encrypted_data = encrypt_data(file_content, encryption_key)
|
||||||
|
|
||||||
|
mylog('verbose', [f'[{pluginName}] Sending encrypted_data: "{encrypted_data}"'])
|
||||||
|
|
||||||
# Prepare the data payload for the POST request
|
# Prepare the data payload for the POST request
|
||||||
data = {
|
data = {
|
||||||
@@ -84,7 +84,7 @@ def main():
|
|||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
mylog('verbose', [f'[{pluginName}] Data for "{plugin_folder}" sent successfully'])
|
mylog('verbose', [f'[{pluginName}] Data for "{plugin_folder}" sent successfully'])
|
||||||
else:
|
else:
|
||||||
mylog('error', [f'[{pluginName}] Failed to send data for "{plugin_folder}"'])
|
mylog('verbose', [f'[{pluginName}] Failed to send data for "{plugin_folder}"'])
|
||||||
|
|
||||||
# log result
|
# log result
|
||||||
plugin_objects.add_object(
|
plugin_objects.add_object(
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ source myenv/bin/activate
|
|||||||
update-alternatives --install /usr/bin/python python /usr/bin/python3 10
|
update-alternatives --install /usr/bin/python python /usr/bin/python3 10
|
||||||
|
|
||||||
# install packages thru pip3
|
# install packages thru pip3
|
||||||
pip3 install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython
|
pip3 install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython pycryptodome
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ import json
|
|||||||
import time
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import requests
|
import requests
|
||||||
|
from Crypto.Cipher import AES
|
||||||
|
from Crypto.Util.Padding import pad, unpad
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
import conf
|
import conf
|
||||||
from const import *
|
from const import *
|
||||||
@@ -798,6 +803,13 @@ def collect_lang_strings(json, pref, stringSqlParams):
|
|||||||
return stringSqlParams
|
return stringSqlParams
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt_data(data, key):
|
||||||
|
key = hashlib.sha256(key.encode()).digest() # Ensure the key is 32 bytes long
|
||||||
|
cipher = AES.new(key, AES.MODE_CBC) # Use CBC mode for encryption
|
||||||
|
iv = cipher.iv # Initialization vector
|
||||||
|
encrypted_data = cipher.encrypt(pad(data.encode(), AES.block_size))
|
||||||
|
return base64.b64encode(iv + encrypted_data).decode('utf-8')
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Misc
|
# Misc
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user