OpenPGPComment - Movable Type plugin
About
OpenPGPComment is a Movable Type plugin that allows MT powered blogs to support PGP/GPG signed comments. Please note that this plugin was formerly named 'PGPComment'.
Version 1.5.2 of the plugin works with MT 3.31 and higher, with a patch to lib/MT/App/Comments.pm while version 1.5.1 is know to work well with MT 2.661, rest of 3.x series. Please note the limitation found with the plugin in MT 3.x.
Unfortunately, I will not be developing OpenPGPComment anymore as I have stopped using MovableType as my blogging engine. Feel free to pick up the development if you are ok with the Perl Artistic License associated with the code.
The system saves the PGP comment as-is into the MT database. When listing the comments to an entry, the PGP related details (headers and footers) are stripped away and only the actual comment is shown. Details of the PGP comment in its original form can be obtained by following the [OpenPGP Signature] link (the actual text can be configured) next to the comment. This unaltered post can be used to verify the signature. Optionally, the plugin can even perform a server side verification of the signed comment.
To give due credit, this plugin was inspired by the system developed by Paul Bausch for his blog. The public-key retrieval mechanism is based on Jacques Distler's idea.
Working
A commenter uses OpenPGP compliant software (like PGP or GnuPG) to sign their comment. He then puts up a link on his webpage telling the server how to find his public key. More details on how to do that can be found further below. If the server does not support server side signature verification, he can also publicise his public key location using "comment" section of his signature.
Once the comment is submitted, one of two things can happen. If the server supports comment verification, the server goes to the URL that the commenter submitted when submitting the comment, follows the link to the public key and fetches the public key. Then the server verifies that the signature on the submitted comment using the public key of the commener, which was just fetched. The result is show to any casual reader of the comments.
If the server does not support signature verification, it just stores the signed comment and shows the comment devoid of the signature header and footer to a casual comment reader. However, it also adds a link to the "raw" unmasked comment with the signature header and footer. When in doubt this raw signature body can be used by the reader to verify the signature on the comment. Of course for this, the reader will have to first find the public key of the commenter. If the commenter passed it via the "comment" section of the signature, that URL can be used. Otherwise, one has to fall back on normal PKI methods like a keyserver.
Examples
You can see OpenPGPComment working in server side signature verification mode at my weblog - TriNetre. Take a look at the comments to my post "Plugin for PGP comments in Movable Type". Click on the links "OpenPGP Signature" under any PGP signed comment to see the verification results.
Download
- For MT 3.31 and higher only! - OpenPGPComment v 1.5.2 [GPG detached signature]. Note that you need to patch lib/MT/App/Comments.pm
- For MT 2.661, MT 3.1x and 3.2 - OpenPGPComment v 1.5.1 [GPG detached signature]
Release date: 20-Jul-2006 (version 1.5.2), 21-Feb-2005 (version 1.5.1)
License - Perl Artistic License
OpenPGPComment for WordPress
Christoph Rummel has written a similar plugin for WordPress - OpenPGPComment for WordPressRequirements
If you do not intend to perform server side comment verification, you need to have only these perl modules installed:
HTML::Entities
CGI
Fcntl
Usually these modules are already installed by most hosting providers in the regular install of Perl. Other than that, if you have a Movable Type blog running on your server, you have all that is needed to run this plugin.
However, if you plan to enable server side comment verification, you will need the following Perl modules (in addition to the 3 mentioned above).
Crypt::OpenPGP
LWP::UserAgent
HTTP::Request
HTML::Parser
URI::URL
File::Copy
DB_File
An usual install of Perl would have installed all these required modules, except for Crypt::OpenPGP.
Installation
There is only one file that has to be installed. Unzip the file "OpenPGPComment.pl" into the "plugins" directory of your MT installation and chmod it to 755. If you are planning to enable server side verification, you need to set up three more files:
- Public-key ring - This stores the public keys for future use. You need to create this file by hand. A command like "echo "" > pubkey.gpg" will do the job. Once the file has been created, point the variable $pub_ring (discussed later) to the location of the file. Note that the file has to read+writeable by the CGI/web server process.
- Backup of Public-key ring - Before a new public key is added to the keyring, it is backed up. You need to create this file by hand. A command like "echo "" > pubkey.gpg.bak" will do the job. Once the file has been created, point the variable $pub_ring_backup (discussed later) to the location of the file. Note that the file has to read+writeable by the CGI/web server process.
- Keyid-URL DB - This file saves the mapping between the keyid and the URL where its public key was advertised. Do not create this file by hand. The script will create it for you as long as you point the variable $keyid_url_map_file to a filename that is contained in a directory that is readable and writeable by the CGI/webserver process.
There are a couple of generic variables that can be customised. To do so, open the script in your editor and change these variables' values:
- $sig_in_textarea - By default this variable is set to '1'. It is used to control how the 'raw' signature comment is displayed. Displaying the signed comment in a textarea allows a user to copy-verify the comment at his end more easily. It also prevents the auto-conversion of raw HTML codes by the browser. Set this variable to '0' to prevent use of textarea to show the signed comment.
- $textarea_rows and $textarea_cols control the dimension of the above mentioned textarea. If $sig_in_textarea is not set to 1, these two variables have no effect.
If you need to enable server side comment verification, you need to customise the following varibles too:
- $do_serverside_verification - Change the value to '1' to perform server side verification. By default it is set to '0'. Only if you change the value to '1' will any of the remaining variables have any effect.
- $VERIFY_DEBUG - Set this to '1' to enable verbose details of the public-key fetching process. Set to '0' to just print out minimal result. It is recommended to leave this to '1' for some time after your install this script to make sure things are working as you expect it to and then change it to '0' later.
- $pub_ring - This variable holds the full path and name of the file that will act as your keyring, holding all the public keys fetched. Note that the file has to be readable and writeable by the process that runs the CGI scripts. It is safe to chmod it to 666. If you are starting fresh, just create an empty file. DO NOT use your personal public-key ring (that you might be using with your PGP/GPG installation) for this. Just start a new empty file.
- $pub_ring_backup - Every time, before the plugin adds a new key to the ring, it backups the present ring. This is helpful just incase the file gets corrupted. Again this file has to be created by you. Just create an empty file and give it the same name as the $pub_ring files + a '.bak'. So if $pub_ring is 'pubring.gpg', $pub_ring_backup should be 'pubring.gpg.bak'. Chmod this too to 666.
- $keyid_url_map_file - This variable contains the path and name of the file that holds the publickey_id and the URL from where it was received. This is used in the verification process. Do not create this file yourself. The script will create it for you. Just make sure that the directory you want to put this file in is read and writeable. Easiset would be to chmod 777 the directory. To be of the safe side, just make sure no other file is present in this directory (since you have chmod it to 777!).
Upgrade
From 1.5.1Upgrade only if you are using MT 3.31 or higher. Continue to use version 1.5.1 if you are using a lower version of MT. To upgrade, just replace the older OpenPGPComment.pl script with the new one. To play safe, keep a backup copy of the old script somewhere. Make sure that the backup copy does not have '.pl' extension if you save it in the 'plugins' directory.
Note that you need to patch lib/MT/App/Comments.pm.
From 1.51.5.1 introduces a new tag "MTPGPCommentAuthorLink" that can be used to selectively disable 'nofollow' for PGPComments. See discussion at Jacques Distler's blog.
From 1.4Please note that up until v 1.5, the link to the raw PGP comment was being generated by the plugin internally. But as of v 1.5, the blog owner has the ability to define where to place the link. Please see the usage of the 'MTIfPGPSigned' tag below to see how this can be done.
From 1.3Just replace the older OpenPGPComment.pl script with the new one. To play safe, keep a backup copy of the old script somewhere. Make sure that the backup copy does not have '.pl' extension if you save it in the 'plugins' directory.
From 1.2Additional new tags for more flexibility - '<$MTPGPCommentPreviewBody$>' and '<MTIfCommentVerification>'. See below under Usage. Replace the older OpenPGPComment.pl script with the new one.
From 1.1, 1.01 or 1.0The PGPComment="1" tag has been discontinued. Use the <$MTPGPComment> instead. Also see new tags <$MTPGPCommentPreviewBody$>' and '<MTIfCommentVerification>'. See below under Usage. Replace the older OpenPGPComment.pl script with the new one.
From 1.01 or 1.0 (additional)Those who are upgrading from version 1.0 and 1.01 please note that this plugin was intialy called "PGPComment". As of version 1.1, it will be called OpenPGPComment to relfect the underlying specifications.
Hence, if you have already installed versions 1.0 or 1.01, there will be a file named 'PGPComment.pl' in the 'plugins' directory. Please delete it and use the new 'OpenPGPComment.pl' file found in the latest version. Again, your plugin directory should not contain the file 'PGPComment.pl'. Only 'OpenPGPComment.pl' should be present.
Mailing List
If you want to be kept informed about new releases and news regarding OpenPGPComment, please subscribe to the OpenPGPComment announcement mailing list. Note that this is an announce-only mailing list. So as a user you cannot post to the mailing list. All emails sent by you (other than subscribe and unsubscribe) will not be read by anyone.
To subscribe to the mailing list, send an email from the account you want to subscribe, to 'openpgpcomment-request@freelists.org' with 'subscribe' in the Subject field of the email.
To unsubscribe to the mailing list, send an email from the account you want to unsubscribe, to 'openpgpcomment-request@freelists.org' with 'unsubscribe' in the Subject field of the email.
To view the archive and other related matters, visit the OpenPGPComment announcement mailing list page.
Tag Usage
There are seven tags that can be used with OpenPGPComment to cutomise the working of the plugin.
- <$MTPGPCommentBody$> - This tag is used instead of the "MTCommentBody" tag. So, where ever you used <$MTCommentBody$> use <$MTPGPCommentBody$> now.
- <$MTPGPCommentPreviewBody$> - This tag is used instead of the "MTCommentPreviewBody" tag. So, where ever you used <$MTCommentPreview$> use <$MTPGPCommentPreviewBody$> now.
- MTIfPGPSigned - This is a conditional tag that prints out the content it encloses if the comment is PGP signed. If the comment is not PGP signed, the content it encloses is not printed out. The primary use of this tag is to let the blog owner place the link to the raw PGP content as per his/her blog template design.
- MTIfSpecificComment - This container tag is used around the template codes that deals with the CommentBody. Example is given later.
- MTIfNotSpecificComment - This container is used around the comment listing template codes that has to be hidden when the full PGP signeature of an entry is being displayed. Usually this is used to enclose the comment entry form. Example is given below.
- MTIfCommentVerification - This container tag is used around the template codes that should be displayed whenever the raw signature is being displayed. The main differerence between MTIfCommentVerification and MTIfSpecificComment is that MTIfCommentVerification can be used outside the context of a MTComment container. Example is given later.
- MTPGPCommentAuthorLink - This tag can be used to disable no-follow tag for PGP signed comments
An example of the tags in action is given below. First, take a look at the comment listing template:
<MTIfSpecificComment>
<div class="comments-body">
</MTIfSpecificComment>
<$MTPGPCommentBody$>
<MTIfSpecificComment>
<span class="comments-post">Posted by <$MTPGPCommentAuthorLink spam_protect="1"$> at <$MTCommentDate$></span>
</div>
</MTIfSpecificComment>
</MTComments>
<MTIfNotSpecificComment>
<MTEntryIfCommentsOpen>
<div class="comments-head">Post a comment</div>
...
...
</MTEntryIfCommentsOpen>
</MTIfNotSpecificComment>
An example of the tags being used in the comment preview template is given below:
<div class="comments-body">
<$MTPGPCommentPreviewBody$>
<span class="comments-post">Posted by <$MTCommentAuthorLink spam_protect="1"$> at <$MTCommentDate$></span>
</div>
</MTComments>
An example to show how to use 'MTIfPGPSigned'. Here this tag is used in the comment listing template to create a link to the page that displays the raw PGP content.
<span class="comments-post">Posted by <$MTCommentAuthorLink spam_protect="1"$> at <$MTCommentDate$>
<MTIfPGPSigned>
{<a href="<$MTCGIPath$><$MTCommentScript$>?entry_id=<$MTEntryID$>
&comment_id=<$MTCommentID$>&raw_pgp=1" title="Verify PGP signature of comment by <$MTCommentAuthor$>
[<$MTCommentDate$>]">OpenPGP Signature</a>}
</MTIfPGPSigned>
</span>
</div>
An example to show how to use 'MTIfCommentVerification'. Here the title of the page is displayed differently if a raw PGP signature is being shown.
<MTIfNotSpecificComment>Comment on </MTIfNotSpecificComment>
<MTIfCommentVerification>PGP-Signed Comment on
</MTIfCommentVerification>
<$MTEntryTitle$>
</title>
Debug Messages
The plugin has been coded to give meaningful error messages. For these verbose error messages to be show, you have to set $VERIFY_DEBUG to 1. See Installation notes to see how to do this. One setup this way, you can see a couple of error/success message when verifying the comment
- "Key already in ring" - This means that the keyid of the key used to sign the message was already present in the key-ring. There is no need to fetch it again.
- "Key not in ring. Fetching..." - This means that the keyid of the key used to sign the message is not present in the key-ring. We need to fetch it.
- "Going to find author's pubkey URL from his homepage XYZ" - The script is on its way to fetch the comment author's homepage (as given by him while submitting the form).
- "Going to get the public key from ABC" - After fetching the author's homepage, the script has found a possible location of the public-key and is going to fetch it.
- "Key hhhhhh not found in this keyfile. Keyring add unsuccessful." - This means that the public key file fetched did not contain the key for the keyid used to sign the comment.
- "Can't open key-url DB file XYZ: errormessage" - The plugin encountered an error in finding the db file to store the keyid-URL pairs. Check Installation to see how to setup the file properly.
- "Failed to make a backup keyring to $pub_ring_backup" - The plugin was unable to backup the existing keyring file before it tries to add the newly found public-key. Check Installation to see how to setup the file properly.
- "Error opening keyring somenumber: someerror" - There was some error in opening the keyring file. Check Installation to see how to setup the file properly.
- "Successfully added new key_id somekeyid" - Great! The public key for the keyid that was used to sign the comment was successfully retrieved and has been added to the keyring. Now we can verify the comment.
- "Good signature ... " - The comment has been verified to be a valid comment from the commeter. Do check the rest of the details to make sure the commenter is who you think he/she is!
- "Bad signature!" - The plugin was not able to positively validate the signature of the comment. Either the comment has been tampered with or the plugin was not able to fetch the public key of the poster because the comment poster has not advertised his/her public key location in the way the plugin uses.
Submitting OpenPGP signed comments
Insert the clear-signed comment into the "Comment" area. Please make sure that you clearsign your comment only after you preview it atleast once. Some blog may not accept some tags (like <p>) and would silently eleminate them from the comment, rendering your signature of the original comment invalid.
If you are clear-signing a comment, do make sure that you have setup your homepage to give details of the location of your public key. To do this, add the following HTML code to your webpage (the one that you use as your URL in the comment).
where the "href" points to the file that holds your PGP/GPG public key.
When this plugin tries to verify the comment, if it does not find your publick key in the keyring, it goes to your homepage URL, looks for the tag given above and then follows the URL mentioned in the 'href' part to fetch the public key. If you are part of a multi-author blog, you can use more than one code as given above to publish the location of all your authors' public keys.
You might also want to consider passing the URL your public key as a comment in your signature, though this is not a requirement, nor does it play any part in the server side comment verification process. You can easily do this by inserting the following line in your configuration file (gpg.conf):
If you are using PGP or GPGShell, ClearSign can be done as follows - as usual, type in your comment (in plain text) into the textbox. Once you have finished, right click on the PGP/GPG Traytool, select "Current Window" and "ClearSign". You will be asked for your privatekey passphrase. Once the correct phrase is given, the comment will be signed and the signed text will automatically be inserted into the textarea, in the place of the plain text. Mac users might want to try out GPGDropThing, part of the MacGPG distribution (thanks to Jim Ray for the tip).
Important - Please make sure that word wrapping is turned off in the GPG/PGP GUI tool you are using. If you are using GPGShell, launch "Preferences GPGShell" and look at the "GPGTray" tab. Change the value of "Word-wrap clear-signed text (not within files) at column:" to "0".
Verifying OpenPGP signatures
The system does not perform comment verification by default. If you want to setup the system to perform comment verification at the server side, please refer to the "Installation" section.
If server side verification is turned on, when this plugin tries to verify the comment, if it does not find your publick key in the keyring, it goes to your homepage URL, looks for the tag given above and then follows the URL mentioned in the 'href' part to fetch the public key. Once found, the key is used to verify your comment and added to the keyring to be used for subsequent verifications.
If the server side comment verification is not setup, the onus is on the comment reader to verify the comment as well as maintain the keyring. Any comment that is signed will have a link "OpenPGP Signature" that will lead you to the raw comment, with all the signatue parts preserved.
Bugs
There is a limitation in the way the plugin works in MT 3.x. MT 3.x allows a per-blog setting for the Sanitize specs. This is not (yet) supported in OpenPGPComment and hence the plugin relies on the GlobalSanitizeSpecs. Note that this affects only those who use per-blog sanitize setting. Thanks to Zack Ajmal for brining this to my notice.
If you think you have spotted another bug, please use the contact form or the email address given on that page to report it to me directly. Kindly provide at least the following information with your report:
- Version of OpenPGPComment plugin you are running.
- Version of Movable Type you are running.
- Details of error messages you are getting. These could be either the error/debug messages printed out by the plugin or got from the web server errorlog.
- Example PGP signed comment that is causing the problem. Direct URL would be great.
Changelog
- Version 1.5.2 on 20-Jul-2006
- One line change to utilize MT::Util::munge_comment added in MT 3.31 (patch courtesy of Jacques Distler)
- Version 1.5.1 on 21-Feb-2005
- Added additional tag "MTPGPCommentAuthorLink" that can be used to selectively disable 'nofollow' for PGPComments (Thanks Jacques Distler).
- Bugfix to make <MTIfPGPSigned> compatible with <MTElse> (Thanks Jacques Distler).
- Version 1.5 on 30-Mar-2004
- Added the condition tag 'MTIfPGPSigned' to be used to define placement of the 'OpenPGP Signature' link. (Thanks to Jacques Distler for the idea and sample code)
- Fixed the bug that prevented the plugin from working with comment filters like MT-Textile. (Thanks to Brad Choate for the fix)
- Version 1.4 on 10-Mar-2004
- Hide unnecessary modules from those who don't need server side verification
- Added back link from raw view
- Added support for comment verification at the server
- Version 1.3 on 02-Mar-2004
- Fixed sanitize security hole
- Added two new tags for more flexibility
- Several small fixes
- Version 1.2 on 28-Feb-2004
- Solved (?) the verification problem with HTML tagged comments
- Added MTPGPComment tag and discontinued PGPComment="1" global filter.
- Version 1.1 on 26-Feb-2004
- Changed plugin name from PGPComment to OpenPGPComment
- Added support for showing signature in textarea
- Version 1.01 on 24-Feb-2004
- Added support for non-standard path/name for mt-comments script file. Instead of hard-coding, the value is now fetched from the weblog config file.
- Version 1.0 on 23-Feb-2004
- Initial release
