You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/10/06 04:38:25 UTC

svn commit: r1004883 - /subversion/trunk/tools/dist/collect_sigs.py

Author: hwright
Date: Wed Oct  6 02:38:24 2010
New Revision: 1004883

URL: http://svn.apache.org/viewvc?rev=1004883&view=rev
Log:
Add a script I've been working on to assist in collecting release signatures.
It's still *very* rough, and doesn't everything I'd like, (and it's probably
not very secure), but in the interests of review, I'm adding it here.

I'd like to get this in shape to use for the 1.7.x releases.  You can play
around with the script at:
http://work.hyrumwright.org/pub/svn/collect_sigs.py

If you see improvements, please commit them, as my test sandbox is usually
updated daily.

* tools/dist/collect_sigs.py:
  New.

Added:
    subversion/trunk/tools/dist/collect_sigs.py   (with props)

Added: subversion/trunk/tools/dist/collect_sigs.py
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dist/collect_sigs.py?rev=1004883&view=auto
==============================================================================
--- subversion/trunk/tools/dist/collect_sigs.py (added)
+++ subversion/trunk/tools/dist/collect_sigs.py Wed Oct  6 02:38:24 2010
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+import cgi
+import cgitb
+cgitb.enable()
+
+import sys, os, string, subprocess, re
+
+version = '1.6.13'
+r = re.compile('\[GNUPG\:\] GOODSIG (\w*) (.*)')
+
+shell_content = '''
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<title>Signature collection for Subversion $version</title>
+</head>
+<body style="font-size: 14pt; text-align: justify;
+  background-color: #f0f0f0; padding: 0 5%">
+<p>This page is used to collect signatures for the proposed release of
+Apache Subversion $version.</p>
+$content
+</body>
+</html>
+'''
+
+def default_page():
+  c = '''
+<form method="post">
+File: <select name="filename">
+%s
+</select>
+<br/>
+<p>Paste signature in the area below:<br/>
+<textarea name="signature" rows="10" cols="80"></textarea>
+</p>
+<input type="submit" value="Submit" />
+</form>
+'''
+
+  contents = [f for f in os.listdir('.')
+              if f.endswith('.tar.gz') or f.endswith('.zip')
+                                       or f.endswith('.tar.bz2')]
+  contents.sort()
+
+  options = ''
+  for f in contents:
+    options = options + '<option value="%s">%s</option>\n' % (f, f)
+
+  return c % options
+
+
+def verify_sig(signature, filename):
+  args = ['gpg', '--logger-fd', '1', '--no-tty',
+          '--status-fd', '2', '--verify', '-', filename]
+
+  gpg = subprocess.Popen(args,
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+
+  gpg.stdin.write(signature)
+  gpg.stdin.close()
+
+  rc = gpg.wait()
+  output = gpg.stdout.read()
+  status = gpg.stderr.read()
+
+  if rc:
+    return (False, status + output)
+
+  lines = status.split('\n')
+  for line in lines:
+    match = r.search(line)
+    if match:
+      keyid = match.group(1)[-8:]
+      user = match.group(2)
+
+  return (True, (keyid, user))
+
+
+def process_sig(signature, filename):
+  c_verified = '''
+  <p style="color: green;">The signature is verified!</p>
+  <p>Filename: <code>%s</code></p>
+  <p>Key ID: <code>%s</code></p>
+  <p>User: <code>%s</code></p>
+  <p>This signature has been saved, and will be included as part of the
+    release signatures.  Please send mail to
+    <a href="mailto:dev@subversion.apache.org">dev@subversion.apache.org</a>
+    acknowledging your successful signature.</p>
+'''
+  c_unverified = '''
+  <p style="color: red;">The signature was not able to be verified!</p>
+  <p>Filename: <code>%s</code></p>
+  <p>Reason:</p><pre>%s</pre>
+  <p>Please talk to the release manager if this is in error.</p>
+'''
+
+  (verified, result) = verify_sig(signature, filename)
+
+  if verified:
+    return c_verified % (filename, result[0], result[1])
+  else:
+    return c_unverified % (filename, result)
+
+
+def main():
+  print "Content-Type: text/html"
+  print
+
+  form = cgi.FieldStorage()
+  if 'signature' not in form:
+    content = default_page()
+  else:
+    content = process_sig(form['signature'].value, form['filename'].value)
+
+  # These are "global" values, not specific to our action.
+  mapping = {
+      'version' : version,
+      'content' : content,
+    }
+
+  template = string.Template(shell_content)
+  print template.safe_substitute(mapping)
+
+
+if __name__ == '__main__':
+  main()

Propchange: subversion/trunk/tools/dist/collect_sigs.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/trunk/tools/dist/collect_sigs.py
------------------------------------------------------------------------------
    svn:executable = *