handle nested roster group. TODO: Improve the way it's displayed in roster. Fixes...
[gajim.git] / src / common / gpg.py
blob81272569e33f88584177a595d89e69c2cee701ed
1 ## src/common/gpg.py
2 ##
3 ## Copyright (C) 2003-2010 Yann Leboulanger <asterix AT lagaule.org>
4 ## Copyright (C) 2005 Alex Mauer <hawke AT hawkesnest.net>
5 ## Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com>
6 ## Copyright (C) 2007 Stephan Erb <steve-e AT h3c.de>
7 ## Copyright (C) 2008 Jean-Marie Traissard <jim AT lapin.org>
8 ## Jonathan Schleifer <js-gajim AT webkeks.org>
9 ##
10 ## This file is part of Gajim.
12 ## Gajim is free software; you can redistribute it and/or modify
13 ## it under the terms of the GNU General Public License as published
14 ## by the Free Software Foundation; version 3 only.
16 ## Gajim is distributed in the hope that it will be useful,
17 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ## GNU General Public License for more details.
21 ## You should have received a copy of the GNU General Public License
22 ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
25 from gajim import HAVE_GPG
26 import os
28 if HAVE_GPG:
29 import gnupg
31 class GnuPG(gnupg.GPG):
32 def __init__(self, use_agent=False):
33 gnupg.GPG.__init__(self)
34 self.passphrase = None
35 self.use_agent = use_agent
36 self.always_trust = False
38 def _setup_my_options(self):
39 self.options.armor = 1
40 self.options.meta_interactive = 0
41 self.options.extra_args.append('--no-secmem-warning')
42 # disable photo viewer when verifying keys
43 self.options.extra_args.append('--verify-options')
44 self.options.extra_args.append('no-show-photo')
45 if self.use_agent:
46 self.options.extra_args.append('--use-agent')
48 def encrypt(self, str_, recipients, always_trust=False):
49 result = super(GnuPG, self).encrypt(str_, recipients,
50 always_trust=always_trust, passphrase=self.passphrase)
52 if result.status == 'invalid recipient':
53 return '', 'NOT_TRUSTED'
55 if result.ok:
56 error = ''
57 else:
58 error = result.status
60 return self._stripHeaderFooter(str(result)), error
62 def decrypt(self, str_, keyID):
63 data = self._addHeaderFooter(str_, 'MESSAGE')
64 result = super(GnuPG, self).decrypt(data,
65 passphrase=self.passphrase)
67 return str(result)
69 def sign(self, str_, keyID):
70 result = super(GnuPG, self).sign(str_, keyid=keyID, detach=True,
71 passphrase=self.passphrase)
73 if result.fingerprint:
74 return self._stripHeaderFooter(str(result))
75 # if 'KEYEXPIRED' in resp:
76 # return 'KEYEXPIRED'
77 return 'BAD_PASSPHRASE'
79 def verify(self, str_, sign):
80 if str_ is None:
81 return ''
82 data = '-----BEGIN PGP SIGNED MESSAGE-----' + os.linesep
83 data = data + 'Hash: SHA1' + os.linesep + os.linesep
84 data = data + str_ + os.linesep
85 data = data + self._addHeaderFooter(sign, 'SIGNATURE')
86 result = super(GnuPG, self).verify(data)
88 if result.valid:
89 return result.key_id
90 return ''
92 def get_keys(self, secret=False):
93 keys = {}
94 result = super(GnuPG, self).list_keys(secret=secret)
95 for key in result:
96 # Take first not empty uid
97 keys[key['keyid'][8:]] = [uid for uid in key['uids'] if uid][0]
98 return keys
100 def get_secret_keys(self):
101 return self.get_keys(True)
103 def _stripHeaderFooter(self, data):
105 Remove header and footer from data
107 if not data: return ''
108 lines = data.splitlines()
109 while lines[0] != '':
110 lines.remove(lines[0])
111 while lines[0] == '':
112 lines.remove(lines[0])
113 i = 0
114 for line in lines:
115 if line:
116 if line[0] == '-': break
117 i = i+1
118 line = '\n'.join(lines[0:i])
119 return line
121 def _addHeaderFooter(self, data, type_):
123 Add header and footer from data
125 out = "-----BEGIN PGP %s-----" % type_ + os.linesep
126 out = out + "Version: PGP" + os.linesep
127 out = out + os.linesep
128 out = out + data + os.linesep
129 out = out + "-----END PGP %s-----" % type_ + os.linesep
130 return out