diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..5703025 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +max-line-length = 120 +ignore = E501, W503, C901 +exclude = build/ \ No newline at end of file diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml new file mode 100644 index 0000000..f7934e8 --- /dev/null +++ b/.github/workflows/python-app.yml @@ -0,0 +1,43 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python application + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Set up Python path + run: echo "PYTHONPATH=$PWD" >> $GITHUB_ENV + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Install the lshell package + run: pip install . + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pytest diff --git a/lshell/checkconfig.py b/lshell/checkconfig.py index 36f6976..ae7105b 100644 --- a/lshell/checkconfig.py +++ b/lshell/checkconfig.py @@ -42,15 +42,15 @@ class CheckConfig: def __init__(self, args, refresh=None, stdin=None, stdout=None, stderr=None): """Force the calling of the methods below""" - if stdin == None: + if stdin is None: self.stdin = sys.stdin else: self.stdin = stdin - if stdout == None: + if stdout is None: self.stdout = sys.stdout else: self.stdout = stdout - if stderr == None: + if stderr is None: self.stderr = sys.stderr else: self.stderr = stderr @@ -598,7 +598,7 @@ def get_config_user(self): if os.path.isdir(self.conf["home_path"]): # change dir to home when initially loading the configuration - if self.refresh == None: + if self.refresh is None: os.chdir(self.conf["home_path"]) # if reloading the configuration, do not change directory else: @@ -803,9 +803,7 @@ def set_noexec(self): self.conf["path_noexec"] = self.myeval(self.conf_raw["path_noexec"]) # if path_noexec is empty, disable LD_PRELOAD # /!\ this feature should be used at the administrator's own risks! - if self.conf["path_noexec"] == "": - return if not os.path.exists(self.conf["path_noexec"]): self.log.critical( diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e28801a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +configparser +logging +readline +pexpect \ No newline at end of file diff --git a/test/test_functional.py b/test/test_functional.py index cb69f8c..5c0fd32 100644 --- a/test/test_functional.py +++ b/test/test_functional.py @@ -632,14 +632,26 @@ def test_38_script_execution_with_template(self): template_path = f"{TOPDIR}/test/template.lsh" test_script_path = f"{TOPDIR}/test/test.lsh" + wrapper_path = f"{TOPDIR}/bin/lshell_wrapper" + + # Step 1: Create the wrapper script + with open(wrapper_path, "w") as wrapper: + wrapper.write( + f"""#!/bin/bash +exec {TOPDIR}/bin/lshell --config {TOPDIR}/etc/lshell.conf "$@" +""" + ) + + # Make the wrapper executable + os.chmod(wrapper_path, 0o755) - # Copy template.lsh to test.lsh + # Step 2: Copy template.lsh to test.lsh and replace the shebang shutil.copy(template_path, test_script_path) # Replace the placeholder in the shebang with open(test_script_path, "r+") as f: content = f.read() - content = content.replace("#!SHEBANG", f"#!{TOPDIR}/bin/lshell") + content = content.replace("#!SHEBANG", f"#!{wrapper_path}") f.seek(0) f.write(content) f.truncate() @@ -648,7 +660,7 @@ def test_38_script_execution_with_template(self): self.child = pexpect.spawn(f"{test_script_path}") # Expected output - expected_output = f"""test\r + expected_output = """test\r *** forbidden command: dig\r *** forbidden path: /tmp/\r FREEDOM\r @@ -681,8 +693,8 @@ def test_39_script_execution_with_template_strict(self): with open(wrapper_path, "w") as wrapper: wrapper.write( f"""#!/bin/bash - exec {TOPDIR}/bin/lshell --config {TOPDIR}/etc/lshell.conf --strict 1 "$@" - """ +exec {TOPDIR}/bin/lshell --config {TOPDIR}/etc/lshell.conf --strict 1 "$@" +""" ) # Make the wrapper executable @@ -702,7 +714,7 @@ def test_39_script_execution_with_template_strict(self): self.child = pexpect.spawn(f"{test_script_path}") # Expected output - expected_output = f"""test\r + expected_output = """test\r *** forbidden command -> "dig"\r *** You have 1 warning(s) left, before getting kicked out.\r This incident has been reported.\r