Merge branch 'release/1.2.4'
commit
7b2c5dc9db
23
Makefile
23
Makefile
|
@ -2,6 +2,11 @@ SHELL=/bin/sh
|
|||
TESTDIR=./gnupg/test
|
||||
TESTHANDLE=$(TESTDIR)/test_gnupg.py
|
||||
FILES=$(SHELL find ./gnupg/ -name "*.py" -printf "%p,")
|
||||
PKG_NAME=python-gnupg
|
||||
DOC_DIR=docs
|
||||
DOC_BUILD_DIR:=$(DOC_DIR)/_build
|
||||
DOC_HTML_DIR:=$(DOC_BUILD_DIR)/html
|
||||
DOC_BUILD_ZIP:=$(PKG_NAME)-docs.zip
|
||||
|
||||
.PHONY=all
|
||||
all: uninstall install test
|
||||
|
@ -73,11 +78,15 @@ py3k-uninstall: uninstall
|
|||
reinstall: uninstall install
|
||||
py3k-reinstall: py3k-uninstall py3k-install
|
||||
|
||||
cleandocs:
|
||||
sphinx-apidoc -F -A "Isis Agora Lovecruft" -H "python-gnupg" \
|
||||
-o docs gnupg/ tests/
|
||||
docs-clean:
|
||||
-rm -rf $(DOC_BUILD_DIR)
|
||||
|
||||
docs:
|
||||
cd docs && \
|
||||
make clean && \
|
||||
make html
|
||||
docs-completely-new:
|
||||
sphinx-apidoc -F -A "Isis Agora Lovecruft" -H "python-gnupg" -o $(DOC_DIR) gnupg/ tests/
|
||||
|
||||
docs-html:
|
||||
cd $(DOC_DIR) && make clean && make html
|
||||
|
||||
docs-zipfile: docs-html
|
||||
cd $(DOC_HTML_DIR) && { find . -name '*' | zip -@ -v ../$(DOC_BUILD_ZIP) ;};
|
||||
@echo "Built documentation in $(DOC_BUILD_DIR)/$(DOC_BUILD_ZIP)"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
import psutil
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
|
|
|
@ -75,7 +75,7 @@ class GPGMeta(type):
|
|||
same effective user ID as that of this program. Otherwise,
|
||||
returns None.
|
||||
"""
|
||||
identity = os.getresuid()
|
||||
identity = psutil.Process(os.getpid()).uids
|
||||
for proc in psutil.process_iter():
|
||||
if (proc.name == "gpg-agent") and proc.is_running:
|
||||
log.debug("Found gpg-agent process with pid %d" % proc.pid)
|
||||
|
@ -321,11 +321,11 @@ class GPGBase(object):
|
|||
created. Lastly, the ``direcory`` will be checked that the EUID has
|
||||
read and write permissions for it.
|
||||
|
||||
:param str homedir: A relative or absolute path to the directory to use
|
||||
for storing/accessing GnuPG's files, including
|
||||
:param str directory: A relative or absolute path to the directory to
|
||||
use for storing/accessing GnuPG's files, including
|
||||
keyrings and the trustdb.
|
||||
:raises: :exc:`RuntimeError` if unable to find a suitable directory to
|
||||
use.
|
||||
use.
|
||||
"""
|
||||
if not directory:
|
||||
log.debug("GPGBase._homedir_setter(): Using default homedir: '%s'"
|
||||
|
|
|
@ -298,7 +298,7 @@ def _sanitise(*args):
|
|||
values = value.split(' ')
|
||||
for v in values:
|
||||
## these can be handled separately, without _fix_unsafe(),
|
||||
## because they are only allowed if the pass the regex
|
||||
## because they are only allowed if they pass the regex
|
||||
if (flag in none_options) and (v is None):
|
||||
continue
|
||||
|
||||
|
@ -332,8 +332,11 @@ def _sanitise(*args):
|
|||
|
||||
if flag in ['--encrypt', '--encrypt-files', '--decrypt',
|
||||
'--decrypt-files', '--import', '--verify']:
|
||||
if _util._is_file(val): checked += (val + " ")
|
||||
else: log.debug("%s not file: %s" % (flag, val))
|
||||
if _util._is_file(val) or \
|
||||
(flag == '--verify' and val == '-'):
|
||||
checked += (val + " ")
|
||||
else:
|
||||
log.debug("%s not file: %s" % (flag, val))
|
||||
|
||||
elif flag in ['--cipher-algo', '--personal-cipher-prefs',
|
||||
'--personal-cipher-preferences']:
|
||||
|
@ -372,7 +375,8 @@ def _sanitise(*args):
|
|||
groups[last] = str(filo.pop())
|
||||
## accept the read-from-stdin arg:
|
||||
if len(filo) >= 1 and filo[len(filo)-1] == '-':
|
||||
groups[last] += str(' - \'\'') ## gross hack
|
||||
groups[last] += str(' - ') ## gross hack
|
||||
filo.pop()
|
||||
else:
|
||||
groups[last] = str()
|
||||
while len(filo) > 1 and not is_flag(filo[len(filo)-1]):
|
||||
|
|
|
@ -31,6 +31,7 @@ from time import mktime
|
|||
import codecs
|
||||
import encodings
|
||||
import os
|
||||
import psutil
|
||||
import threading
|
||||
import random
|
||||
import re
|
||||
|
@ -270,6 +271,8 @@ def _find_binary(binary=None):
|
|||
except IndexError as ie:
|
||||
log.info("Could not determine absolute path of binary: '%s'"
|
||||
% binary)
|
||||
elif os.access(binary, os.X_OK):
|
||||
found = binary
|
||||
if found is None:
|
||||
try: found = _which('gpg')[0]
|
||||
except IndexError as ie:
|
||||
|
@ -393,7 +396,7 @@ def _make_passphrase(length=None, save=False, file=None):
|
|||
passphrase = _make_random_string(length)
|
||||
|
||||
if save:
|
||||
ruid, euid, suid = os.getresuid()
|
||||
ruid, euid, suid = psutil.Process(os.getpid()).uids
|
||||
gid = os.getgid()
|
||||
now = mktime(localtime())
|
||||
|
||||
|
@ -529,39 +532,40 @@ def _write_passphrase(stream, passphrase, encoding):
|
|||
|
||||
|
||||
class InheritableProperty(object):
|
||||
"""Based on the emulation of PyProperty_Type() in Objects/descrobject.c"""
|
||||
"""Based on the emulation of PyProperty_Type() in Objects/descrobject.c"""
|
||||
|
||||
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
|
||||
self.fget = fget
|
||||
self.fset = fset
|
||||
self.fdel = fdel
|
||||
self.__doc__ = doc
|
||||
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
|
||||
self.fget = fget
|
||||
self.fset = fset
|
||||
self.fdel = fdel
|
||||
self.__doc__ = doc
|
||||
|
||||
def __get__(self, obj, objtype=None):
|
||||
if obj is None:
|
||||
return self
|
||||
if self.fget is None:
|
||||
raise AttributeError("unreadable attribute")
|
||||
if self.fget.__name__ == '<lambda>' or not self.fget.__name__:
|
||||
return self.fget(obj)
|
||||
else:
|
||||
return getattr(obj, self.fget.__name__)()
|
||||
def __get__(self, obj, objtype=None):
|
||||
if obj is None:
|
||||
return self
|
||||
if self.fget is None:
|
||||
raise AttributeError("unreadable attribute")
|
||||
if self.fget.__name__ == '<lambda>' or not self.fget.__name__:
|
||||
return self.fget(obj)
|
||||
else:
|
||||
return getattr(obj, self.fget.__name__)()
|
||||
|
||||
def __set__(self, obj, value):
|
||||
if self.fset is None:
|
||||
raise AttributeError("can't set attribute")
|
||||
if self.fset.__name__ == '<lambda>' or not self.fset.__name__:
|
||||
self.fset(obj, value)
|
||||
else:
|
||||
getattr(obj, self.fset.__name__)(value)
|
||||
def __set__(self, obj, value):
|
||||
if self.fset is None:
|
||||
raise AttributeError("can't set attribute")
|
||||
if self.fset.__name__ == '<lambda>' or not self.fset.__name__:
|
||||
self.fset(obj, value)
|
||||
else:
|
||||
getattr(obj, self.fset.__name__)(value)
|
||||
|
||||
def __delete__(self, obj):
|
||||
if self.fdel is None:
|
||||
raise AttributeError("can't delete attribute")
|
||||
if self.fdel.__name__ == '<lambda>' or not self.fdel.__name__:
|
||||
self.fdel(obj)
|
||||
else:
|
||||
getattr(obj, self.fdel.__name__)()
|
||||
|
||||
def __delete__(self, obj):
|
||||
if self.fdel is None:
|
||||
raise AttributeError("can't delete attribute")
|
||||
if self.fdel.__name__ == '<lambda>' or not self.fdel.__name__:
|
||||
self.fdel(obj)
|
||||
else:
|
||||
getattr(obj, self.fdel.__name__)()
|
||||
|
||||
class Storage(dict):
|
||||
"""A dictionary where keys are stored as class attributes.
|
||||
|
|
|
@ -308,7 +308,7 @@ class GPG(GPGBase):
|
|||
sig_fh = None
|
||||
try:
|
||||
sig_fh = open(sig_file)
|
||||
args = ["--verify %s - " % sig_fh.name]
|
||||
args = ["--verify %s -" % sig_fh.name]
|
||||
proc = self._open_subprocess(args)
|
||||
writer = _util._threaded_copy_data(file, proc.stdin)
|
||||
self._collect_output(proc, result, stdin=proc.stdin)
|
||||
|
@ -557,18 +557,20 @@ class GPG(GPGBase):
|
|||
|
||||
fpr = str(key.fingerprint)
|
||||
if len(fpr) == 20:
|
||||
if self.temp_keyring or self.temp_secring:
|
||||
if not os.path.exists(self._keys_dir):
|
||||
os.makedirs(self._keys_dir)
|
||||
prefix = os.path.join(self._keys_dir, fpr)
|
||||
for d in map(lambda x: os.path.dirname(x),
|
||||
[self.temp_keyring, self.temp_secring]):
|
||||
if not os.path.exists(d):
|
||||
os.makedirs(d)
|
||||
|
||||
if self.temp_keyring:
|
||||
if os.path.isfile(self.temp_keyring):
|
||||
prefix = os.path.join(self.temp_keyring, fpr)
|
||||
try: os.rename(self.temp_keyring, prefix+".pubring")
|
||||
except OSError as ose: log.error(ose.message)
|
||||
|
||||
if self.temp_secring:
|
||||
if os.path.isfile(self.temp_secring):
|
||||
prefix = os.path.join(self.temp_secring, fpr)
|
||||
try: os.rename(self.temp_secring, prefix+".secring")
|
||||
except OSError as ose: log.error(ose.message)
|
||||
|
||||
|
|
|
@ -173,7 +173,6 @@ class GPGTestCase(unittest.TestCase):
|
|||
self.keyring = self.gpg.keyring
|
||||
self.secring = self.gpg.secring
|
||||
self.insecure_prng = False
|
||||
self.gpg._keys_dir = os.path.join(_files, 'generated-keys')
|
||||
|
||||
def tearDown(self):
|
||||
"""This is called once per self.test_* method after the test run."""
|
||||
|
@ -523,7 +522,7 @@ class GPGTestCase(unittest.TestCase):
|
|||
self.assertIsNotNone(key)
|
||||
self.assertNotEquals(key, "")
|
||||
self.assertGreater(len(str(key)), 0)
|
||||
keyfile = os.path.join(self.gpg._keys_dir, 'test_key_3.pub')
|
||||
keyfile = os.path.join(_files, 'test_key_3.pub')
|
||||
log.debug("Storing downloaded key as %s" % keyfile)
|
||||
with open(keyfile, 'w') as fh:
|
||||
fh.write(str(key))
|
||||
|
|
|
@ -1,58 +1,3 @@
|
|||
#
|
||||
# python-gnupg/requirements.txt
|
||||
# -----------------------------
|
||||
# Pip requirements.txt file. This file is also parsed for distribute to use in
|
||||
# setup.py.
|
||||
#_____________________________________________________________________________
|
||||
# This file is part of python-gnupg, a Python interface to GnuPG.
|
||||
# Copyright © 2013 Isis Lovecruft, <isis@leap.se> 0xA3ADB67A2CDB8B35
|
||||
# © 2013 Andrej B.
|
||||
# © 2013 LEAP Encryption Access Project
|
||||
# © 2008-2012 Vinay Sajip
|
||||
# © 2005 Steve Traugott
|
||||
# © 2004 A.M. Kuchling
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the included LICENSE file for details.
|
||||
#______________________________________________________________________________
|
||||
#
|
||||
# Force pip upgrade due to security vulnerabilities.
|
||||
#
|
||||
# This has actually has little to do with installing python-gnupg, since
|
||||
# older versions of pip would install everything just fine. except that, in
|
||||
# my opinion, using GnuPG for privacy is silly when the installation of
|
||||
# python-gnupg with an older version of pip is trivially exploitable through
|
||||
# a MITM attack. see https://github.com/pypa/pip/pull/791
|
||||
#
|
||||
# Also, note that SSL package delivery is *not* entirely fixed yet. See
|
||||
# https://github.com/TheTorProject/ooni-backend/pull/1#discussion_r4084881
|
||||
#
|
||||
#pip>=1.3.1
|
||||
#
|
||||
# NOTE: setuptools is currently (as of 27 May 2013) being merged back into its
|
||||
# parent project, distribute. By using the included distribute_setup.py
|
||||
# script, we make sure that we have a recent version of setuptools/distribute,
|
||||
# which is the *only* Python packaging framework compatible at this point with
|
||||
# both Python>=2.4 and Python3.x.
|
||||
#
|
||||
# A new version of distribute is necessary due to the merging of setuptools
|
||||
# back into its parent project, distribute. Also, the only way to package for
|
||||
# both Python 2 and 3 is to use distribute.
|
||||
#
|
||||
#distribute>=0.6.45
|
||||
#
|
||||
# Sphinx is only necessary for building documentation, so it is added in
|
||||
# setup.py under extras_require['docs'].
|
||||
#
|
||||
# If you want to build the documentation, uncomment this line:
|
||||
#Sphinx>=1.1
|
||||
#
|
||||
# And, this one is actually used in the gnupg module code:
|
||||
#
|
||||
psutil>=0.5.1
|
||||
# sha256: UI5KRMglOjhqD4bZyb1KG0y7L5TojUmhnBUTZTymbEU
|
||||
psutil==1.2.1
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
[upload_docs]
|
||||
upload-dir = docs/_build/html
|
||||
show-response = true
|
||||
verbose = true
|
||||
|
||||
[upload]
|
||||
sign = True
|
||||
|
|
44
setup.py
44
setup.py
|
@ -23,7 +23,10 @@ from __future__ import absolute_import
|
|||
from __future__ import print_function
|
||||
|
||||
import setuptools
|
||||
import os
|
||||
import versioneer
|
||||
|
||||
|
||||
versioneer.versionfile_source = 'gnupg/_version.py'
|
||||
versioneer.versionfile_build = 'gnupg/_version.py'
|
||||
versioneer.tag_prefix = ''
|
||||
|
@ -34,6 +37,44 @@ __contact__ = 'isis@patternsinthevoid.net'
|
|||
__url__ = 'https://github.com/isislovecruft/python-gnupg'
|
||||
|
||||
|
||||
def get_requirements():
|
||||
"""Extract the list of requirements from our requirements.txt.
|
||||
|
||||
:rtype: 2-tuple
|
||||
:returns: Two lists, the first is a list of requirements in the form of
|
||||
pkgname==version. The second is a list of URIs or VCS checkout strings
|
||||
which specify the dependency links for obtaining a copy of the
|
||||
requirement.
|
||||
"""
|
||||
requirements_file = os.path.join(os.getcwd(), 'requirements.txt')
|
||||
requirements = []
|
||||
links=[]
|
||||
try:
|
||||
with open(requirements_file) as reqfile:
|
||||
for line in reqfile.readlines():
|
||||
line = line.strip()
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
elif line.startswith(
|
||||
('https://', 'git://', 'hg://', 'svn://')):
|
||||
links.append(line)
|
||||
else:
|
||||
requirements.append(line)
|
||||
|
||||
except (IOError, OSError) as error:
|
||||
print(error)
|
||||
|
||||
return requirements, links
|
||||
|
||||
|
||||
requires, deplinks = get_requirements()
|
||||
print('Found requirements:')
|
||||
[print('\t%s' % name) for name in requires]
|
||||
|
||||
print('Found dependency links:')
|
||||
[print('\t%s' % uri) for uri in deplinks]
|
||||
|
||||
|
||||
setuptools.setup(
|
||||
name = "gnupg",
|
||||
description="A Python wrapper for GnuPG",
|
||||
|
@ -62,7 +103,8 @@ greater.
|
|||
scripts=['versioneer.py'],
|
||||
test_suite='gnupg.test.test_gnupg',
|
||||
|
||||
install_requires=['psutil>=0.5.1'],
|
||||
install_requires=requires,
|
||||
dependency_links=deplinks,
|
||||
extras_require={'docs': ["Sphinx>=1.1", "repoze.sphinx"]},
|
||||
|
||||
platforms="Linux, BSD, OSX, Windows",
|
||||
|
|
Loading…
Reference in New Issue