Blame lang/python/src/errors.py

Packit d7e8d0
# Copyright (C) 2016-2017 g10 Code GmbH
Packit d7e8d0
# Copyright (C) 2004 Igor Belyi <belyi@users.sourceforge.net>
Packit d7e8d0
# Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
Packit d7e8d0
#
Packit d7e8d0
#    This library is free software; you can redistribute it and/or
Packit d7e8d0
#    modify it under the terms of the GNU Lesser General Public
Packit d7e8d0
#    License as published by the Free Software Foundation; either
Packit d7e8d0
#    version 2.1 of the License, or (at your option) any later version.
Packit d7e8d0
#
Packit d7e8d0
#    This library is distributed in the hope that it will be useful,
Packit d7e8d0
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d7e8d0
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit d7e8d0
#    Lesser General Public License for more details.
Packit d7e8d0
#
Packit d7e8d0
#    You should have received a copy of the GNU Lesser General Public
Packit d7e8d0
#    License along with this library; if not, write to the Free Software
Packit d7e8d0
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
Packit d7e8d0
Packit d7e8d0
from __future__ import absolute_import, print_function, unicode_literals
Packit d7e8d0
Packit d7e8d0
from . import gpgme
Packit d7e8d0
from . import util
Packit d7e8d0
Packit Service 30b792
del absolute_import, print_function, unicode_literals
Packit Service 30b792
Packit d7e8d0
# To appease static analysis tools, we define some constants here.
Packit d7e8d0
# They are overwritten with the proper values by process_constants.
Packit d7e8d0
NO_ERROR = None
Packit d7e8d0
EOF = None
Packit d7e8d0
Packit d7e8d0
util.process_constants('GPG_ERR_', globals())
Packit d7e8d0
del util
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class GpgError(Exception):
Packit d7e8d0
    """A GPG Error
Packit d7e8d0
Packit d7e8d0
    This is the base of all errors thrown by this library.
Packit d7e8d0
Packit d7e8d0
    If the error originated from GPGME, then additional information
Packit d7e8d0
    can be found by looking at 'code' for the error code, and 'source'
Packit d7e8d0
    for the errors origin.  Suitable constants for comparison are
Packit d7e8d0
    defined in this module.  'code_str' and 'source_str' are
Packit d7e8d0
    human-readable versions of the former two properties.
Packit d7e8d0
Packit d7e8d0
    If 'context' is not None, then it contains a human-readable hint
Packit d7e8d0
    as to where the error originated from.
Packit d7e8d0
Packit d7e8d0
    If 'results' is not None, it is a tuple containing results of the
Packit d7e8d0
    operation that failed.  The tuples elements are the results of the
Packit d7e8d0
    function that raised the error.  Some operations return results
Packit d7e8d0
    even though they signal an error.  Of course this information must
Packit d7e8d0
    be taken with a grain of salt.  But often, this information is
Packit d7e8d0
    useful for diagnostic uses or to give the user feedback.  Since
Packit d7e8d0
    the normal control flow is disrupted by the exception, the callee
Packit d7e8d0
    can no longer return results, hence we attach them to the
Packit d7e8d0
    exception objects.
Packit d7e8d0
Packit d7e8d0
    """
Packit Service 30b792
Packit d7e8d0
    def __init__(self, error=None, context=None, results=None):
Packit d7e8d0
        self.error = error
Packit d7e8d0
        self.context = context
Packit d7e8d0
        self.results = results
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def code(self):
Packit Service 30b792
        if self.error is None:
Packit d7e8d0
            return None
Packit d7e8d0
        return gpgme.gpgme_err_code(self.error)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def code_str(self):
Packit Service 30b792
        if self.error is None:
Packit d7e8d0
            return None
Packit d7e8d0
        return gpgme.gpgme_strerror(self.error)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def source(self):
Packit Service 30b792
        if self.error is None:
Packit d7e8d0
            return None
Packit d7e8d0
        return gpgme.gpgme_err_source(self.error)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def source_str(self):
Packit Service 30b792
        if self.error is None:
Packit d7e8d0
            return None
Packit d7e8d0
        return gpgme.gpgme_strsource(self.error)
Packit d7e8d0
Packit d7e8d0
    def __str__(self):
Packit d7e8d0
        msgs = []
Packit Service 30b792
        if self.context is not None:
Packit d7e8d0
            msgs.append(self.context)
Packit Service 30b792
        if self.error is not None:
Packit d7e8d0
            msgs.append(self.source_str)
Packit d7e8d0
            msgs.append(self.code_str)
Packit d7e8d0
        return ': '.join(msgs)
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class GPGMEError(GpgError):
Packit d7e8d0
    '''Generic error
Packit d7e8d0
Packit d7e8d0
    This is a generic error that wraps the underlying libraries native
Packit d7e8d0
    error type.  It is thrown when the low-level API is invoked and
Packit d7e8d0
    returns an error.  This is the error that was used in PyME.
Packit d7e8d0
Packit d7e8d0
    '''
Packit Service 30b792
Packit d7e8d0
    @classmethod
Packit d7e8d0
    def fromSyserror(cls):
Packit d7e8d0
        return cls(gpgme.gpgme_err_code_from_syserror())
Packit Service 30b792
Packit d7e8d0
    @property
Packit d7e8d0
    def message(self):
Packit d7e8d0
        return self.context
Packit Service 30b792
Packit d7e8d0
    def getstring(self):
Packit d7e8d0
        return str(self)
Packit Service 30b792
Packit d7e8d0
    def getcode(self):
Packit d7e8d0
        return self.code
Packit Service 30b792
Packit d7e8d0
    def getsource(self):
Packit d7e8d0
        return self.source
Packit d7e8d0
Packit d7e8d0
Packit Service 30b792
def errorcheck(retval, extradata=None):
Packit d7e8d0
    if retval:
Packit d7e8d0
        raise GPGMEError(retval, extradata)
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class KeyNotFound(GPGMEError, KeyError):
Packit d7e8d0
    """Raised if a key was not found
Packit d7e8d0
Packit d7e8d0
    GPGME indicates this condition with EOF, which is not very
Packit d7e8d0
    idiomatic.  We raise this error that is both a GPGMEError
Packit d7e8d0
    indicating EOF, and a KeyError.
Packit d7e8d0
Packit d7e8d0
    """
Packit Service 30b792
Packit d7e8d0
    def __init__(self, keystr):
Packit d7e8d0
        self.keystr = keystr
Packit d7e8d0
        GPGMEError.__init__(self, EOF)
Packit Service 30b792
Packit d7e8d0
    def __str__(self):
Packit d7e8d0
        return self.keystr
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
# These errors are raised in the idiomatic interface code.
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class EncryptionError(GpgError):
Packit d7e8d0
    pass
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class InvalidRecipients(EncryptionError):
Packit d7e8d0
    def __init__(self, recipients, **kwargs):
Packit d7e8d0
        EncryptionError.__init__(self, **kwargs)
Packit d7e8d0
        self.recipients = recipients
Packit Service 30b792
Packit d7e8d0
    def __str__(self):
Packit Service 30b792
        return ", ".join("{}: {}".format(r.fpr, gpgme.gpgme_strerror(r.reason))
Packit d7e8d0
                         for r in self.recipients)
Packit d7e8d0
Packit Service 30b792
Packit Service 30b792
class DecryptionError(GpgError):
Packit d7e8d0
    pass
Packit d7e8d0
Packit Service 30b792
Packit Service 30b792
class UnsupportedAlgorithm(DecryptionError):
Packit d7e8d0
    def __init__(self, algorithm, **kwargs):
Packit Service 30b792
        DecryptionError.__init__(self, **kwargs)
Packit d7e8d0
        self.algorithm = algorithm
Packit Service 30b792
Packit d7e8d0
    def __str__(self):
Packit d7e8d0
        return self.algorithm
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class SigningError(GpgError):
Packit d7e8d0
    pass
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class InvalidSigners(SigningError):
Packit d7e8d0
    def __init__(self, signers, **kwargs):
Packit d7e8d0
        SigningError.__init__(self, **kwargs)
Packit d7e8d0
        self.signers = signers
Packit Service 30b792
Packit d7e8d0
    def __str__(self):
Packit Service 30b792
        return ", ".join("{}: {}".format(s.fpr, gpgme.gpgme_strerror(s.reason))
Packit d7e8d0
                         for s in self.signers)
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class VerificationError(GpgError):
Packit d7e8d0
    def __init__(self, result, **kwargs):
Packit d7e8d0
        GpgError.__init__(self, **kwargs)
Packit d7e8d0
        self.result = result
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class BadSignatures(VerificationError):
Packit d7e8d0
    def __str__(self):
Packit Service 30b792
        return ", ".join("{}: {}".format(s.fpr, gpgme.gpgme_strerror(s.status))
Packit d7e8d0
                         for s in self.result.signatures
Packit d7e8d0
                         if s.status != NO_ERROR)
Packit d7e8d0
Packit Service 30b792
Packit d7e8d0
class MissingSignatures(VerificationError):
Packit d7e8d0
    def __init__(self, result, missing, **kwargs):
Packit d7e8d0
        VerificationError.__init__(self, result, **kwargs)
Packit d7e8d0
        self.missing = missing
Packit Service 30b792
Packit d7e8d0
    def __str__(self):
Packit d7e8d0
        return ", ".join(k.subkeys[0].fpr for k in self.missing)