Unverified Commit b9dcacab authored by anarcat's avatar anarcat

Merge branch '2.x' into dev/python3

parents 28d8ca38 e0cf4269
Pipeline #29499 canceled with stage
*.pyc
.be/id-cache
bts.mbox
build
.cache
.coverage
dist
doc/doctrees/
doc/html/
*.egg-info/
.eggs/
man
monkeysign/_version.py
presentation.html
.pybuild
*.pyc
/.python-version
.tox/
ui
bts.mbox
.be/id-cache
monkeysign/_version.py
_version.py
> Please provide a summary of the bug you encountered here.
## Expected behavior
> What you expected to happen
## Actual behavior
> What happened instead
## Steps to reproduce
> Try to reproduce the issue. Please describe every step you took to
> reproduce the issue. Make sure to run Monkeysign with `--debug` when
> you reproduce and paste the output below.
1. step 1: collect underpants
2. step 2: ???
3. step 3: profit!
## Suggested fixes
> If you have ideas about how to fix this, feel free to provide it
> here or remove this section.
## Testsuite output
> Please paste the output of `monkeysign --test` here:
```
$ monkeysign --test
```
## Environment details
> Run `monkeysign --version`.If you are running 2.1.0, just paste the
> output here. If the monkeysign version is `??`, maybe you need to
> install `python-setuptools-scm`.
>
> Otherwise, paste the version number, but also:
>
> * ``lsb_release -b``: operating system name, version and codename
> (e.g. ``Debian GNU/Linux 8.4 (jessie)``)
> * ``uname -a``: kernel version, architecture and build dates (e.g. ``Linux
> marcos 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-1 (2016-03-06)
> x86_64 GNU/Linux``)
> * ``python --version``
> * ``gpg --version``
>
> If you are using the graphical interface, try to also include the
> versions of the following libraries:
>
> * GTK
> * PyGTK
> * ZBar
> * QRencode
> * PIL
>
> Also explain how was Monkeysign installed (Debian package, PIP, from git, etc).
## Debugging output
> When you reproduced the issue, you used the `--debug` flag, paste
> the output here:
```
$ monkeysign --debug ...
```
> Watch out, personnal information like key fingerprints or key
> material may show up in the output. Review the output before
> copying it here.
This diff is collapsed.
monkeysign (2.2.3) unstable; urgency=medium
[ Simon Fondrie-Teitler ]
* Don't escape percent signs that are actually required in default mua command
[ Antoine Beaupré ]
* some small improvements to the bug issue template
* create 2.2.x branch officially
* silence errors in test suite with GnuPG 2
-- Antoine Beaupré <anarcat@debian.org> Tue, 24 Jan 2017 15:40:35 -0500
monkeysign (2.2.2) unstable; urgency=medium
[ Antoine Beaupré ]
* explicitly depend on socks, seems like pybuild doesn't puck up the
depends (Closes: #847716)
* forgot some future tests failures (Closes: #841115)
* properly redirect version information
* mention --test in bug report guidelines
* clarify support schedule, fix typos
* abandon 2.1.x, tell people how to support more
* indicate that you need to request access to create merge requests
* document the new test skipping features
* give proper credits to documenters
* add credits section
* fix trove classifier
* output the parsed qrcode data when verbose
* do not load default config files in tests
* adopt covenant code of conduct
* patches merging guidelines
* refer to modernPGP manuals
* move code of conducts contacts to a special section
[ Simon Fondrie-Teitler ]
* Add right click menu with print/save to qr code
* Don't attempt to sign a user's own key
* Make message more friendly
* add test for signing one's own key
* lowercase k in OpenPGPkey __repr__
* Add Simon to authors file
[ Tobias Mueller ]
* gpg: Use os.path.expanduser instead of the environment variable
-- Antoine Beaupré <anarcat@debian.org> Thu, 15 Dec 2016 11:04:13 -0500
monkeysign (2.2.1) unstable; urgency=medium
* fix socks dependency specification: it is a runtime, not just
build-time, dependency
* mark as production-ready in python classification
* skip another test that requires network during build
* run CI tests with --debug to ease future debugging
-- Antoine Beaupré <anarcat@debian.org> Sat, 15 Oct 2016 09:18:21 -0400
monkeysign (2.2.0) unstable; urgency=medium
* fix tests with Debian CI
......
......@@ -30,6 +30,7 @@ Architecture: all
Depends: ${misc:Depends}
, ${python:Depends}
, python-pkg-resources
, python-socks
, gnupg
, gnupg-agent
, dirmngr
......@@ -40,20 +41,20 @@ Recommends: python-qrencode
, python-mock
Suggests: monkeysign-doc
Description: OpenPGP key signing and exchange for humans
monkeysign is a tool to overhaul the OpenPGP keysigning experience
monkeysign is a project to overhaul the OpenPGP keysigning experience
and bring it closer to something that most primates can understand.
.
The project makes use of cheap digital cameras and the type of bar
code known as a QRcode to provide a human-friendly yet still-secure
keysigning experience.
To achieve this goal, it makes use of cheap digital cameras and the
type of bar code known as a QRcode to provide a human-friendly yet
still-secure keysigning experience.
.
No more reciting tedious strings of hexadecimal characters. And, you
can build a little rogue's gallery of the people that you have met
and exchanged keys with!
.
Monkeysign is the commandline signing software, a caff
replacement. Monkeyscan is the graphical user interface that scans
qrcodes.
Monkeysign is also the name of it's commandline signing software, a
caff replacement. Monkeyscan is the graphical user interface that
scans qrcodes.
Package: monkeysign-doc
Architecture: all
......@@ -64,19 +65,19 @@ Replaces: monkeysign (<< 2.1.0)
Breaks: monkeysign (<< 2.1.0)
Section: doc
Description: OpenPGP key signing and exchange for humans (documentation)
monkeysign is a tool to overhaul the OpenPGP keysigning experience
monkeysign is a project to overhaul the OpenPGP keysigning experience
and bring it closer to something that most primates can understand.
.
The project makes use of cheap digital cameras and the type of bar
code known as a QRcode to provide a human-friendly yet still-secure
keysigning experience.
To achieve this goal, it makes use of cheap digital cameras and the
type of bar code known as a QRcode to provide a human-friendly yet
still-secure keysigning experience.
.
No more reciting tedious strings of hexadecimal characters. And, you
can build a little rogue's gallery of the people that you have met
and exchanged keys with!
.
Monkeysign is the commandline signing software, a caff
replacement. Monkeyscan is the graphical user interface that scans
qrcodes.
Monkeysign is also the name of it's commandline signing software, a
caff replacement. Monkeyscan is the graphical user interface that
scans qrcodes.
.
This package ships with the builtin documentation.
......@@ -4,14 +4,18 @@ printf "\ndetailed monkeysign version information\n" >&3
# first try with monkeyscan, as it has everything monkeysign shows, but
# with extra GUI information
# if it fails, it will show why and then monkeysign will run normally
monkeyscan --version --debug >&3 || monkeysign --version --debug >&3
monkeyscan --version --debug 2>&3 || monkeysign --version --debug 2>&3
cat >&3 <<EOF
please also include a backtrace and full --debug information
please also include a backtrace and full --debug information in case
of a crash or any failure.
WARNING: make sure you review the information included in the output for
confidential information. secret key material should never show up in
Monkeysign output, but public key material, including user identies like
pictures and email addresses may be shown.
also include the output of monkeysign --test if you run Monkeysign
older than 2.1.
EOF
Test-command: monkeysign --test
Test-command: monkeysign --debug --test
Depends: @, python-mock
Restrictions: allow-stderr
......@@ -33,19 +33,32 @@ templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# markdown support: http://blog.readthedocs.com/adding-markdown-support/
import sphinx
if sphinx.version_info > (1,3,):
source_suffix = ['.rst', '.md']
else:
print "WARNING: can't set source_suffix as you are running an older Sphinx version (< 1.3)"
try:
from recommonmark.parser import CommonMarkParser
source_parsers = {'.md': CommonMarkParser}
except ImportError:
print "WARNING: no markdown support found, bits of documentation will be missing"
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Monkeysign'
copyright = u'2014, Antoine Beaupré'
# look for monkeysign in the parent directory
sys.path.insert(0, os.path.dirname(__file__) + '/..')
from monkeysign import __version__ as version
from monkeysign import __documenters__
# General information about the project.
project = u'Monkeysign'
copyright = u'2014-2016, %s and %s' % (u",".join(__documenters__[2:-1]), __documenters__[-1])
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
......
=========
Credits
=========
Those people are the ones who made Monkeysign possible.
.. literalinclude:: ../monkeysign/__init__.py
:start-after: credits-start
......@@ -31,3 +31,7 @@ In this documentation, the following definitions are used:
A computer program used to read, compose and send email,
normally ran on user computers. See :wikipedia:`Mail User
Agent` for more information.
We also try to adhere to the `Modern PGP <http://modernpgp.org/>`_
`terminology <https://github.com/ModernPGP/terminology>`_ when
possible.
......@@ -10,13 +10,14 @@
install
usage
support
contributing
history
api
ui-mockups/index
glossary
credits
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
Installing
==========
Install
=======
Monkeysign can be installed in various ways, depending on which
platform you are using. You can install Monkeysign:
......
../.gitlab/issue_templates/bug.md
\ No newline at end of file
.. to be built separately, so silence warnings about it missing from
toctrees:
:orphan:
Monkeysign: OpenPGP key exchange for humans
===========================================
......
=========
Support
=========
If you have problems or question using Monkeysign, there are several
options at your disposal:
* Try to troubleshoot the issue yourself
* Write to the mailing list
* Chat on IRC
* File bug reports
We of course welcome other contributions like documentation,
translations and patches, see the :doc:`contributing` guide for more
information on how to contribute to the project.
Troubleshooting
---------------
The basic way to troubleshoot Monkeysign is to run the same command as
you did when you had an error with the ``--verbose`` or, if that
doesn't yield satisfactory results, with the ``--debug`` output.
.. note:: The debug output outputs a lot of information, as it shows
the OpenPGP key material as it is exchanged with GnuPG. It
may be confusing for new users.
If you suspect there is a bug in Monkeysign specific to your
environment, you can also try to see if it is reproducible within the
test suite with ``monkeysign --test``. From there, you can either file
a bug report or try to fix the issue yourself, see the
:doc:`contributing` section for more information.
Otherwise, see below for more options to get support.
Mailing list
------------
Anyone can write to the mailing list at
monkeysphere@lists.riseup.net. You can `browse the archives
<https://lists.riseup.net/www/arc/monkeysphere>`_ before posting to
see if your question has already been answered. Thanks to `Riseup.net
<https://riseup.net/>`_ for graciously hosting our mailing list.
.. tip:: We encourage you to `donate to Riseup
<https://riseup.net/en/donate>`_ to support the Monkeysign
project, as we use several parts of their infrastructure to
develop Monkeysign.
Note that the mailing list is for the larger `Monkeysphere project
<http://web.monkeysphere.info/>`_ so if you subscribe, you should
expect discussions to go beyond only Monkeysign. Furthermore, when you
write to the mailing list, you should explicitly mention that you are
talking about Monkeysign.
Chat
----
We are often present in realtime in the ``#monkeysphere`` channel of
the `OFTC network <https://www.oftc.net/>`_. You can join the channel
using `this link <ircs://irc.oftc.net/monkeysphere>`_ or `this web
interface
<http://webchat.oftc.net/?nick=monkey.&channels=monkeysphere&prompt=1>`_.
.. raw:: html
<iframe src="http://webchat.oftc.net/?nick=monkey.&channels=monkeysphere&prompt=1" width="647" height="400"></iframe>
Bug reports
-----------
We want you to report bugs you find in Monkeysign. It's an important
part of contributing to a project, and all bug reports will be read and
replied to politely and professionally.
We are using `0xACAB.org's Gitlab instance
<https://0xacab.org/monkeysphere/monkeysign/issues>`__ to manage
issues, and this is where bug reports should be sent. Some issues are
also documented by Debian users directly.
.. tip:: A few tips on how to make good bug reports:
* Before you report a new bug, review the existing issues in
the `online issue tracker`_ and the `Debian BTS for
Monkeysign`_ to make sure the bug has not already been
reported elsewhere.
* The first aim of a bug report is to tell the developers
exactly how to reproduce the failure, so try to reproduce
the issue yourself and describe how you did that.
* If that is not possible, just try to describe what went wrong in
detail. Write down the error messages, especially if they
have numbers.
* Take the necessary time to write clearly and precisely. Say
what you mean, and make sure it cannot be misinterpreted.
* Include the output of ``monkeysign --test``, ``monkeysign
--version`` and ``monkeysign --debug`` in your bug
reports. See the :doc:`issue template <issue_template>` for
more details about what to include in bug reports.
If you wish to read more about issues regarding communication
in bug reports, you can read `How to Report Bugs
Effectively`_ which takes about 30 minutes.
.. _online issue tracker: https://0xacab.org/monkeysphere/monkeysign/issues
.. _How to Report Bugs Effectively: http://www.chiark.greenend.org.uk/~sgtatham/bugs.html
.. warning:: The output of the ``--debug`` shows public key material
used by Monkeysign. Special efforts have been made so
that private key material is never displayed (or in fact
accessed directly or copied) but you may want to avoid
publicly disclosing which keys you are signing because
that can reveal your social graph. If you are confident
the signed user will publish the results on the public
keyservers, this is not much of a concern. But otherwise,
you should leave that decision to that user. This is
particularly relevant if you do *not* want to publicly
certify this (e.g. if you are using the ``--local``
flag). Do review the output before sending it in bug
reports.
Debian BTS
~~~~~~~~~~
You can also report bugs by email over the `Debian
BTS <http://bugs.debian.org/>`__, even if you are not using Debian. Use
the ``reportbug`` package to report a bug if you run Debian (or Ubuntu),
otherwise send an email to ``submit@bugs.debian.org``, with content like
this:
::
To: submit@bugs.debian.org
From: you@example.com
Subject: fails to frobnicate
Package: monkeysign
Version: 1.0
Monkeysign fails to frobnicate.
I tried to do...
I was expecting...
And instead I had this backtrace...
I am running Arch Linux 2013.07.01, Python 2.7.5-1 under a amd64
architecture.
See also the `complete
instructions <http://www.debian.org/Bugs/Reporting>`__ for more
information on how to use the Debian bugtracker. You can also browse the
existing bug reports in the `Debian BTS for
Monkeysign <http://bugs.debian.org/monkeysign>`_ there.
Using
Usage
=====
Monkeysign comes in two different interfaces: a commandline interface
......@@ -141,6 +141,10 @@ examples of known working configurations.
monkeysign --mua "thunderbird -compose to=%(to)s,subject=%(subject)s,body=%(body)s,attachment=%(attach)s" [...]
.. note:: Thunerbird fails to respect the attachment parameter in
versions before 52.1.1, see :bts:`837771` for more
details.
* Mutt::
monkeysign --mua "mutt -a %(attach)s -s %(subject)s -i %(body)s %(to)s" [...]
......
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals
__description__ = 'OpenPGP key exchange for humans'
__long_description__ = """
monkeysign is a tool to overhaul the OpenPGP keysigning experience and
......@@ -46,6 +48,12 @@ __license__ = """
__website__ = 'http://web.monkeysphere.info/monkeysign'
__documentation__ = 'http://monkeysign.readthedocs.io/en/' + __version__
# hack to include the credits in the documentation
# maybe this should be parsed from a AUTHORS file instead, see
# https://0xacab.org/monkeysphere/monkeysign/issues/56
# if you feel comptent to respond to Code of Conduct reports,
# make sure you add your email address below
# credits-start
__authors__ = ['In alphabetical order:',
'',
'Antoine Beaupré',
......@@ -55,6 +63,7 @@ __authors__ = ['In alphabetical order:',
'Kristian Fiskerstrand',
'Philip Jägenstedt',
'Ramakrishnan Muthukrishnan',
'Simon Fondrie-Teitler',
'Tobias Mueller',
]
__documenters__ = ['In alphabetical order:',
......
......@@ -22,6 +22,7 @@ import locale
import sys
import os
import getpass
import logging
if sys.version_info < (3,):
input = raw_input
......@@ -29,6 +30,8 @@ if sys.version_info < (3,):
from monkeysign.ui import MonkeysignUi
import monkeysign.translation
logger = logging.getLogger(__name__)
class MonkeysignCli(MonkeysignUi):
"""sign a key in a safe fashion.
......@@ -53,11 +56,11 @@ passwords."""
os.environ['GPG_TTY'] = os.ttyname(sys.stdin.fileno())
except OSError as e:
if e.errno == errno.ENOTTY:
self.warn(_('cannot find your TTY, GPG may freak out if you do not set the GPG_TTY environment'))
logger.warning(_('cannot find your TTY, GPG may freak out if you do not set the GPG_TTY environment'))
else:
raise
else:
self.log(_('reset GPG_TTY to %s') % os.environ['GPG_TTY'])
logger.info(_('reset GPG_TTY to %s'), os.environ['GPG_TTY'])
# 1. fetch the key into a temporary keyring
self.find_key()
......@@ -65,7 +68,7 @@ passwords."""
# 2. copy the signing key secrets into the keyring
self.copy_secrets()
self.warn(_('Preparing to sign with this key\n\n%s') % self.signing_key)
logger.warning(_('Preparing to sign with this key\n\n%s'), self.signing_key)
# 3. for every user id (or all, if -a is specified)
# 3.1. sign the uid, using gpg-agent
......@@ -108,8 +111,8 @@ passwords."""
# workaround http://bugs.python.org/issue7768
pattern = input(prompt.encode(sys.stdout.encoding or locale.getpreferredencoding(True)))
while not (pattern in allowed_uids or (pattern.isdigit() and int(pattern)-1 in list(range(0,len(allowed_uids))))):
print(_('invalid uid'))
while not (pattern in allowed_uids or (pattern.isdigit() and int(pattern)-1 in range(0,len(allowed_uids)))):
logger.warning(_('invalid uid'))
pattern = input(prompt.encode(sys.stdout.encoding or locale.getpreferredencoding(True)))
if pattern.isdigit():
pattern = allowed_uids[int(pattern)-1]
......
......@@ -72,11 +72,14 @@ from __future__ import print_function
import errno
import os, tempfile, shutil, subprocess, re
from datetime import datetime
import logging
import io
import monkeysign.translation
logger = logging.getLogger(__name__)
class Context():
"""Python wrapper for GnuPG
......@@ -104,13 +107,10 @@ class Context():
'with-colons': None,
'with-fingerprint': None,
'fixed-list-mode': None,
'no-verbose': None,
'list-options': 'show-sig-subpackets,show-uid-validity,show-unusable-uids,show-unusable-subkeys,show-keyring,show-sig-expire',
}
# whether to paste output here and there
# if not false, needs to be a file descriptor
debug = False
def __init__(self):
self.options = dict(Context.options) # copy
......@@ -128,7 +128,7 @@ class Context():
if option in self.options:
del self.options[option]
else:
return false
return False
def build_command(self, command):
"""internal helper to build a proper gpg commandline
......@@ -179,6 +179,7 @@ class Context():
we can optionnally watch for a confirmation pattern on the
statusfd.
"""
logger.debug('command: %s', self.build_command(command))
proc = subprocess.Popen(self.build_command(command), # nosec
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
......@@ -187,9 +188,7 @@ class Context():
self.stdout = self.stdout.decode('utf-8')
self.stderr = self.stderr.decode('utf-8')
self.returncode = proc.returncode
if self.debug:
print('command:', self.build_command(command), file=self.debug)
print('ret:', self.returncode, 'stdout:', self.stdout, 'stderr:', self.stderr, file=self.debug)
logger.debug('ret: %s stdout: %s stderr: %s', self.returncode, self.stdout, self.stderr)
return proc.returncode == 0
def seek_pattern(self, fd, pattern):
......@@ -208,11 +207,11 @@ class Context():
line = fd.readline().decode('utf-8')
match = re.search(pattern, line)
while line and not match:
if self.debug: print("skipped:", line, end=' ', file=self.debug)
line = fd.readline().decode('utf-8')
logger.debug("skipped: %s", line)
line = fd.readline()
match = re.search(pattern, line)
if match:
if self.debug: print("FOUND:", line, end=' ', file=self.debug)
logger.debug("FOUND: %s", line)
return match
else:
raise GpgProtocolError(self.returncode, _("could not find pattern '%s' in input, last skipped '%s'") % (pattern, line))
......@@ -241,14 +240,16 @@ class Context():
ignored = ('[GNUPG:] KEYEXPIRED', '[GNUPG:] SIGEXPIRED', '[GNUPG:] KEY_CONSIDERED', 'gpg: ')
while line and line.startswith(ignored):
if self.debug: print("IGNORED:", line, end=' ', file=self.debug)
line = fd.readline().decode('utf-8')
logger.debug("IGNORED: %s", line)
line = fd.readline()
match = re.search(pattern, line)
if self.debug:
if match: print("FOUND:", line, end=' ', file=self.debug)
else: print("SKIPPED:", line, end=' ', file=self.debug)
if match:
logger.debug("FOUND: %s", line)
else:
logger.debug("SKIPPED: %s",line)
if not match:
raise GpgProtocolError(self.returncode, 'expected "%s", found "%s"' % (pattern, line))
return match
......@@ -311,7 +312,7 @@ class Keyring():
if homedir is not None:
self.context.set_option('homedir', homedir)
else:
homedir = os.environ['HOME'] + '/.gnupg'
homedir = os.path.join(os.path.expanduser("~"), '.gnupg')
if 'GNUPGHOME' in os.environ:
homedir = os.environ['GNUPGHOME']
self.homedir = homedir
......@@ -473,8 +474,7 @@ class Keyring():
def del_uid(self, fingerprint, pattern):
command = self.context.build_command(['edit-key', fingerprint])
if self.context.debug:
print('command:', command, file=self.context.debug)
logger.debug('command: %s', command)
proc = subprocess.Popen(command, # nosec
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
......@@ -520,8 +520,7 @@ class Keyring():
# output of --sign-key
command = self.context.build_command([['sign-key',
'lsign-key'][local], pattern])
if self.context.debug:
print('command:', command, file=self.context.debug)
logger.debug('command: %s', command)
proc = subprocess.Popen(command, # nosec
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
......@@ -624,7 +623,7 @@ class TempKeyring(Keyring):
Keyring.__init__(self, tempfile.mkdtemp(prefix="pygpg-"))
def __del__(self):
shutil.rmtree(self.homedir)
shutil.rmtree(self.homedir, ignore_errors=True)
class OpenPGPkey():
"""An OpenPGP key.
......@@ -841,7 +840,7 @@ class OpenPGPkey():
def __repr__(self):
s = '<OpenPGPKey(%s UIDs:%d)>'
s = '<OpenPGPkey(%s UIDs:%d)>'
s %= (self.fpr, len(self.uidslist))
return s
......@@ -863,6 +862,25 @@ class OpenPGPkey():
if i == 4: s += ' '
return s
def __eq__(self, other):
"""
Two keys are equal if their fingerprint matches. If either don't
have a fingerprint, we can't say for sure that they're equal
"""
if isinstance(other, self