1
# Copyright (C) 2005 Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
"""GPG signing and checking logic."""
23
from bzrlib.lazy_import import lazy_import
24
lazy_import(globals(), """
36
class DisabledGPGStrategy(object):
37
"""A GPG Strategy that makes everything fail."""
39
def __init__(self, ignored):
40
"""Real strategies take a configuration."""
42
def sign(self, content):
43
raise errors.SigningFailed('Signing is disabled.')
46
class LoopbackGPGStrategy(object):
47
"""A GPG Strategy that acts like 'cat' - data is just passed through."""
49
def __init__(self, ignored):
50
"""Real strategies take a configuration."""
52
def sign(self, content):
53
return ("-----BEGIN PSEUDO-SIGNED CONTENT-----\n" + content +
54
"-----END PSEUDO-SIGNED CONTENT-----\n")
58
tty = os.environ.get('TTY')
60
os.environ['GPG_TTY'] = tty
61
trace.mutter('setting GPG_TTY=%s', tty)
63
# This is not quite worthy of a warning, because some people
64
# don't need GPG_TTY to be set. But it is worthy of a big mark
65
# in ~/.bzr.log, so that people can debug it if it happens to them
66
trace.mutter('** Env var TTY empty, cannot set GPG_TTY.'
70
class GPGStrategy(object):
71
"""GPG Signing and checking facilities."""
73
def _command_line(self):
74
return [self._config.gpg_signing_command(), '--clearsign']
76
def __init__(self, config):
79
def sign(self, content):
80
if isinstance(content, unicode):
81
raise errors.BzrBadParameterUnicode('content')
82
ui.ui_factory.clear_term()
84
preexec_fn = _set_gpg_tty
85
if sys.platform == 'win32':
86
# Win32 doesn't support preexec_fn, but wouldn't support TTY anyway.
89
process = subprocess.Popen(self._command_line(),
90
stdin=subprocess.PIPE,
91
stdout=subprocess.PIPE,
92
preexec_fn=preexec_fn)
94
result = process.communicate(content)[0]
95
if process.returncode is None:
97
if process.returncode != 0:
98
raise errors.SigningFailed(self._command_line())
101
if e.errno == errno.EPIPE:
102
raise errors.SigningFailed(self._command_line())
106
# bad subprocess parameters, should never happen.
109
if e.errno == errno.ENOENT:
110
# gpg is not installed
111
raise errors.SigningFailed(self._command_line())