diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6f60715 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,37 @@ +--- +name: release + +# This workflow requires a PYPI_API_TOKEN secret to be defined in the GitHub +# repository settings. + +on: + release: + types: [created] + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set package version in setup.cfg + run: sed -i "s/^version = 0$/version = ${GITHUB_REF#refs/tags/v}/" setup.cfg + + - 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 build setuptools wheel twine + + - name: Build and publish + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} + run: | + python -m build + python -m twine upload dist/* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3aed9a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/sshkp/__pycache__/ + +/build/ +/dist/ + +/*.egg-info/ diff --git a/README.md b/README.md index cfb8baf..1bc3cfc 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,22 @@ # sshkp +[![GitHub release workflow](https://img.shields.io/github/workflow/status/dmotte/sshkp/release?logo=github&label=release&style=flat-square)](https://github.com/dmotte/sshkp/actions) +[![PyPI](https://img.shields.io/pypi/v/sshkp?logo=python&style=flat-square)](https://pypi.org/project/sshkp/) + :snake: Script to execute an **SSH command** using a password from a **KeePass database**. This project uses the [pykeepass](https://pypi.org/project/pykeepass/) library and the `sshpass` command line utility. Note that, for this to work, the title of your KeePass database entry should be written in a form that can be used with the `ssh` command, e.g. `user@hostname`. +## Installation + +This utility is available as a Python package on **PyPI**: + +```bash +pip3 install sshkp +``` + ## Usage ```bash @@ -17,25 +28,20 @@ sshkp user@hostname .print # just prints the SSH password If you don't set the `KP_PASSWORD` environment variable before calling the script, the password will be asked at runtime. -See `sshkp --help` for more information. - -It is advised to install the script in a directory under your `$PATH` (see [below](#installation)). +:information_source: For more details on how to use this command, you can also refer to the help message (`sshkp --help`). -## Installation +## Development -To install _sshkp_ you need to execute the following commands as root: +If you want to contribute to this project, the first thing you have to do is to **clone this repository** on your local machine: ```bash -apt update && apt install sshpass python3-pip -pip3 install -r requirements.txt - -curl -Lo "/usr/local/bin/sshkp" \ - https://github.com/dmotte/sshkp/releases/latest/download/sshkp -chmod +x "/usr/local/bin/sshkp" +git clone https://github.com/dmotte/sshkp.git ``` -:information_source: For **user installation** (no root needed, will only work for current user) we recommend `~/.local/bin` instead of `/usr/local/bin`. If it's not in your `$PATH`, you can add the following to your `.bashrc` or `.zshrc`: +Then you can install the package in **editable** mode: ```bash -export PATH="~/.local/bin:$PATH" +pip3 install -e . --user ``` + +This will just link the package to the original location, basically meaning any changes to the original package would reflect directly in your environment ([source](https://stackoverflow.com/a/35064498)). diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index ee65bcd..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pykeepass==4.0.1 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..1426744 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,42 @@ +[metadata] +name = sshkp +url = https://github.com/dmotte/sshkp +author = dmotte +license = MIT + +description = Script to execute an SSH command using a password from a KeePass database +long_description = + [![GitHub release workflow](https://img.shields.io/github/workflow/status/dmotte/sshkp/release?logo=github&label=release&style=flat-square)](https://github.com/dmotte/sshkp/actions) + [![PyPI](https://img.shields.io/pypi/v/sshkp?logo=python&style=flat-square)](https://pypi.org/project/sshkp/) + + Script to execute an **SSH command** using a password from a **KeePass database**. + + Please refer to the [GitHub repository](https://github.com/dmotte/sshkp) for more information. +long_description_content_type = text/markdown + +keywords = ssh database script password environment-variables keepass sshpass pykeepass sshkp kdbx command cli +classifiers = + Intended Audience :: End Users/Desktop + Environment :: Console + Natural Language :: English + License :: OSI Approved :: MIT License + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.9 + Topic :: Terminals + Topic :: Utilities + +# This version number will be replaced with the current git tag by the +# release.yml workflow +version = 0 + +[options] +install_requires = + pykeepass >= 4.0.1 +python_requires = >=3.9.1 +packages = sshkp + +[options.entry_points] +console_scripts = + sshkp = sshkp.cli:main diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..957cc1d --- /dev/null +++ b/setup.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +from setuptools import setup + +if __name__ == '__main__': + setup() diff --git a/sshkp/__init__.py b/sshkp/__init__.py new file mode 100644 index 0000000..6ef7f39 --- /dev/null +++ b/sshkp/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# To make all the functions defined in the cli module accessible by importing +# the root module +from .cli import * diff --git a/sshkp/__main__.py b/sshkp/__main__.py new file mode 100644 index 0000000..8e4cd13 --- /dev/null +++ b/sshkp/__main__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys + +from .cli import main + +if __name__ == '__main__': + sys.exit(main()) diff --git a/sshkp b/sshkp/cli.py similarity index 92% rename from sshkp rename to sshkp/cli.py index 0f4c969..cf945ef 100644 --- a/sshkp +++ b/sshkp/cli.py @@ -3,11 +3,15 @@ import argparse import getpass import os +import sys from pykeepass import PyKeePass -def main(): +def main(argv=None): + if argv is None: + argv = sys.argv + parser = argparse.ArgumentParser(description=''' Executes an SSH command with a password from a KeePass database. This script supports two environment variables: KP_FILENAME (mandatory) @@ -21,7 +25,7 @@ def main(): then it just prints the password without executing anything else''') - args = vars(parser.parse_args()) + args = vars(parser.parse_args(argv[1:])) ############################################################################ @@ -49,7 +53,7 @@ def main(): if len(command) >= 1 and command[0] == '.print': print(entry.password) - return + return 0 os.environ['SSHPASS'] = entry.password @@ -57,7 +61,3 @@ def main(): '/usr/bin/sshpass', ['sshpass', '-e', 'ssh', entryname] + command, ) - - -if __name__ == '__main__': - main()