From f7e5fde8ceb147d80e2e3afc9effbc56b510178e Mon Sep 17 00:00:00 2001 From: Danny Grove Date: Wed, 6 Nov 2019 13:24:34 -0800 Subject: [PATCH] Fix current_sha missing * Fix issue with current_sha not being saved * Fix creation of distribution * Fix pip install * Bump to python-gnupg==0.4.5, If no expiry sent, don't filter * Remove references to pyinstaller * Put .PHONY about each PHONY item * Swap TMPDIR for TMP_DIR b/c Mac OS Closes #28 --- .circleci/config.yml | 8 ++-- Makefile | 43 ++++++++--------- Pipfile | 2 +- Pipfile.lock | 108 ++++++++++++++++++++++--------------------- mtls/cli.py | 26 +++++++---- mtls/mtls.py | 36 +++++++++------ requirements.txt | 10 ++-- test/test_cli.py | 4 +- 8 files changed, 123 insertions(+), 114 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f28ee3a..eee8454 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,9 +16,9 @@ commands: - run: name: Pipenv Install command: | - pip install --user pip==18.0 - pip install --user pipenv - pipenv --three install --dev + python -m pip install --user pip==18.0 + python -m pip install --user pipenv + python -m pipenv --three install --dev environment: PIP_SHIMS_BASE_MODULE: pipenv.patched.notpip - save_cache: @@ -123,7 +123,7 @@ jobs: command: pipenv lock -r > requirements.txt - run: name: Create Distribution - command: make pkg-pypi + command: make pkg - store_artifacts: path: dist/ diff --git a/Makefile b/Makefile index c588e43..c08028c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -.PHONY: setup env clean lint build test SHELL := /bin/bash PIP_ENV:=$(shell pipenv --venv) ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) @@ -12,77 +11,71 @@ else UNAME := $(shell uname -s) endif +.PHONY: shell shell: @pipenv shell +.PHONY: setup setup: set-hooks - @pipenv --three install --dev - @pipenv run easy_install PyInstaller==3.4 + @pipenv sync --dev +.PHONY: pipenv-lock pipenv-lock: @pipenv update @pipenv lock -r > requirements.txt +.PHONY: set-hooks set-hooks: @echo "Setting commit hooks" @ ([ ! -L ".git/hooks/pre-commit" ] && \ ln -s $(PWD)/scripts/git-hooks/pre-commit.sh .git/hooks/pre-commit) \ || true -install: build - @mkdir -p $(DESTDIR) - @echo "Copying mtls/mtls to $(DESTDIR), Please ensure you have $(DESTDIR) in your PATH" - @cp mtls-$(UNAME)/mtls $(DESTDIR) - +.PHONY: format format: @pipenv run black -l 79 ./mtls/*.py @pipenv run black -l 79 ./test/*.py +.PHONY: lint lint: @pipenv run pycodestyle **/*.py +.PHONY: build-develop build-develop: @pipenv run python setup.py develop -build-pyinstaller-binary: - @pipenv run pyinstaller --onefile --distpath=mtls-$(UNAME) mtls.spec - +.PHONY: build-pypi build-pypi: @pipenv run python setup.py sdist bdist_wheel +.PHONY: build build: setup @pipenv run python setup.py build +.PHONY: run run: @pipenv run python3 bin/mtls $(ARGS) -run-build: - @./mtls-$(UNAME)/mtls $(ARGS) - +.PHONY: test test: setup -@$(PIP_ENV)/bin/coverage run -m unittest -v +.PHONY: test-by-name test-by-name: -@$(PIP_ENV)/bin/coverage run -m unittest $(TEST) -v +.PHONY: coverage coverage: @$(PIP_ENV)/bin/coverage report -m +.PHONY: coveralls coveralls: @$(PIP_ENV)/bin/coveralls - -pkg: build-pyinstaller-binary - @echo "Generating sha256sum of Binary" - @shasum -a256 mtls-$(UNAME)/mtls > mtls-$(UNAME)/mtls.sha256sum -ifeq ($(SIGN), 1) - @echo "Signing binary" - @gpg --sign --detach-sign --output mtls-$(UNAME)/mtls.sig mtls-$(UNAME)/mtls -endif - @tar -zcvf mtls-$(UNAME)-$(VERSION).tar.gz mtls-$(UNAME) - -pkg-pypi: build +.PHONY: pkg +pkg: build @pipenv run python setup.py sdist bdist_wheel +.PHONY: clean clean: @rm -r build dist $(PIP_ENV) mtls-$(UNAME) diff --git a/Pipfile b/Pipfile index 28bfddb..63d4357 100644 --- a/Pipfile +++ b/Pipfile @@ -15,6 +15,6 @@ click = "==7.0" cryptography = "==2.4.2" pyOpenSSL = "==19.0.0" pycodestyle = "==2.4.0" -python-gnupg = "==0.4.4" +python-gnupg = "==0.4.5" requests = "==2.21.0" urllib3 = "==1.24.3" diff --git a/Pipfile.lock b/Pipfile.lock index 69c46f6..2a8af0c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0ba45462934bad1207bec9734f0cf9e1e13ecb8cb5c56cea30f0d72f98e4c010" + "sha256": "98c5aabd1f7ad028556740cf6bbdef86789f466713dbfc2f3c6739e81c4fefd4" }, "pipfile-spec": 6, "requires": {}, @@ -16,50 +16,54 @@ "default": { "asn1crypto": { "hashes": [ - "sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87", - "sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49" + "sha256:7bb1cc02a5620b3d72da4ba070bda2f44f0e61b44dee910a302eddff802b6fb5", + "sha256:87620880a477123e01177a1f73d0f327210b43a3cdbd714efcd2fa49a8d7b384" ], - "version": "==0.24.0" + "version": "==1.2.0" }, "certifi": { "hashes": [ - "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", - "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" ], - "version": "==2019.6.16" + "version": "==2019.9.11" }, "cffi": { "hashes": [ - "sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774", - "sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d", - "sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90", - "sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b", - "sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63", - "sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45", - "sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25", - "sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3", - "sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b", - "sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647", - "sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016", - "sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4", - "sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb", - "sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753", - "sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7", - "sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9", - "sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f", - "sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8", - "sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f", - "sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc", - "sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42", - "sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3", - "sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909", - "sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45", - "sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d", - "sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512", - "sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff", - "sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201" - ], - "version": "==1.12.3" + "sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42", + "sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04", + "sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5", + "sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54", + "sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba", + "sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57", + "sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396", + "sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12", + "sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97", + "sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43", + "sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db", + "sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b", + "sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579", + "sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346", + "sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159", + "sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652", + "sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e", + "sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a", + "sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506", + "sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f", + "sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d", + "sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c", + "sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20", + "sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858", + "sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc", + "sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a", + "sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3", + "sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e", + "sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410", + "sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25", + "sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b", + "sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d" + ], + "version": "==1.13.2" }, "chardet": { "hashes": [ @@ -132,11 +136,11 @@ }, "python-gnupg": { "hashes": [ - "sha256:45daf020b370bda13a1429c859fcdff0b766c0576844211446f9266cae97fb0e", - "sha256:85c231850a0275c9722f06e34b45a22510b83a6a6e88f93b5ae32ba04c95056c" + "sha256:3353e59949cd2c15efbf1fca45e347d8a22f4bed0d93e9b89b2657bda19cec05", + "sha256:c095a41f310ad7a4fd393406660ac9bd6c175ccaa0f072f9c18f33be8130a27a" ], "index": "pypi", - "version": "==0.4.4" + "version": "==0.4.5" }, "requests": { "hashes": [ @@ -148,10 +152,10 @@ }, "six": { "hashes": [ - "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", - "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", + "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" ], - "version": "==1.12.0" + "version": "==1.13.0" }, "urllib3": { "hashes": [ @@ -172,10 +176,10 @@ }, "attrs": { "hashes": [ - "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", - "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", + "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" ], - "version": "==19.1.0" + "version": "==19.3.0" }, "black": { "hashes": [ @@ -187,10 +191,10 @@ }, "certifi": { "hashes": [ - "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", - "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" ], - "version": "==2019.6.16" + "version": "==2019.9.11" }, "chardet": { "hashes": [ @@ -298,10 +302,10 @@ }, "six": { "hashes": [ - "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", - "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", + "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" ], - "version": "==1.12.0" + "version": "==1.13.0" }, "toml": { "hashes": [ diff --git a/mtls/cli.py b/mtls/cli.py index a0191a0..6f0d269 100644 --- a/mtls/cli.py +++ b/mtls/cli.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -import datetime import os import sys from configparser import ConfigParser +from datetime import datetime import click @@ -245,7 +245,7 @@ def add_user(ctx, admin, fingerprint, email, keyserver): click.secho("A server was not provided.", fg="red") sys.exit(1) if fingerprint is None and email is None: - click.echo("A fingerprint must be provided") + click.echo("A fingerprint or email must be provided") sys.exit(1) if email is not None: fingerprint = handle_email(ctx, email, keyserver) @@ -288,12 +288,11 @@ def handle_email(ctx, email, keyserver=None): search_res = ctx.obj.gpg.search_keys(email, keyserver=keyserver) else: search_res = ctx.obj.gpg.search_keys(email) - now = str(int(datetime.datetime.now().timestamp())) + now = str(int(datetime.now().timestamp())) non_expired = [] for res in search_res: - if res["expires"] < now: - continue - non_expired.append(res) + if res["expires"] == "" or res["expires"] > now: + non_expired.append(res) if len(non_expired) == 0: click.secho("A fingerprint with the key could not be found.") sys.exit(1) @@ -301,13 +300,20 @@ def handle_email(ctx, email, keyserver=None): return non_expired[0]["keyid"] for idx, res in enumerate(non_expired): click.echo( - "{idx}) {fingerprint} {uid}".format( - idx=idx, fingerprint=res["keyid"], uid=res["uids"][0] + "{idx}) {fingerprint} {uid} - Created: {created}".format( + idx=idx, + fingerprint=res["keyid"], + uid=res["uids"][0], + created=datetime.utcfromtimestamp(int(res["date"])).strftime('%m/%d/%Y %H:%M:%S') ) ) num = len(non_expired) - value = int(input("Please select a key to add: ")) - if value > num: + try: + value = int(input("Please select a key to add: ")) + if value > num: + click.secho("Invalid number, exiting") + sys.exit(1) + except: click.secho("Invalid number, exiting") sys.exit(1) return non_expired[value]["keyid"] diff --git a/mtls/mtls.py b/mtls/mtls.py index f153999..a1862f8 100644 --- a/mtls/mtls.py +++ b/mtls/mtls.py @@ -112,6 +112,8 @@ def check_revoked(self, cert): return False def create_cert(self, output): + if output: + self.override = True self._create_db() cert = None if not self._has_root_cert(): @@ -292,21 +294,26 @@ def add_root_ca_to_store(self, ca_cert_file_path): def delete_cert_by_name(self, name): paths = self._get_certdb_paths() if sys.platform == "darwin": - fingerprint = self.config.get(self.server, "current_sha") - click.secho( - "Deleting invalid/expired certificates for {}".format( - fingerprint - ), - fg="yellow", + fingerprint = self.config.get( + self.server, + "current_sha", + fallback="" ) - delete_identity_cmd = [ - "security", - "delete-identity", - "-Z", - fingerprint, - ] - output = self._run_cmd(delete_identity_cmd, capture_output=True) - # Override path to just be firefox on darwin for the next command + if fingerprint != "": + click.secho( + "Deleting invalid/expired certificates for {}".format( + fingerprint + ), + fg="yellow", + ) + delete_identity_cmd = [ + "security", + "delete-identity", + "-Z", + fingerprint, + ] + output = self._run_cmd(delete_identity_cmd, capture_output=True) + # Override path to just be firefox on darwin for the next command paths = self._firefox_certdb_location() if sys.platform in ["linux", "linux2", "darwin"]: click.secho( @@ -908,7 +915,6 @@ def remove_user(self, fingerprint, is_admin=False): ) def set_user_options(self, options): - self.override = True for key in options: self.config.set(self.server, key, options.get(key)) diff --git a/requirements.txt b/requirements.txt index 04c81e7..ba59b5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ -i https://pypi.org/simple -asn1crypto==0.24.0 -certifi==2019.6.16 -cffi==1.12.3 +asn1crypto==1.2.0 +certifi==2019.9.11 +cffi==1.13.2 chardet==3.0.4 click==7.0 cryptography==2.4.2 @@ -9,7 +9,7 @@ idna==2.8 pycodestyle==2.4.0 pycparser==2.19 pyopenssl==19.0.0 -python-gnupg==0.4.4 +python-gnupg==0.4.5 requests==2.21.0 -six==1.12.0 +six==1.13.0 urllib3==1.24.3 diff --git a/test/test_cli.py b/test/test_cli.py index e232e83..eb3b6b8 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -132,7 +132,7 @@ def gen_csr(self, common_name=None): class TestCliBase(unittest.TestCase): @classmethod def setUpClass(cls): - TMPDIR_PREFIX = os.environ.get("TMPDIR") or "/tmp/" + TMPDIR_PREFIX = os.environ.get("TMP_DIR") or "/tmp/" TMPDIR_PREFIX = os.path.expanduser(TMPDIR_PREFIX) VERBOSE_GPG = os.environ.get("DEBUG_GNUPG") or False cls.seed_dir = tempfile.TemporaryDirectory(dir=TMPDIR_PREFIX) @@ -530,7 +530,7 @@ def test_add_admin_by_email(self): "add", "--admin", "--keyserver", - "keyserver.ubuntu.com", + "keys.openpgp.org", "--email", "danny@drgrovellc.com", ],