Monthly Archives: November 2009

Building Services Using Automator Workflows in Snow Leopard (10.6)

In Snow Leopard (Mac OS X 10.6) the Automator tool has been drastically upgraded to support the creation of service workflows. In simple terms, this means you can build automated chains of tasks that can be invoked in a context sensitive manner. Not simple enough? Using this tool, you can automate common actions you perform and the proper service will appear in the menu only when it is capable of being used. You can even assign global hotkeys (via the Keyboard preference pane) to your service. Let’s take a look at a simple service workflow so you can see how it’s done.

Open Automator (it’s located in your /Applications folder). You will be greeted by a sheet requesting a template for your workflow. Choose service.

choose_your_template

You’ll now be greeted by the main Automator window. On the left you’ll see a Library and actions you can perform. On the right you’ll see an empty pane where you drag actions or files to build your workflow. Third party applications you have installed can expose additional available actions, so the list of available actions will vary for each user’s computer.

main_window

As an example, we’re going to build a service that allows you to select files in the Finder, automatically zip them, and attach them to a new email. To begin, change the drop down in the upper right from “text” to “files or folders” and change “any application” to “Finder”. This means that the service we’re constructing will accept files or folders from the Finder as input. Next we need to add our first action. To accomplish this type “create” in the search field in the upper left of the actions pane. This will live filter the available actions so you can more easily locate the “Create Archive” action. Once you’ve found it, drag and drop it to the right hand side.

After creating the zip archive we want to attach it to a mail message. Search for “new mail message” and drag and drop it below the first action. It will prompt you with a few dialogs (mostly for permissions to access your keychain), but when you’re done you should have the workflow below.

prelim_workflow

To test you can click Run, but you’ll receive a warning that states “This service will not receive input when run inside Automator. To test this service within Automator, add the “Get Specified Finder Items” action to the beginning of your workflow. Remove or disable the action before running the workflow outside of Automator.”. Hit cancel (there’s no point to running our service without input!) and add the “Get Specified Finder Items” action to the very top of your workflow. You’ll also need to add an item or two for testing.

get_specified

To test the entire service, click Run in the upper right! You should see it create a zip file in the same directory as whatever files you specified, then open a new Mail message with your zip file attached.

If everything is working you can remove or disable the “Get Specified Finder Items” action and save your new service. Whatever you name it will be how it appears in your Services menu, so try to give it a descriptive name (something like “Create Zip and Email”). Now head to the Finder, select a file or folder, and click the Finder menu to see the Services submenu.

services_menu

Success!

But what if you don’t want to use that submenu? OS X allows you to assign global shortcuts/hotkeys to any Service using the Keyboard preference pane in System Preferences. Go to Keyboard Shortcuts within it, click the services option on the left, then find your “Create Zip and Email” option on the right. To add a shortcut you’ll need to double click on the righthand side of the Create Zip and Email row. Once the text box appears, press the key combination you want to use to invoke this service. Try to choose one that won’t conflict with anything.

keyboard_assigned

Automator has a great deal of power, so try experimenting with various actions to build your own ideal workflow. For example, I frequently parse SSL certificates in the course of my day, so I built this workflow to do it quickly and display the results in a text document in my editor of choice:

parse_cert

I also wanted a universal key combo to start the screensaver (which requires a password) so I could lock my computer quickly without using the mouse.

start_screensaver

If you’ve got other service ideas or want to show off one of you’ve written drop a comment! It’s always great to discover a better/more efficient way to accomplish a task.

Bypass Hulu Regional Restrictions in Mac OS X

Hulu is a great site to find new shows and catch up on old, but due to various contracts no one outside the US can use it. This irritated some friends of mine from Canada, England, Germany, et cetera. So I decided to write up one (very reliable) way to circumvent the Hulu geolocation checks — using a VPN.1

Accessing Hulu Outside The US

In this case, we’ll be using a small VM and the open source VPN server pptpd. All the server side instructions below are applicable to both OS X and Windows, but the client setup is only specified for Mac OS X.

Server Setup

First, obtain a VM from a reputable (and fast) US vendor. The VM must be located in the US since that’s our required origin. I personally use Slicehost, but there are many others. Once you get your login be sure you change the root password.

Install pptpd. If you’re running on Ubuntu or Debian you can simply run

apt-get install pptpd

Once you have pptpd installed, we’ll need to add a user. The default pptpd configuration is fine, but we’ll need to edit /etc/ppp/chap-secrets. When you edit the file (using vi, nano, emacs, et cetera) you’ll see this:

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses

Client is your username, server is “pptpd”, secret is your password in plaintext, and IP addresses is a range of allowed IPs. If you’re unconcerned about who might attempt to access your VPN, you can simply use a wildcard (*). Once you’ve populated this file with data it will look something like this:

# Secrets for authentication using CHAP
# client	server	secret			IP addresses
testuser	pptpd	mypassword		*

We need to set up IPv4 forwarding, so edit /etc/sysctl.conf and uncomment the line below from the file (remove the #).

#net.ipv4.ip_forward=1

This will enable the behavior after a reboot, but you can enable it right now by running:

echo 1 > /proc/sys/net/ipv4/ip_forward

Now run these commands:

/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
/sbin/iptables -A FORWARD -i eth0 -o ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -i ppp0 -o eth0 -j ACCEPT

Once you’ve run these you can save them so they execute every time your VM boots by following these quick instructions. This completes the server side setup.

Client Setup

Now it’s time to configure the Mac to utilize the VPN server. Bear in mind that all traffic to the internet will be routed through your VPN server when this is active, so you’ll only want to connect to your VPN when watching Hulu.2

Open System Preferences and go to Network.  Click the plus sign in the lower left and choose add to add a VPN PPTP interface.  Then set the server address (the IP of your VM) and account name (“testuser” from above).
network_screen

After filling out those fields, click authentication settings and type your password, then click Okay.

advanced

Finally, click advanced, then click DNS and click the plus sign.  Add 4.2.2.1 as a DNS server.3

dns_fix

Save these changes and then you can click connect to test it out. Your traffic should all be routed through the VPN and since the endpoint is located in the US Hulu should work just fine!

  1. There are many other ways, including just proxying Hulu traffic from the browser and Flash plugin, but I’m not going to cover those methods.
  2. This can be alleviated by using a split tunnel if you want to go to the trouble.
  3. Our PPTP server doesn’t announce its own DNS by default.

Fixing GrowlMail for Mail 4.2

Update 3: Fix for 10.6.7 and Mail 4.5
Update 2: Fix for 10.6.5 and Mail 4.4
Update: Fix for 10.6.4 and Mail 4.3

Lately Apple has been revving the version number (and plugin compatibility UUID) of Mail.app with every version of 10.6. This breaks bundles like GrowlMail even when they are still compatible. The easy fix (although not necessarily the best if it turns out an update is required!) is to run a few commands in Terminal to add the new UUIDs1 to the SupportedPluginCompatibilityUUID key in the Info.plist.2

If you have already had your plugins disabled by opening Mail.app you’ll need to look in ~/Library/Mail (or /Library/Mail if you installed globally) and move the files back to the active bundles directory. They’ll typically be in Bundles (Disabled), so quit Mail, find them, and move them back into the proper directory.

Once you’ve gotten the files moved into the proper location use either the local installation or global installation commands below (depending on where you found your bundles). To run them, simply copy/paste them into a Terminal window.3

For GrowlMail (assuming local installation)

defaults write ~/Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "2F0CF6F9-35BA-4812-9CB2-155C0FDB9B0F"
defaults write ~/Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "0CB5F2A0-A173-4809-86E3-9317261F1745"

For GrowlMail (global installation)

defaults write /Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "2F0CF6F9-35BA-4812-9CB2-155C0FDB9B0F"
defaults write /Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "0CB5F2A0-A173-4809-86E3-9317261F1745"

Update: Letterbox has been updated, but the above instructions can be adapted for any future OS update that breaks compatibility.

Update 2: You can download a pre-patched copy if you don’t want to follow the above instructions. Just unzip it and drop it in your bundles directory.

Update 3: GrowlMail 1.2.1 has been released, which fixes 10.6.2 compatibility. This issue will likely occur again with 10.6.3 though!

  1. 2F0CF6F9-35BA-4812-9CB2-155C0FDB9B0F for Mail.app v4.2 and 0CB5F2A0-A173-4809-86E3-9317261F1745 for the Message framework. These were released with OS X 10.6.2.
  2. These UUIDs can be found in /Applications/Mail.app/Contents/Info.plist and /System/Library/Frameworks/Message.framework/Resources/Info.plist for when they inevitably change again.
  3. Terminal is found in /Applications/Utilities if you’ve never used it before. You’ll see a prompt and you can paste the commands in and hit enter.

Find A Matching Certificate And Key Pair

If you have a list of keys and SSL certs and don’t know which cert belongs with which key, here’s a script for you. It’s not efficient (nested for loop!), but it gets the job done quickly.1

#!/bin/bash
for i in `ls *.key` 
do
key_mod=`openssl rsa -noout -in $i -modulus`
for j in `ls *.cer`
do
x509_mod=`openssl x509 -noout -in $j -modulus`
if [ "$x509_mod" == "$key_mod" ]; then
echo "$j matches $i"
fi 
done
done
  1. If bash allowed multidimensional or associative arrays this would be trivial to optimize.

SSL VHosting On The Same IP (aka SNI)

Server Name Indication (SNI), an extension to TLS, allows browsers that support it to connect to SSL hosts that do not have dedicated IPs (much like standard http virtual hosting has worked for years). This extension, however, must be supported on both the server and client side. Microsoft has not yet chosen to support it (maybe IIS 8?), but the Apache project did with the 2.2.12 release. Recently, Ubuntu 9.10 Server became the first server distribution to ship with Apache and OpenSSL built with the appropriate flags, so if you’d like to follow along you can use a 9.10 VM.

In the ideal case everything is the same as a regular vhost, but you’ll first need to enable SSL. On Ubuntu this requires you to run a2enmod and type “ssl”. After that you’ll need to add

NameVirtualHost *:443

to the root conf, then make your VirtualHost much like a normal one. A very basic pair of vhosts is seen below.

<VirtualHost *:443>
	ServerAdmin webmaster@localhost
 
	DocumentRoot /my/doc/root
	ServerName mydomain.com
	SSLEngine On
	SSLCertificateFile /path/to/domain.crt 
	SSLCertificateKeyFile /path/to/domain.key
</VirtualHost>
<VirtualHost *:443>
	ServerAdmin webmaster@localhost
 
	DocumentRoot /my/doc/root
	ServerName mydomain2.com
	SSLEngine On
	SSLCertificateFile /path/to/domain2.crt 
	SSLCertificateKeyFile /path/to/domain2.key
</VirtualHost>

These vhosts should be placed in different includes ideally, but it isn’t required. If you just want to test with a self-signed certificate you can create one with

openssl req -new -nodes -keyout mykey.key -out mycert.cer -days 3650 -x509

You’ll need to specify the domain name you want in the “Common Name” section.

Once you’ve got all this done you can restart apache and test it out! If you test on a browser that doesn’t support SNI (IE on XP) you’ll get the SSL cert for the first vhost apache parses. To disable accessing it on non-SNI hosts you can add

SSLStrictSNIVHostCheck on

to the root conf. This will cause a 403 error for those browsers.

If you’d like to see an example implementation of SNI you can check out my IDN domains https://☢.ws/ and https://☣.ws/. These sites are hosted on the same IP with different SSL certificates. I have strict host checking turned on so visiting them with a non-SNI capable browser will result in a 403 error.1

  1. See the Wikipedia article about Server Name Indication for more information on supported browsers.

More Useful Bash/Terminal Settings

A few more tricks to make your bash environment better. As always, add them to your ~/.profile or ~/.bash_profile to enable.

Disable the pagination of long lists when ambiguously tab completing.

bind 'set page-completions off'

Increase max returned items before being prompted. (ie, “Display all 380 possibilities? (y or n”). You can set the number to whatever you’d like.

bind 'set completion-query-items 300'

Show the list of autocompletion options after the first tab. This prevents the beep + second tab behavior.

bind 'set show-all-if-ambiguous on'

When autocompleting for cd or rmdir, list only directories as choices.

complete -d cd rmdir

Autocompletion for ssh known_hosts. Add this to your ~/.ssh/config (if the file doesn’t exist, create it)

Host *
HashKnownHosts no

Make grep highlight the matching terms in its output.

export GREP_OPTIONS='--color=auto'

Ignore case for case preserving but insensitive filesystems (like HFS+). I don’t personally use this, but perhaps some people will like it.

bind 'set completion-ignore-case on'

Don’t show hidden files when listing. Another option I don’t personally use.

bind 'set match-hidden-files off'