mirror of
https://github.com/borgbackup/borg.git
synced 2026-06-11 01:41:57 -04:00
commit
0fa548beac
16 changed files with 59 additions and 20 deletions
21
.github/workflows/ci.yml
vendored
21
.github/workflows/ci.yml
vendored
|
|
@ -40,9 +40,28 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
- uses: chartboost/ruff-action@v1
|
||||
|
||||
security:
|
||||
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install bandit[toml]
|
||||
- name: Run Bandit
|
||||
run: |
|
||||
bandit -r src/borg -c pyproject.toml
|
||||
|
||||
linux:
|
||||
|
||||
needs: lint
|
||||
needs: [lint, security]
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ ignore_missing_imports = true
|
|||
|
||||
[tool.tox]
|
||||
requires = ["tox>=4.19", "pkgconfig", "cython", "wheel", "setuptools_scm"]
|
||||
env_list = ["py{310,311,312,313}-{none,fuse2,fuse3}", "docs", "ruff", "mypy"]
|
||||
env_list = ["py{310,311,312,313}-{none,fuse2,fuse3}", "docs", "ruff", "mypy", "bandit"]
|
||||
|
||||
[tool.tox.env_run_base]
|
||||
package = "editable-legacy" # without this it does not find setup_docs when running under fakeroot
|
||||
|
|
@ -195,3 +195,15 @@ commands = [["mypy", "--ignore-missing-imports"]]
|
|||
change_dir = "docs"
|
||||
deps = ["sphinx", "sphinxcontrib-jquery", "guzzle_sphinx_theme"]
|
||||
commands = [["sphinx-build", "-n", "-v", "-W", "--keep-going", "-b", "html", "-d", "{envtmpdir}/doctrees", ".", "{envtmpdir}/html"]]
|
||||
|
||||
[tool.bandit]
|
||||
exclude_dirs = [".cache", ".eggs", ".git", ".git-rewrite", ".idea", ".mypy_cache", ".ruff_cache", ".tox", "build", "dist", "src/borg/testsuite"]
|
||||
skips = [
|
||||
"B101", # skip assert warnings, we do not allow running borg with assertions disabled.
|
||||
"B404", # do not warn about just import subprocess
|
||||
]
|
||||
|
||||
[tool.tox.env.bandit]
|
||||
skip_install = true
|
||||
deps = ["bandit[toml]"]
|
||||
commands = [["bandit", "-r", "src/borg", "-c", "pyproject.toml"]]
|
||||
|
|
|
|||
|
|
@ -12,3 +12,4 @@ pytest-cov
|
|||
pytest-benchmark
|
||||
Cython
|
||||
pre-commit
|
||||
bandit[toml]
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class CreateMixIn:
|
|||
try:
|
||||
try:
|
||||
env = prepare_subprocess_env(system=True)
|
||||
proc = subprocess.Popen(
|
||||
proc = subprocess.Popen( # nosec B603
|
||||
args.paths,
|
||||
stdout=subprocess.PIPE,
|
||||
env=env,
|
||||
|
|
@ -97,7 +97,7 @@ class CreateMixIn:
|
|||
if args.paths_from_command:
|
||||
try:
|
||||
env = prepare_subprocess_env(system=True)
|
||||
proc = subprocess.Popen(
|
||||
proc = subprocess.Popen( # nosec B603
|
||||
args.paths, stdout=subprocess.PIPE, env=env, preexec_fn=None if is_win32 else ignore_sigint
|
||||
)
|
||||
except (FileNotFoundError, PermissionError) as e:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class LocksMixIn:
|
|||
env = prepare_subprocess_env(system=True)
|
||||
try:
|
||||
# we exit with the return code we get from the subprocess
|
||||
rc = subprocess.call([args.command] + args.args, env=env)
|
||||
rc = subprocess.call([args.command] + args.args, env=env) # nosec B603
|
||||
set_ec(rc)
|
||||
except (FileNotFoundError, OSError, ValueError) as e:
|
||||
raise CommandError(f"Error while trying to run '{args.command}': {e}")
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ def pytest_report_header(config, start_path):
|
|||
def set_env_variables():
|
||||
os.environ["BORG_CHECK_I_KNOW_WHAT_I_AM_DOING"] = "YES"
|
||||
os.environ["BORG_DELETE_I_KNOW_WHAT_I_AM_DOING"] = "YES"
|
||||
os.environ["BORG_PASSPHRASE"] = "waytooeasyonlyfortests"
|
||||
os.environ["BORG_PASSPHRASE"] = "waytooeasyonlyfortests" # nosec B105
|
||||
os.environ["BORG_SELFTEST"] = "disabled"
|
||||
|
||||
|
||||
|
|
@ -103,7 +103,8 @@ def archiver(tmp_path, set_env_variables):
|
|||
os.environ["BORG_KEYS_DIR"] = archiver.keys_path
|
||||
os.environ["BORG_CACHE_DIR"] = archiver.cache_path
|
||||
os.mkdir(archiver.input_path)
|
||||
os.chmod(archiver.input_path, 0o777) # avoid troubles with fakeroot / FUSE
|
||||
# avoid troubles with fakeroot / FUSE:
|
||||
os.chmod(archiver.input_path, 0o777) # nosec B103
|
||||
os.mkdir(archiver.output_path)
|
||||
os.mkdir(archiver.keys_path)
|
||||
os.mkdir(archiver.cache_path)
|
||||
|
|
|
|||
|
|
@ -658,7 +658,7 @@ class FlexiKey:
|
|||
elif self.STORAGE == KeyBlobStorage.REPO:
|
||||
# While the repository is encrypted, we consider a repokey repository with a blank
|
||||
# passphrase an unencrypted repository.
|
||||
self.logically_encrypted = passphrase != ""
|
||||
self.logically_encrypted = passphrase != "" # nosec B105
|
||||
|
||||
# what we get in target is just a repo location, but we already have the repo obj:
|
||||
target = self.repository
|
||||
|
|
@ -688,7 +688,7 @@ class FlexiKey:
|
|||
fd.write(key_data)
|
||||
fd.write("\n")
|
||||
elif self.STORAGE == KeyBlobStorage.REPO:
|
||||
self.logically_encrypted = passphrase != ""
|
||||
self.logically_encrypted = passphrase != "" # nosec B105
|
||||
key_data = key_data.encode("utf-8") # remote repo: msgpack issue #99, giving bytes
|
||||
target.save_key(key_data)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -169,11 +169,11 @@ class ExclusiveLock:
|
|||
# should be cleaned up anyway. Try to clean up, but don't crash.
|
||||
try:
|
||||
os.unlink(temp_unique_name)
|
||||
except: # noqa
|
||||
except: # nosec B110 # noqa
|
||||
pass
|
||||
try:
|
||||
os.rmdir(temp_path)
|
||||
except: # noqa
|
||||
except: # nosec B110 # noqa
|
||||
pass
|
||||
|
||||
def release(self):
|
||||
|
|
|
|||
|
|
@ -558,9 +558,9 @@ def umount(mountpoint):
|
|||
|
||||
env = prepare_subprocess_env(system=True)
|
||||
try:
|
||||
rc = subprocess.call(["fusermount", "-u", mountpoint], env=env)
|
||||
rc = subprocess.call(["fusermount", "-u", mountpoint], env=env) # nosec B603, B607
|
||||
except FileNotFoundError:
|
||||
rc = subprocess.call(["umount", mountpoint], env=env)
|
||||
rc = subprocess.call(["umount", mountpoint], env=env) # nosec B603, B607
|
||||
set_ec(rc)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class Passphrase(str):
|
|||
# passcommand is a system command (not inside pyinstaller env)
|
||||
env = prepare_subprocess_env(system=True)
|
||||
try:
|
||||
passphrase = subprocess.check_output(shlex.split(passcommand), text=True, env=env)
|
||||
passphrase = subprocess.check_output(shlex.split(passcommand), text=True, env=env) # nosec B603
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
||||
raise PasscommandFailure(e)
|
||||
return cls(passphrase.rstrip("\n"))
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ def popen_with_error_handling(cmd_line: str, log_prefix="", **kwargs):
|
|||
return
|
||||
logger.debug("%scommand line: %s", log_prefix, command)
|
||||
try:
|
||||
return subprocess.Popen(command, **kwargs)
|
||||
return subprocess.Popen(command, **kwargs) # nosec B603
|
||||
except FileNotFoundError:
|
||||
logger.error("%sexecutable not found: %s", log_prefix, command[0])
|
||||
return
|
||||
|
|
|
|||
|
|
@ -275,7 +275,9 @@ class LegacyRemoteRepository:
|
|||
borg_cmd = self.ssh_cmd(location) + borg_cmd
|
||||
logger.debug("SSH command line: %s", borg_cmd)
|
||||
# we do not want the ssh getting killed by Ctrl-C/SIGINT because it is needed for clean shutdown of borg.
|
||||
self.p = Popen(borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint)
|
||||
self.p = Popen(
|
||||
borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint
|
||||
) # nosec B603
|
||||
self.stdin_fd = self.p.stdin.fileno()
|
||||
self.stdout_fd = self.p.stdout.fileno()
|
||||
self.stderr_fd = self.p.stderr.fileno()
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ def getfqdn(name=""):
|
|||
An empty argument is interpreted as meaning the local host.
|
||||
"""
|
||||
name = name.strip()
|
||||
if not name or name == "0.0.0.0":
|
||||
if not name or name == "0.0.0.0": # nosec B104:hardcoded_bind_all_interfaces
|
||||
name = socket.gethostname()
|
||||
try:
|
||||
addrs = socket.getaddrinfo(name, None, 0, socket.SOCK_DGRAM, 0, socket.AI_CANONNAME)
|
||||
|
|
|
|||
|
|
@ -576,7 +576,9 @@ class RemoteRepository:
|
|||
borg_cmd = self.ssh_cmd(location) + borg_cmd
|
||||
logger.debug("SSH command line: %s", borg_cmd)
|
||||
# we do not want the ssh getting killed by Ctrl-C/SIGINT because it is needed for clean shutdown of borg.
|
||||
self.p = Popen(borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint)
|
||||
self.p = Popen(
|
||||
borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint
|
||||
) # nosec B603
|
||||
self.stdin_fd = self.p.stdin.fileno()
|
||||
self.stdout_fd = self.p.stdout.fileno()
|
||||
self.stderr_fd = self.p.stderr.fileno()
|
||||
|
|
|
|||
|
|
@ -201,7 +201,9 @@ class Lock:
|
|||
logger.debug("LOCK-ACQUIRE: exclusive locks detected, deleting our shared lock.")
|
||||
self._delete_lock(key, ignore_not_found=True, update_last_refresh=True)
|
||||
# wait a random bit before retrying
|
||||
time.sleep(self.retry_delay_min + (self.retry_delay_max - self.retry_delay_min) * random.random())
|
||||
time.sleep(
|
||||
self.retry_delay_min + (self.retry_delay_max - self.retry_delay_min) * random.random() # nosec B311
|
||||
)
|
||||
logger.debug("LOCK-ACQUIRE: timeout while trying to acquire a lock.")
|
||||
raise LockTimeout(str(self.store))
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ if sys.platform.startswith("linux"):
|
|||
for preload in preloads:
|
||||
if preload.startswith("libfakeroot"):
|
||||
env = prepare_subprocess_env(system=True)
|
||||
fakeroot_output = subprocess.check_output(["fakeroot", "-v"], env=env)
|
||||
fakeroot_output = subprocess.check_output(["fakeroot", "-v"], env=env) # nosec B603, B607
|
||||
fakeroot_version = parse_version(fakeroot_output.decode("ascii").split()[-1])
|
||||
if fakeroot_version >= parse_version("1.20.2"):
|
||||
# 1.20.2 has been confirmed to have xattr support
|
||||
|
|
|
|||
Loading…
Reference in a new issue