diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f733832 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,59 @@ +name: Upload Python Package to PyPI when a Release is Created + +on: + workflow_dispatch: + release: + types: [created] + +jobs: + build_and_test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - ubuntu-24.04 + - macos-latest + - windows-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel build + - name: build + run: | + python setup.py build + - name: package + run: | + python -m build + publish: + needs: build_and_test + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/osquery + permissions: + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel build + - name: build + run: | + python setup.py build + - name: package + run: | + python -m build + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/README.md b/README.md index d4ceb86..62290b0 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ if __name__ == "__main__": # For an installed and running system osqueryd, this is: # Linux and macOS: /var/osquery/osquery.em # FreeBSD: /var/run/osquery.em - # Windows: \\.pipe\osquery.em + # Windows: \\.\pipe\osquery.em instance = osquery.ExtensionClient('/home/you/.osquery/osqueryd.sock') instance.open() # This may raise an exception @@ -150,6 +150,13 @@ python setup.py install See [CONTRIBUTING.md](https://github.com/osquery/osquery-python/blob/master/CONTRIBUTING.md) and the [osquery wiki](https://osquery.readthedocs.org) for development information. +### How To Release + +1. Pick a version number +2. Update `osquery/__init__.py` to match +3. Use the GitHub release +4. Make sure the GitHub Action ran + ### Vulnerabilities Facebook has a [bug bounty](https://www.facebook.com/whitehat/) program that includes osquery. If you find a security vulnerability in osquery, please submit it via the process outlined on that page and do not file a public issue. For more information on finding vulnerabilities in osquery, see a recent blog post about [bug-hunting osquery](https://www.facebook.com/notes/facebook-bug-bounty/bug-hunting-osquery/954850014529225). diff --git a/osquery/__init__.py b/osquery/__init__.py index 58c52b4..280298b 100644 --- a/osquery/__init__.py +++ b/osquery/__init__.py @@ -4,10 +4,10 @@ """ __title__ = "osquery" -__version__ = "3.0.6" -__author__ = "osquery developers" +__version__ = "3.1.1" +__author__ = "osquery authors" __license__ = "BSD" -__copyright__ = "Copyright 2015 Facebook" +__copyright__ = "Copyright 2015-present, The osquery authors" __url__ = "https://osquery.io" __all__ = [ diff --git a/osquery/management.py b/osquery/management.py index e93eccd..316aaa0 100644 --- a/osquery/management.py +++ b/osquery/management.py @@ -42,10 +42,12 @@ def emit(self, record): # We bootleg our own version of Windows pipe coms from osquery.TPipe import TPipe from osquery.TPipe import TPipeServer - if os.path.exists(os.environ["PROGRAMDATA"] + "\\osquery\\osqueryd\\osqueryd.exe"): - WINDOWS_BINARY_PATH = os.environ["PROGRAMDATA"] + "\\osquery\\osqueryd\\osqueryd.exe" - if os.path.exists(os.environ["PROGRAMW6432"] + "\\osquery\\osqueryd\\osqueryd.exe"): - WINDOWS_BINARY_PATH = os.environ["PROGRAMW6432"] + "\\osquery\\osqueryd\\osqueryd.exe" + PTH = os.path.join(os.environ["PROGRAMDATA"], "osquery", "osqueryd", "osqueryd.exe") + if os.path.exists(PTH): + WINDOWS_BINARY_PATH = PTH + PTH = os.path.join(os.environ["PROGRAMW6432"], "osquery", "osqueryd", "osqueryd.exe") + if os.path.exists(PTH): + WINDOWS_BINARY_PATH = PTH DARWIN_BINARY_PATH = "/usr/local/bin/osqueryd" LINUX_BINARY_PATH = "/usr/bin/osqueryd" @@ -98,6 +100,14 @@ def __del__(self): # On macOS and Linux mkstemp opens a descriptor. if self._socket is not None and self._socket[0] is not None: os.close(self._socket[0]) + + # Remove the dangling temporary file from mkstemp if it still exists + if os.path.exists(self._socket[1]): + try: + os.unlink(self._socket[1]) + except OSError: + logging.warning("Failed to remove socket descriptor: %s", self._socket[1]) + self._socket = None def open(self, timeout=2, interval=0.01): @@ -183,18 +193,27 @@ def start_watcher(client, interval): try: while True: status = client.extension_manager_client().ping() - if status.code is not 0: + if status.code != 0: + logging.error("Ping received nonzero status: %d", status) break time.sleep(interval) - except socket.error: - # The socket was torn down. - pass - os._exit(0) + + except socket.error as e: + logging.error("Ping received socket.error: %s", e) + + except TTransport.TTransportException as e: + logging.error("Ping received thrift.transport.TTransport.TTransportException: %s", e) + + except Exception as e: + logging.error("Ping received unknown exception: %s", e) + + finally: + os._exit(1) def start_extension(name="", version="0.0.0", - sdk_version="1.8.0", + sdk_version="3.0.7", min_sdk_version="1.8.0"): """Start your extension by communicating with osquery core and starting a thrift server. @@ -240,7 +259,7 @@ def start_extension(name="", message=message, ) - if status.code is not 0: + if status.code != 0: raise ExtensionException( code=1, message=status.message, @@ -292,7 +311,7 @@ def deregister_extension(): message=message, ) - if status.code is not 0: + if status.code != 0: raise ExtensionException( code=1, message=status.message, diff --git a/osquery/table_plugin.py b/osquery/table_plugin.py index 79b3d16..9046aa6 100644 --- a/osquery/table_plugin.py +++ b/osquery/table_plugin.py @@ -39,7 +39,7 @@ def call(self, context): if context["action"] == "generate": ctx = {} if "context" in context: - ctx = json.dumps(context["context"]) + ctx = json.loads(context["context"]) rows = self.generate(ctx) for i, row in enumerate(rows): for key, value in row.items(): diff --git a/setup.cfg b/setup.cfg index 87cb642..94f4887 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [metadata] -description-file = README.rst +description_file = README.rst [bdist_wheel] universal=1 diff --git a/setup.py b/setup.py index 5a74549..9ac5756 100755 --- a/setup.py +++ b/setup.py @@ -89,7 +89,6 @@ def run(self): ], install_requires=[ "thrift>=0.10", - "argparse>=1.1", "future", ], extras_require={