mirror of
https://github.com/netinvent/npbackup.git
synced 2025-10-27 13:57:26 +08:00
Only hide encrypted env variables, leave standard ones available
This commit is contained in:
parent
11dd20a4d4
commit
34f920d008
4 changed files with 59 additions and 11 deletions
|
|
@ -23,7 +23,7 @@ This will prevent local backups, so we need to think of a better zero knowledge
|
||||||
# NPF-SEC-00005: Viewer mode can bypass permissions
|
# NPF-SEC-00005: Viewer mode can bypass permissions
|
||||||
|
|
||||||
Since viewer mode requires actual knowledge of repo URI and repo password, there's no need to manage local permissions.
|
Since viewer mode requires actual knowledge of repo URI and repo password, there's no need to manage local permissions.
|
||||||
Viewer mode permissions are set to "restore".
|
Viewer mode permissions are set to "restore-only".
|
||||||
|
|
||||||
# NPF-SEC-00006: Never inject permissions if some are already present
|
# NPF-SEC-00006: Never inject permissions if some are already present
|
||||||
|
|
||||||
|
|
@ -61,3 +61,7 @@ Using obfuscation() symmetric function in order to not store the bare AES key.
|
||||||
# NPF-SEC-00012: Don't add PRIVATE directory to wheel / bdist builds
|
# NPF-SEC-00012: Don't add PRIVATE directory to wheel / bdist builds
|
||||||
|
|
||||||
The PRIVATE directory might contain alternative AES keys and obfuscation functions which should never be bundled for a PyPI release.
|
The PRIVATE directory might contain alternative AES keys and obfuscation functions which should never be bundled for a PyPI release.
|
||||||
|
|
||||||
|
# NPF-SEC-00013: Don't leave encrypted envrionment variables for script usage
|
||||||
|
|
||||||
|
Sensible environment variables aren't available for scripts / additional parameters and will be replaced by a given string from __env__.py
|
||||||
|
|
@ -43,4 +43,8 @@ def set_build_type(build_type: str) -> None:
|
||||||
BUILD_TYPE = build_type
|
BUILD_TYPE = build_type
|
||||||
|
|
||||||
|
|
||||||
|
# Allowed server ids for upgrade
|
||||||
ALLOWED_UPGRADE_SERVER_IDS = ("npbackup.upgrader", "npbackup.deployment_server")
|
ALLOWED_UPGRADE_SERVER_IDS = ("npbackup.upgrader", "npbackup.deployment_server")
|
||||||
|
|
||||||
|
# Replacement string for sensible data
|
||||||
|
HIDDEN_BY_NPBACKUP = "_[o_O]_hidden_by_npbackup"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ __intname__ = "npbackup.gui.core.runner"
|
||||||
__author__ = "Orsiris de Jong"
|
__author__ = "Orsiris de Jong"
|
||||||
__copyright__ = "Copyright (C) 2022-2025 NetInvent"
|
__copyright__ = "Copyright (C) 2022-2025 NetInvent"
|
||||||
__license__ = "GPL-3.0-only"
|
__license__ = "GPL-3.0-only"
|
||||||
__build__ = "2025021201"
|
__build__ = "2025021202"
|
||||||
|
|
||||||
|
|
||||||
from typing import Optional, Callable, Union, List
|
from typing import Optional, Callable, Union, List
|
||||||
|
|
@ -857,7 +857,6 @@ class NPBackupRunner:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
encrypted_env_variables = []
|
encrypted_env_variables = []
|
||||||
|
|
||||||
env_variables += encrypted_env_variables
|
|
||||||
expanded_env_vars = {}
|
expanded_env_vars = {}
|
||||||
if isinstance(env_variables, list):
|
if isinstance(env_variables, list):
|
||||||
for env_variable in env_variables:
|
for env_variable in env_variables:
|
||||||
|
|
@ -874,8 +873,26 @@ class NPBackupRunner:
|
||||||
)
|
)
|
||||||
logger.debug("Trace:", exc_info=True)
|
logger.debug("Trace:", exc_info=True)
|
||||||
|
|
||||||
|
expanded_encrypted_env_vars = {}
|
||||||
|
if isinstance(encrypted_env_variables, list):
|
||||||
|
for encrypted_env_variable in encrypted_env_variables:
|
||||||
|
if isinstance(encrypted_env_variable, dict):
|
||||||
|
for k, v in encrypted_env_variable.items():
|
||||||
|
try:
|
||||||
|
v = os.path.expanduser(v)
|
||||||
|
v = os.path.expandvars(v)
|
||||||
|
expanded_encrypted_env_vars[k.strip()] = v.strip()
|
||||||
|
except Exception as exc:
|
||||||
|
self.write_logs(
|
||||||
|
f"Cannot expand encrypted environment variable {k}: {exc}",
|
||||||
|
level="error",
|
||||||
|
)
|
||||||
|
logger.debug("Trace:", exc_info=True)
|
||||||
try:
|
try:
|
||||||
self.restic_runner.environment_variables = expanded_env_vars
|
self.restic_runner.environment_variables = expanded_env_vars
|
||||||
|
self.restic_runner.encrypted_environment_variables = (
|
||||||
|
expanded_encrypted_env_vars
|
||||||
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.write_logs(
|
self.write_logs(
|
||||||
"Cannot initialize additional environment variables", level="error"
|
"Cannot initialize additional environment variables", level="error"
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ __intname__ = "npbackup.restic_wrapper"
|
||||||
__author__ = "Orsiris de Jong"
|
__author__ = "Orsiris de Jong"
|
||||||
__copyright__ = "Copyright (C) 2022-2025 NetInvent"
|
__copyright__ = "Copyright (C) 2022-2025 NetInvent"
|
||||||
__license__ = "GPL-3.0-only"
|
__license__ = "GPL-3.0-only"
|
||||||
__build__ = "2025012201"
|
__build__ = "2025021201"
|
||||||
__version__ = "2.3.6"
|
__version__ = "2.4.0"
|
||||||
|
|
||||||
|
|
||||||
from typing import Tuple, List, Optional, Callable, Union
|
from typing import Tuple, List, Optional, Callable, Union
|
||||||
|
|
@ -28,6 +28,7 @@ from npbackup.__env__ import (
|
||||||
CHECK_INTERVAL,
|
CHECK_INTERVAL,
|
||||||
HEARTBEAT_INTERVAL,
|
HEARTBEAT_INTERVAL,
|
||||||
BUILD_TYPE,
|
BUILD_TYPE,
|
||||||
|
HIDDEN_BY_NPBACKUP
|
||||||
)
|
)
|
||||||
from npbackup.path_helper import CURRENT_DIR
|
from npbackup.path_helper import CURRENT_DIR
|
||||||
from npbackup.restic_wrapper import schema
|
from npbackup.restic_wrapper import schema
|
||||||
|
|
@ -96,6 +97,7 @@ class ResticRunner:
|
||||||
self._ignore_cloud_files = True
|
self._ignore_cloud_files = True
|
||||||
self._additional_parameters = None
|
self._additional_parameters = None
|
||||||
self._environment_variables = {}
|
self._environment_variables = {}
|
||||||
|
self._encrypted_environment_variables = {}
|
||||||
|
|
||||||
# Function which will make executor abort if result is True
|
# Function which will make executor abort if result is True
|
||||||
self._stop_on = None
|
self._stop_on = None
|
||||||
|
|
@ -137,6 +139,16 @@ class ResticRunner:
|
||||||
)
|
)
|
||||||
os.environ[env_variable] = value
|
os.environ[env_variable] = value
|
||||||
|
|
||||||
|
for (
|
||||||
|
encrypted_env_variable,
|
||||||
|
value,
|
||||||
|
) in self.encrypted_environment_variables.items():
|
||||||
|
self.write_logs(
|
||||||
|
f'Setting encrypted envrionment variable "{encrypted_env_variable}"',
|
||||||
|
level="debug",
|
||||||
|
)
|
||||||
|
os.environ[encrypted_env_variable] = value
|
||||||
|
|
||||||
# Configure default cpu usage when not specifically set
|
# Configure default cpu usage when not specifically set
|
||||||
if not "GOMAXPROCS" in self.environment_variables:
|
if not "GOMAXPROCS" in self.environment_variables:
|
||||||
nb_cores = os.cpu_count()
|
nb_cores = os.cpu_count()
|
||||||
|
|
@ -154,11 +166,12 @@ class ResticRunner:
|
||||||
"""
|
"""
|
||||||
Unsets repository & password environment, we don't need to keep that data when not requested
|
Unsets repository & password environment, we don't need to keep that data when not requested
|
||||||
"""
|
"""
|
||||||
os.environ["RESTIC_PASSWORD"] = "o_O"
|
os.environ["RESTIC_PASSWORD"] = HIDDEN_BY_NPBACKUP
|
||||||
os.environ["RESTIC_REPOSITORY"] = self.repository_anonymous
|
os.environ["RESTIC_REPOSITORY"] = self.repository_anonymous
|
||||||
|
|
||||||
for env_variable in self.environment_variables.keys():
|
# NPF-SEC-00013 Don't leave encrypted environment variables for script usage
|
||||||
os.environ[env_variable] = "__ooOO(° °)OOoo__"
|
for encrypted_env_variable in self.encrypted_environment_variables.keys():
|
||||||
|
os.environ[encrypted_env_variable] = HIDDEN_BY_NPBACKUP
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def stdout(self) -> Optional[Union[int, str, Callable, queue.Queue]]:
|
def stdout(self) -> Optional[Union[int, str, Callable, queue.Queue]]:
|
||||||
|
|
@ -268,7 +281,7 @@ class ResticRunner:
|
||||||
@property
|
@property
|
||||||
def repository_anonymous(self):
|
def repository_anonymous(self):
|
||||||
if self.repository:
|
if self.repository:
|
||||||
return self.repository.split(":")[0] + ":_(o_O)_hidden_by_npbackup"
|
return self.repository.split(":")[0] + ":" + HIDDEN_BY_NPBACKUP
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def write_logs(
|
def write_logs(
|
||||||
|
|
@ -519,9 +532,19 @@ class ResticRunner:
|
||||||
@environment_variables.setter
|
@environment_variables.setter
|
||||||
def environment_variables(self, value):
|
def environment_variables(self, value):
|
||||||
if not isinstance(value, dict):
|
if not isinstance(value, dict):
|
||||||
raise ValueError("Bogus environment variables set")
|
raise ValueError(f"Bogus environment variables set: {value}")
|
||||||
self._environment_variables = value
|
self._environment_variables = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def encrypted_environment_variables(self):
|
||||||
|
return self._encrypted_environment_variables
|
||||||
|
|
||||||
|
@encrypted_environment_variables.setter
|
||||||
|
def encrypted_environment_variables(self, value):
|
||||||
|
if not isinstance(value, dict):
|
||||||
|
raise ValueError(f"Bogus encrypted environment variables set: {value}")
|
||||||
|
self._encrypted_environment_variables = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def binary(self):
|
def binary(self):
|
||||||
return self._binary
|
return self._binary
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue