[ANN] autosign extension
Lasse Kliemann
lasse-list-mercurial-2009 at mail.plastictree.net
Wed May 13 09:02:57 CDT 2009
* Message by -Martin Geisler- from Wed 2009-05-13:
> So please go test it:
>
> http://bitbucket.org/mg/autosign/src/tip/autosign.py
>
> You can verify some or all signatures with 'hg checksigs'. This looks
> like this:
>
> 85:286738f92d3f: ** no signature
> 86:bc7de65702b7: ** bad signature on 1e9a254defd6
> 87:88f1c9bc2f9a: good signature
>
> and could probably use some improvements. Also, calling it 'verifysigs'
> might be a better name?
Thank you for your efforts!
Some suggestions and observations:
'checksigs' seems to ignore the first revision if no revision is
specified. See the attached patch for what maybe a simple fix
(start range at 0). (BTW, I had never written a line of Python
code before. Please excuse any uglyness in my patch.)
The test for 'GOODSIG' in the output may be too weak. Someone
might just create a key with 'GOODSIG' in the username. See the
attached patch for a first attempt to fix this (and to implement
the scheme sketched in the next paragraph, which I however do not
consider a final solution; see further below for that).
We need a way to connect the 'user' field in the changeset with
the key. More precisely: there should be a way to specify which
keys are allowed to give - via a good signature in the sense of
'gpg --verify' - testimony about authorship of which users. A
straightforward way is to only consider a signature valid if the
username in the key matches the username in the 'user' field of
the changeset. This is a common practice with signed e-mail
(username in key is compared to 'From:' header). This alone is
not enough, however, since anyone can create a key with anyone's
identity. As an additional measure, the trust of the key could be
considered.
However, I would prefer something quite different. We could allow
a configurable set of pairs (F,U) consisting of a key fingerprint
F and a username U each. The configuration could be done in
~/.hgrc or such.
Verification would work as follows. Let C be a changeset and S
its signature. Then S is considered _valid_ for C if there exists
a pair (F,U) such that:
* S it is a good signature for C (in the sense of gpg --verify)
for a key that has fingerprint F
* and U is the exact string in the 'user' field of C.
Then, I can say: well, I know a co-worker by some name U, and he
signs his changesets with a key that has fingerprint F. I would
then add pair (F,U) to the list in ~/.hgrc. After each pull, I
would run 'hg checksigs'. If it does not complain, I henceforth
know that I can trust all changesets bearing the name U of the
co-worker to truly originate from him. So, I would do a
verification once, and henceforth could simply rely on the output
of 'hg log'.
Advantages: no fiddling with signatures on keys (to increase
their trust), and no need for committers to have the exact same
username in Mercurial ([ui] username = ...) which they have on
their key.
> Unlike the gpg extension there is no support for changing signing keys
> or the path to gpg -- we should probably add that.
>
> When I started I of course figured that I would combine this with the
> gpg extension, but haven't done so yet. One reason is that I want this
> to support signatures made by other programs and mechanisms (say, X.509
> certs via openssl) and then the name 'gpg' is a misnormer :-)
X.509 should be supported, yes. We would have to adopt the above
scheme of fingerprint-username pairs to it, if accepted. I could
make a proposal for it then.
-------------- next part --------------
diff -r cfcfce96d0fa autosign.py
--- a/autosign.py Wed May 13 00:17:10 2009 +0200
+++ b/autosign.py Wed May 13 15:58:31 2009 +0200
@@ -14,7 +14,7 @@
including the signature.
"""
-import os, tempfile, subprocess, binascii
+import os, tempfile, subprocess, binascii, re
from mercurial import (util, cmdutil, extensions, revlog, error,
encoding, changelog)
@@ -29,7 +29,7 @@
return binascii.b2a_base64(sig).strip()
-def verify(msg, sig, quiet=False):
+def verify(msg, user, sig, quiet=False):
sig = binascii.a2b_base64(sig)
try:
fd, filename = tempfile.mkstemp(prefix="hg-", suffix=".sig")
@@ -43,7 +43,8 @@
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=stderr)
out, err = p.communicate(msg)
- return 'GOODSIG' in out
+ return (re.search('^\[GNUPG:\] GOODSIG [^ ]* ' + re.escape(user) + '$', out, re.MULTILINE) is not None
+ and re.search('^\[GNUPG:\] (TRUST_FULLY|TRUST_ULTIMATE)', out, re.MULTILINE) is not None)
finally:
try:
os.unlink(filename)
@@ -105,7 +106,7 @@
The final return code is the highest of the above.
"""
if not revrange:
- revs = xrange(1, len(repo))
+ revs = xrange(0, len(repo))
else:
revs = cmdutil.revrange(repo, revrange)
@@ -121,7 +122,7 @@
else:
ui.debug(_("signature: %s\n") % sig)
try:
- if verify(hex(h), sig, quiet=True):
+ if verify(hex(h), ctx.user(), sig, quiet=True):
msg = _("good signature")
else:
msg = _("** bad signature on %s") % short(h)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
Url : http://selenic.com/pipermail/mercurial/attachments/20090513/bec1f1ff/attachment.pgp
More information about the Mercurial
mailing list