~bzr-gtk/bzr-gtk/gtk2

399.3.28 by Daniel Schierbeck
Added license and copyright information to crypt module.
1
# This program is free software; you can redistribute it and/or modify
2
# it under the terms of the GNU General Public License as published by
3
# the Free Software Foundation; either version 2 of the License, or
4
# (at your option) any later version.
5
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
399.3.32 by Daniel Schierbeck
Fixed encoding error.
15
__copyright__ = 'Copyright (C) 2008 Daniel Schierbeck'
399.3.28 by Daniel Schierbeck
Added license and copyright information to crypt module.
16
__author__ = 'Daniel Schierbeck <daniel.schierbeck@gmail.com>'
399.3.4 by Daniel Schierbeck
Moved crypt code to crypt.py.
17
18
import dbus
19
20
BUS_NAME = 'org.gnome.seahorse'
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
21
399.3.4 by Daniel Schierbeck
Moved crypt code to crypt.py.
22
CRYPTO_INTERFACE = 'org.gnome.seahorse.CryptoService'
23
CRYPTO_PATH = '/org/gnome/seahorse/crypto'
24
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
25
OPENPGP_INTERFACE = 'org.gnome.seahorse.Keys'
26
OPENPGP_PATH = '/org/gnome/seahorse/keys/openpgp'
27
399.3.4 by Daniel Schierbeck
Moved crypt code to crypt.py.
28
KEY_TYPE_OPENPGP = 'openpgp'
29
KEY_TYPE_SSH = 'ssh'
30
498.1.2 by Elliot Murphy
Trying to fix bug 107169 so that visualize can be used even if there are DBus problems which prevent seahorse from being loaded
31
try:
32
    bus = dbus.SessionBus()
567.1.1 by Jelmer Vernooij
Always try to use seahorse, not just when it has already been started by the
33
    crypto = dbus.Interface(bus.get_object(BUS_NAME, CRYPTO_PATH), 
34
                            CRYPTO_INTERFACE)
35
    openpgp = dbus.Interface(bus.get_object(BUS_NAME, OPENPGP_PATH),
36
                             OPENPGP_INTERFACE)
498.1.2 by Elliot Murphy
Trying to fix bug 107169 so that visualize can be used even if there are DBus problems which prevent seahorse from being loaded
37
except dbus.exceptions.DBusException, e:
498.1.6 by Elliot Murphy
Fix stupid typo, add johns latest suggestion.
38
    get_name = getattr(e, 'get_dbus_name', None)
39
    if get_name is not None:
40
        name = get_name()
41
    else:
42
        name = getattr(e, '_dbus_error_name', None)
597.3.1 by matkor at laptop-hp
Detection of error opening dbus when python-dbus-0.62 is used.
43
        
44
    if name is None:
45
        args = getattr(e, 'args', None) # This is case for old python-dbus-0.62
46
        if args == ("Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)",):
47
            raise ImportError
48
        
498.1.6 by Elliot Murphy
Fix stupid typo, add johns latest suggestion.
49
    # DBus sometimes fails like this, just treat it as if seahorse is not
50
    # available rather than crashing.
567.1.1 by Jelmer Vernooij
Always try to use seahorse, not just when it has already been started by the
51
    if name in ("org.freedesktop.DBus.Error.Spawn.ExecFailed", 
52
                "org.freedesktop.DBus.Error.ServiceUnknown"):
498.1.3 by Elliot Murphy
Match DBus Spawn.ExecFailed exception rather than all DBus exceptions.
53
        raise ImportError
498.1.4 by Elliot Murphy
fix silly typo
54
    else:
498.1.3 by Elliot Murphy
Match DBus Spawn.ExecFailed exception rather than all DBus exceptions.
55
        raise
399.3.27 by Daniel Schierbeck
Only show Signature tab if DBus and Seahorse are installed.
56
399.3.7 by Daniel Schierbeck
Made Seahorse discover unknown keys, and added trust level to the UI.
57
FLAG_VALID = 0x0001
58
FLAG_CAN_ENCRYPT = 0x0002
59
FLAG_CAN_SIGN = 0x0004
60
FLAG_EXPIRED = 0x0100
61
FLAG_REVOKED = 0x0200
62
FLAG_DISABLED = 0x0400
63
FLAG_TRUSTED = 0x1000
64
399.3.6 by Daniel Schierbeck
Added support for key trust.
65
TRUST_NEVER = -1
66
TRUST_UNKNOWN = 0
67
TRUST_MARGINAL = 1
68
TRUST_FULL = 5
69
TRUST_ULTIMATE = 10
70
399.3.24 by Daniel Schierbeck
Added key location getter.
71
LOCATION_MISSING = 10
72
LOCATION_SEARCHING = 20
73
LOCATION_REMOTE = 50
74
LOCATION_LOCAL = 100
75
450.5.3 by Daniel Schierbeck
Made the signature checking code not try to discover the signature key.
76
keyset = dict()
399.3.7 by Daniel Schierbeck
Made Seahorse discover unknown keys, and added trust level to the UI.
77
399.3.4 by Daniel Schierbeck
Moved crypt code to crypt.py.
78
def verify(crypttext):
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
79
    (cleartext, key) = crypto.VerifyText(KEY_TYPE_OPENPGP, 1, crypttext)
80
450.5.3 by Daniel Schierbeck
Made the signature checking code not try to discover the signature key.
81
    if key != "":
82
        if key not in keyset:
83
            keyset[key] = Key(key)
84
511.1.2 by Jelmer Vernooij
Return cleartext from seahorse module
85
        return (cleartext, keyset[key])
86
87
    return (cleartext, None)
88
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
89
90
class Key:
91
92
    def __init__(self, key):
93
        self.key = key
450.5.4 by Daniel Schierbeck
Made the crypt code only use one DBus call to get key fields.
94
450.5.3 by Daniel Schierbeck
Made the signature checking code not try to discover the signature key.
95
        (keys, unmatched) = openpgp.MatchKeys([self.get_id()], 0x00000010)
96
        self.available = (key in keys)
399.3.25 by Daniel Schierbeck
Added discovery of unknown keys.
97
450.5.4 by Daniel Schierbeck
Made the crypt code only use one DBus call to get key fields.
98
        if self.available:
99
            fields = openpgp.GetKeyFields(key, ['fingerprint', 'trust', 'flags', 'display-name', 'location'])
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
100
        else:
450.5.4 by Daniel Schierbeck
Made the crypt code only use one DBus call to get key fields.
101
            fields = dict()
102
103
        self.fingerprint = fields.get('fingerprint', 'N/A')
104
        self.trust = fields.get('trust', TRUST_UNKNOWN)
105
        self.flags = fields.get('flags', 0)
106
        self.display_name = fields.get('display-name', '')
107
        self.location = fields.get('location', LOCATION_MISSING)
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
108
    
109
    def get_flags(self):
110
        return self.flags
111
399.3.10 by Daniel Schierbeck
Added getter for display name field.
112
    def get_display_name(self):
113
        return self.display_name
114
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
115
    def get_id(self):
116
        return self.key.split(':')[1][8:]
117
118
    def get_fingerprint(self):
119
        return self.fingerprint
120
121
    def get_trust(self):
122
        return self.trust
123
399.3.24 by Daniel Schierbeck
Added key location getter.
124
    def get_location(self):
125
        return self.location
126
399.3.11 by Daniel Schierbeck
Fixed error with unavailable keys.
127
    def is_available(self):
450.5.3 by Daniel Schierbeck
Made the signature checking code not try to discover the signature key.
128
        return self.available
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
129
130
    def is_trusted(self):
450.5.4 by Daniel Schierbeck
Made the crypt code only use one DBus call to get key fields.
131
        return self.flags & FLAG_TRUSTED != 0