I’m increasingly of the opinion, as you might have guessed from reading past articles on my blog, that if you can encrypt a thing, you must encrypt a thing, if it’s sent over the internet especially  after adding Google Analytics to WordPress.

So, since more crypto use is always a good thing, I wanted to find a way to encrypt email sent from my WordPress blog. Specifically, I wanted to encrypt my “hire me” contact form, which is emailed to me and quite often contains sensitive information. Sometimes clients are quite forthcoming in their initial messages, so I think it’s professional to protect that.

Although the contact form is the primary use case, this code should work for any email (with only one recipient) sent via wordpress’ internal code, providing the address has a valid (non expired encrypting) public key on file. Adding a key is, in this code, a manual process, however it’d be trivial to extend the code to chat to a key server.

So, anyway, you need to find the functions.php for your theme (I wanted to do this quickly, so I didn’t write a plugin), and put in the following code.

You’ll also need to install the gnupg extension for php. If you’re on debian, this should just be a matter of apt-get install php5-gnupg.

/**
Recursively find a non-expired encryption key for a given address.
*/
function find_encryption_key($keys) {

    $fingerprint = null;
    foreach ($keys as $k) {
        
        if ((!$k['expired'])  && ($k['can_encrypt']) && (!$fingerprint) && (isset($k['fingerprint']))) {
            $fingerprint = $k['fingerprint'];
        }
        
        if (!$fingerprint && isset($k['subkeys'])) {
            $fingerprint = find_encryption_key($k['subkeys']);
        }
    }
    
    return $fingerprint;
}

/**
Encrypt $message for delivery to $address
*/
function encryptto($message, $address) {
    
    $gpg = new gnupg();
    
    if (is_array($address)) {
        $address = $address[0];
    }
    
    // Find keys
    $keys = $gpg->keyinfo($address);
    if ($keys) {
        $fingerprint = find_encryption_key($keys);

        $gpg->addencryptkey($fingerprint);
        
        return $gpg->encrypt($message);
    }
    
    return false;
}

// Attempt to send encrypted email.
add_filter( 'wp_mail', function ($args) {
    $new_wp_mail = array(
        'to'          => $args['to'],
        'subject'     => $args['subject'],
        'message'     => $args['message'],
        'headers'     => $args['headers'],
        'attachments' => $args['attachments'],
    );
    
    if ($encrypt = encryptto($args['message'], $args['to'])) {
        $new_wp_mail['message'] = $encrypt;
    }
    
    return $new_wp_mail;
}, 1);

This code will try and find a key for the to address and attempt PGP encryption.

It’s not perfect, for example, if encryption fails for whatever reason, the message will be sent in the clear. I did it this way since not everyone’s public key will be on file, but I still wanted the email sent, so this is probably a good thing.

Also, for jetpack contact forms & comments at least, the code will fire the clear message text to Akismet, if you have the plugin installed. The latest version of Akismet will default to sending the message over TLS, so this isn’t the end of the world if you’re worried about passive monitoring.

Anyway, the more encrypted traffic on the net the better. Have fun!

I have a number of WordPress sites which use Dan Coulter’s Flickr API powered gallery plugin to render images from an attached Flickr account.

This plugin appears to no longer be maintained by the author, and I have previously written about having to make a couple of code changes in order to get it to work again.

Anyway, a little while ago, I noticed that my Flickr galleries had stopped working again, so here’s a fix.

SSL Redux

Firstly, the Flickr API now REQUIRES that you connect to it via SSL. However, the Flickr gallery code uses the non-ssl endpoints.

So, in phpFlickr.php we need to update the endpoint URLs

var $rest_endpoint = 'https://api.flickr.com/services/rest/';
var $upload_endpoint = 'https://api.flickr.com/services/upload/';
var $replace_endpoint = 'https://api.flickr.com/services/replace/'; 

If you use the database cache, at this point you’ll need to reset it, since you need to rebuild the cache using the correct URLS.

To do this, open up mysql (or mysqlmyadmin) and open your wordpress database. Next, delete all the rows from the cache, e.g.

mysql> use wordpress;
Database changed
mysql> delete from wp_phpflickr_cache;
Query OK, 904 rows affected (0.04 sec)

Broken Flickr shortcode

Next, it seems that there was a collision with the Flickr shortcode, seems something was already defining the code but was expecting different parameters (likely Jetpack, but I’ve not really investigated).

So, I modified flickr-gallery.php to define the shortcodes in the plugin’s init function, after un-registering the existing definitions, and altered the priority so that it was defined last.

Get the updated plugin on Github…

» Visit the project on Github...

I make use of Jetpack for this blog in order to add some pretty handy functionality, cross posting to my silo accounts, commenting, and OpenGraph.

Unfortunately, I had to make a couple of tweaks in order to get Opengraph working correctly.

This info is dotted around t’internet, but as an aide-mémoire, I figured I’d consolidate here.

OpenGraph headers not showing

To start, I had to get the OpenGraph headers to show in the first place. This required me to make a minor modification to the code of the plugin, not exactly desirable, but good for the moment.

Basically, Jetpack has a list of plugins that it conflicts with, and if one of those plugins is running, then it disables certain features. Unfortunately, I was running one of these plugins.

I didn’t want to disable the plugin, but after reviewing the code, I figured I wasn’t making use of the conflicting functionality (namely Opengraph, and two sets of opengraph headers is known to cause problems), so I removed the plugin from the list.

This list is found in $conflicting_plugins, which can be found in the function check_open_graph() in the file class.jetpack.php. Comment out the appropriate line at your own risk.

Missing/default open graph image

Next, I wanted to provide a default image for situations when the I don’t have a featured image in the post. This required a slight modification to my theme’s functions.php, as described here and here.

Showing your twitter user instead of @jetpack

Finally, I wanted to use my own twitter handle (@mapkyca) for the twitter card, instead of the default @jetpack.

This was another quick addition to my functions.php, e.g.

add_filter( 'jetpack_open_graph_tags', function( $og_tags ) {
        $og_tags['twitter:site'] = '@mapkyca';
        return $og_tags;
}, 11 );

See this discussion for details.