1.1 --- a/MoinMessage.py Fri Jun 07 18:41:04 2013 +0200
1.2 +++ b/MoinMessage.py Sat Jun 08 01:21:27 2013 +0200
1.3 @@ -282,10 +282,7 @@
1.4 (fingerprint, identity, content).
1.5 """
1.6
1.7 - try:
1.8 - content, signature = message.get_payload()
1.9 - except ValueError:
1.10 - raise MoinMessageMissingPart
1.11 + content, signature = getContentAndSignature(message)
1.12
1.13 # Verify the message format.
1.14
1.15 @@ -386,6 +383,23 @@
1.16 return mimetype == "multipart/encrypted" and \
1.17 message.get_param("protocol") == "application/pgp-encrypted"
1.18
1.19 +def getContentAndSignature(message):
1.20 +
1.21 + """
1.22 + Return the content and signature parts of the given RFC 3156 'message'.
1.23 +
1.24 + NOTE: RFC 3156 states that signed messages should employ a detached
1.25 + NOTE: signature but then shows "BEGIN PGP MESSAGE" for signatures
1.26 + NOTE: instead of "BEGIN PGP SIGNATURE".
1.27 + NOTE: The "micalg" parameter is currently not supported.
1.28 + """
1.29 +
1.30 + try:
1.31 + content, signature = message.get_payload()
1.32 + return content, signature
1.33 + except ValueError:
1.34 + raise MoinMessageMissingPart
1.35 +
1.36 # Communications functions.
1.37
1.38 def timestamp(message):
2.1 --- a/MoinMessageSupport.py Fri Jun 07 18:41:04 2013 +0200
2.2 +++ b/MoinMessageSupport.py Sat Jun 08 01:21:27 2013 +0200
2.3 @@ -10,8 +10,10 @@
2.4 from MoinMoin.log import getLogger
2.5 from MoinMoin.user import User
2.6 from MoinMoin import wikiutil
2.7 -from MoinSupport import ItemStore, getHeader, getMetadata, getWikiDict, writeHeaders
2.8 -from MoinMessage import GPG, Message, MoinMessageError, is_signed, is_encrypted
2.9 +from MoinSupport import ItemStore, getHeader, getMetadata, getWikiDict, \
2.10 + writeHeaders
2.11 +from MoinMessage import GPG, Message, MoinMessageError, \
2.12 + is_signed, is_encrypted, getContentAndSignature
2.13 from email.parser import Parser
2.14 import time
2.15
2.16 @@ -123,74 +125,20 @@
2.17
2.18 request = self.request
2.19
2.20 - homedir = self.get_homedir()
2.21 - if not homedir:
2.22 - return
2.23 -
2.24 - gpg = GPG(homedir)
2.25 + # Accept any message whose sender was authenticated by the PGP method.
2.26
2.27 - # NOTE: RFC 3156 states that signed messages should employ a detached
2.28 - # NOTE: signature but then shows "BEGIN PGP MESSAGE" for signatures
2.29 - # NOTE: instead of "BEGIN PGP SIGNATURE".
2.30 - # NOTE: The "micalg" parameter is currently not supported.
2.31 -
2.32 - try:
2.33 - fingerprint, identity, content = gpg.verifyMessage(message)
2.34 + if request.user and request.user.valid and request.user.auth_method == "pgp":
2.35
2.36 - # Reject messages without a declaration.
2.37 -
2.38 - except MoinMessageMissingPart:
2.39 - writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
2.40 - request.write("There must be a content part and a signature for signed uploads.")
2.41 - return
2.42 + # Handle the embedded message.
2.43
2.44 - # Reject messages without appropriate content.
2.45 -
2.46 - except MoinMessageBadContent:
2.47 - writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
2.48 - request.write("Signature data must be provided in the second part as application/pgp-signature.")
2.49 - return
2.50 + content, signature = getContentAndSignature(message)
2.51 + self.handle_message_content(content)
2.52
2.53 # Reject any unverified message.
2.54
2.55 - except MoinMessageError:
2.56 + else:
2.57 writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden")
2.58 request.write("The message could not be verified.")
2.59 - return
2.60 -
2.61 - # Log non-fatal errors.
2.62 -
2.63 - if gpg.errors:
2.64 - getLogger(__name__).warning(gpg.errors)
2.65 -
2.66 - # Map the fingerprint to a Wiki user.
2.67 -
2.68 - old_user = None
2.69 - request = self.request
2.70 -
2.71 - try:
2.72 - if fingerprint:
2.73 - gpg_users = getWikiDict(
2.74 - getattr(request.cfg, "moinmessage_gpg_users_page", "MoinMessageUserDict"),
2.75 - request
2.76 - )
2.77 -
2.78 - # With a user mapping and a fingerprint corresponding to a known
2.79 - # user, temporarily switch user in order to make the edit.
2.80 -
2.81 - if gpg_users and gpg_users.has_key(fingerprint):
2.82 - old_user = request.user
2.83 - request.user = User(request, auth_method="gpg", auth_username=gpg_users[fingerprint])
2.84 -
2.85 - # Handle the embedded message.
2.86 -
2.87 - self.handle_message_content(content)
2.88 -
2.89 - # Restore any user identity.
2.90 -
2.91 - finally:
2.92 - if old_user:
2.93 - request.user = old_user
2.94
2.95 def handle_message_content(self, content):
2.96
3.1 --- a/MoinMoin/auth/pgp.py Fri Jun 07 18:41:04 2013 +0200
3.2 +++ b/MoinMoin/auth/pgp.py Sat Jun 08 01:21:27 2013 +0200
3.3 @@ -2,7 +2,7 @@
3.4 """
3.5 MoinMoin - PGP authentication using incoming MIME request bodies
3.6
3.7 - @copyright: 2001-2003 Juergen Hermann <jh@web.de>,
3.8 + @copyright: 2001-2003 Juergen Hermann <jh@web.de>
3.9 2003-2006 MoinMoin:ThomasWaldmann
3.10 2007 MoinMoin:JohannesBerg
3.11 2013 Paul Boddie <paul@boddie.org.uk>