iOS 9 ATS (App Transport Security) exceptions

App Transport Security is a feature that improves the security of connections between an app and web services. The feature consists of default connection requirements that conform to best practices for secure connections. Apps can override this default behavior and turn off transport security.
Transport security is available on iOS 9.0 or later, and on OS X 10.11 and later.


What does that mean?

That unless you change something in your iOS app’ plist, your app will not be able to communicate with unsecure HTTP servers, when it runs on iOS 9.

That’s a good thing really; Apple is trying to force people to update their HTTP servers to use the latest HTTPS protocols & recommendations: TLS 1.2, SHA256 or better, forward secrecy.

OK. A good thing. What’s the problem then?

Where this could cause you issues is if you use third-party services that have not yet adhered to those standards.

They might have a good reason not to (doubtful!), or they are working on implementing them, but are not there yet.

What’s the solution?

Right now, the best workaround is to whitelist all servers on a case-by-case basis, per the service providers own recommendations.
Thus the need for the list in this repository.

In the ats.plist file in this repo, you’ll find the exceptions that you need to add to your app .plist, if you use some of the third-party services that published recommendations regarding ATS.

How can I help?

If you know of any other services that published recommendations for exceptions that should be used in iOS 9 apps, for their service to work as expected, please fork and create a pull request.

How can I test if my servers will work with ATS enabled, or what exceptions I might need?

nscurl --ats-diagnostics

How to extract your TOTP secrets from Authy

Maybe you just want to back them up in case something goes wrong, or maybe you want to set up a new two-factor authentication app on a platform that Authy doesn’t support (*cough* Windows Phone *cough*). Whatever your reasons, if you want to export your TOTP secret keys from Authy, their apps or support guys won’t be much help to you.

The trick, that I just used to install all my existing TOTP secrets in the Microsoft Authenticator app, is to modify one of their app of which we have the source, namely their Chrome app, to show us what we want.

So I opened gaedmjdfmmahhbjefcbgaolhhanlaolb/js/app.js from my Chrome Extensions folder (~/Library/Application Support/Google/Chrome/Default/Extensions on a Mac, ~/.config/google-chrome/Default/Extensions on Linux) in my favorite text editor (TextMate), and used JavaScript > Reformat Selection to be able to see what was happening in there. I then found that the shared secrets I was after was stored in GoogleAuthApp.decryptedSeed. I was looking for the decrypted version, because I didn’t want to have to understand where the encrypted values were stored, and how I could decrypt them myself; their Chrome app could decrypt them already, so all I needed was to add something in there that would somehow output them.

So I added a getter for the shared secret, in GoogleAuthApp, like this:

}, GoogleAuthApp.prototype.getOtp = function() {
 return this.isEncrypted() ? "------" : this.otpGenerator.getOtp(this.decryptedSeed)
}, GoogleAuthApp.prototype.getSharedSecret = function() {    
return this.isEncrypted() ? "?" : this.decryptedSeed
}, GoogleAuthApp.prototype.isDecrypted = function() {

Then I modified TokensView.prototype.updateTokens to output this info, along with the human-readable name of the entry, in a link to a QR code that I can scan in any TOTP client (compatible with Google Authenticator), like this:

}, TokensView.prototype.updateTokens = function(tokenRows) {
    var app, element, tokenRow, _i, _len, _results;
    for (_results = [], _i = 0, _len = tokenRows.length; _len > _i; _i++) tokenRow = tokenRows[_i], element = $(tokenRow), app = AppManager.get().find(element.attr("data-token-id")), _results.push(element.find(".tokenCode").text(app.getOtp()));
    for (_i = 0, _len = tokenRows.length; _len > _i; _i++) {
        tokenRow = tokenRows[_i];
        element = $(tokenRow);
        app = AppManager.get().find(element.attr("data-token-id"));
        try {
            var $sharedSecretBlock = element.find(".sharedSecret");
            if ($sharedSecretBlock.length == 0) {
               element.append('<div class="sharedSecret" style="float:right;font-size:13px;padding-right:8px"></div>');
               $sharedSecretBlock = element.find(".sharedSecret");
            var qrQata = "otpauth://totp/" + encodeURIComponent(app.getName(app)) + "?secret=" + encodeURIComponent(app.getSharedSecret(app));
            $sharedSecretBlock.html('<a href="' + encodeURIComponent(qrQata) + '" target="_blank">Show Secret QR</a>');
            } catch(err) {
    return _results

I noticed TokensView.prototype.updateTokens is only called after the tokens expire, so at most 30 seconds after you decrypted your data by entering your password, but eh, good enough.

So, if you want to do that too, you can try to do the changes I detailed above, or just replace your gaedmjdfmmahhbjefcbgaolhhanlaolb/js/app.js with my version (based on version 1.2 of their Chrome app), and wait between 0 and 30 seconds to see the links appear:


Click them one by one, scan them with your new client, and voilà! You’re ready to rock two-factor logins on your new device.

Of note: CloudFlare doesn’t show a QR code in my screenshot above because it uses “Authy two-factor authentication”, which is not compatible with Google Authenticator.  There’s just no point in exporting those out of Authy, since they are not usable anywhere else…

RSS-For-Later: Replace Google Reader with Pocket

Google Reader is going away later this year. This means those of us using RSS to keep in touch with the world will need to find an alternative to be able to get our fix using our different devices.

I still remember the pre-Google Reader days of RSS, when RSS clients were silos that talked to nobody. This meant that trying to read articles on a PDA (Palm Zire anyone?), and on a PC, forced us to skip a bunch of articles each time we switched from one to the other…
Solutions for this problem existed at the time, but were convoluted, and not that pleasant. i.e. I don’t want to go back there!

This morning, I read a post by Ruth John, aka @Rumyra, about how she used IFTTT (If-This-Then-That) to inject the content of a RSS feed into the Pocket read-it-later service. This stuck me as a good idea, so I started with a Yahoo Pipe that took my OPML, and merged all articles into one feed, and I inputed that into IFTTT, and chose Pocket as the target. Sadly, that didn’t work so well; IFTTT has known issues with Yahoo Pipes RSS feeds. Next option: just do it myself!

A couple hours later, I now have a working web-app that I used  to import my list of feeds (in OPML format), that I can use to manage my feeds list, and that will automatically post new articles to my Pocket account. It even works with the existing RSS Subscription Extension (by Google), so I can easily subscribe to new feeds too.

Interested? Try it yourself at


1. Enter your email address to create an account. The email address is not really used for anything right now; it’s just a way to link an account to a real person.
You will receive a secret URL that you will need to bookmark, as this will be the only way for you to manage your feeds later.

2. Import your OPML (exported from Google Takeout, or any other RSS client), or manually add new feeds.

3. Click “Connect to Pocket” to authorize RSS-For-Later to send new articles to your Pocket account.

4. There are no step 4. :) Just wait for new articles to start appearing in your Pocket account.


RSS-For-Later is now available on Github, for anyone to install on his own server/host, or to improve (submit pull requests).

Suggestions & comments are welcome.

How to run a super-fast Android emulator with Intel x86 system images

Note: I did this on my MacBook Pro, and saw a major difference between the x86 emulator, and the old ARM emulator. I guess I should thank the CPU my MacBook uses, which supports Intel® HAXM*. If yours doesn’t, you’re out of luck!
* Intel® HAXM requires an Intel® processor with support for Intel® VT-x, Intel® EM64T (Intel® 64), and Execute Disable (XD) Bit functionality.


  1. Install Intel® HAXM
  2. In Eclipse (or not), run the Android SDK Manager, and install the latest “Intel x86 Atom System Image”. The latest one I see right now is in the Android 4.2.2 (API 17) section.
    There’s also images for 4.1, 4.0 and 2.3 if you want to run those emulators.
    Also, you might already have it installed.
  3. Next, start the Android Virtual Device (AVD) Manager, and either create a new AVD, or edit an existing one.
  4. Choose a Target for one of the Intel system image you downloaded. The CPU/ABI field will allow you to select “Intel Atom (x86)”. Yay!
  5. In the Emulation Options section, select the Use Host GPU option.

Step 6 is to marvel at the speed at which your AVDs now run!

Flickr interesting or groups photos on your (jailbroken) Apple TV screensaver

Update: My server’s IP address changed recently, so you’ll need to change the IP address in your Apple TV’ /etc/hosts for this to continue working. The new IP is: You can do this with:

ssh [email protected] 'cat /etc/hosts | grep -v > /etc/hosts2 ; echo "" >> /etc/hosts2 ; mv -f /etc/hosts2 /etc/hosts'

Note: The default password for root is alpine.

Original post follows.

Since I replaced my Apple TV 1 with an Apple TV 2, and started using Flickr as the screensaver, I was wondering how I could use group photos or interesting photos from Flickr, instead of just a user’s photos, or the result of a search.
Today, I was able to hack it to do what I want!

(Note: You need a jailbroken Apple TV for this to work.)

I was able to find other workarounds, but none seemed to do what I really wanted, or they were simply not good ideas in the long run.

To do what I wanted, I forwarded all requests intended for, which the Apple TV uses for the Flickr screensaver, to my own server. The simple PHP script I created to receive those requests then checks if the request is a search, and if so, if it contains specific strings, namely group:some group name or explore:. If it does, it will use the Flickr API to do a group search for some group name, and will return the photos of the first group found, or it will return photos from the Explore section, respectively. All other requests are simply forwarded to the Flickr API as-is.

Bonus: The Apple TV tries to load 100 pictures; my script returns 500! Less chance of seeing the same photos twice like this. :)

Second bonus: It’s actually quite easy to return pictures from any other website like this, so my script could be easily modified to return photos from a Gallery3 website, or another photo site that has an API, or whatever.


To use it yourself, the only thing you need is to force all requests to to go though my server:

ssh [email protected] 'echo "" >> /etc/hosts'

Note: The default password for root is alpine.

To use a group photos for your screensaver, enter group:some group name in the search option.
You’ll want to make sure the some group name you use returns the group you want to use as the first search result in the groups search on Flickr.

To use the Explore/Interesting photos, enter explore: in the search option.

[Updated] Phone Power in Canada: awesome features set, so-so routing & support

Last year, I took the plunge and switched from a big local telephony provider to a web-based VoIP provider: Phone Power.
Their features set is quite something: free second line, voicemails to email, some free international minutes, etc.
But, when it comes to routing local calls, they are so-so.

I live in Montreal, Quebec, Canada. Many local agencies & companies have 1-800 numbers that are geolocation-locked; you can’t call those numbers from outside Canada, or outside Quebec (depending). How they detect the origin of the call is not based on the caller ID (the caller’s phone number); it has to do with how the call is routed, i.e. where it’s coming from for real.

Now, the problem is not that Phone Power isn’t technically capable of routing those calls correctly, since I have been able to call those numbers on multiple occasions. The problem is that they are unable to keep routing consistent. The result is that those calls will only work sometimes, and will sometimes fail. And, when it’s not working, and you call/chat support to fix it, they don’t know how to resolve the situation. Sometimes, after 20-30 minutes of back and forth, they are able to make those calls go through. Other times, they can’t fix it, and answer that they’ll investigate further, and contact me later when they found something.

Here’s a timeline of my (10+) contacts with support regarding this:

Me: I can’t connect to the following number: 1-800-361-3977 Would it help if my voip phone number was a canadian phone number maybe ?
Support: Possibly. Likely. Though you’d need to speak with billing for the logistics of that.

Me: Trying to dial [a 1-866 number], it’s telling me that number can’t be reached from my calling area.
Support: Basically i tried forcing the call through all of the providers i have available to me and i get the same message from them all. Call the bank and see if they allow inbound calls from outside canada.

Me: Michael called me today regarding a problem I’m having with 1-866 numbers.
Support (after 1+ hour of back and forth): Can you dial one more time plaese?
Me: yes, it’s ringing! Bingo!!
Support We will be calling you back because we do not want this issue to happen to you or an other customer. I will currently leave it on for now. They might be changing it to test it on our end.

Support: This is a follow up email regarding the ticket you recently opened with us about dialing toll free numbers in Canada. While we do bill calls to Canada at a domestic rate, the call features recognize Canadian numbers as International in nature (as we are an American based company). So with International dialing blocked, it would not permit you to call such numbers.
Me: […] it seems like it only partially block Canadian numbers… Because I can call local Canadian numbers without a problem with the setting On. It only prevents me from being able to call some Canadian 1-800 numbers…

Me: Returning the call from Dude. He asked to call back if my 1-866 calls failed again. They do. it worked fine at the end of the chat session on the 27th, but now they are failing again.
Support: Please try calling again and let me know what happens now.
Me: It’s working. All of them seems to work again now.
Support: We are still going to need to work on this issue to get it fully resolved. We will contact you once we have an update.

Me: “The number you have dial has not been recognized.”; different error message than earlier today.
Support: [We need to trace the call; can you dial the number again?]
Me: [No, my wife needs the phone now. I’ll call back again when the phone if unused.]

Me: Some 1-866 local numbers can’t be reached again.
Support: Ok, lets go again.
Me: working now.

Support: We tried to reach you in regards to the problem or service issue you reported on your Phone Power account, but had no success. If you are still experiencing the problem or issue, please reply to this email, or contact us at 888-607-6937 (option 3) in the next 24 hours.
Me: It’s working fine at this time.

Me: Since I last wrote to you about this on November 16, 2011, when all was working fine, some 1-800 number are not working again.
Support: …
Me: if you can’t fix it like that, just make it so all my calls are routed like they were on Nov. 16 and leave it at that.
Support: I have already tested that and it did not work either. I will look into this more and contact you later.

Me: What’s the update on this ? Last contact was on December 5: “I will look into this more and contact you later.”
Me: (7 hours later) Official complain email sent to [email protected], with instructions to forward to the appropriate person, since there is no other contact information on their website.
No response whatsoever.

Support: This is a follow up email regarding the ticket you recently opened with us about your outbound calls to toll free numbers, we attempted to reach you however were not successful. We have removed the test route, please re-test and let us know if problem still exist.
Me: 1-800 / 1-866 calls are failing again.

Update: Someone from PP called last week. He sounded like someone who cares about the image of the company; maybe he was the director of operations or something. Anyway, he told me that my problem should now be resolved for good, and that he was really sorry about the time it took them to resolve this issue. Things are working fine right now. Let’s hope it stays that way.

Update 2: I switched to since my contract with PhonePower expired. Pretty happy so far. It probably costs me a few more cents a month, but I’m happy with it so far.

[Updated] How to monitor the Apple Store for available refurbished items using cron

So, you’d like to buy a refurbished product from the Apple Store, but it’s currently Out of Stock. And will probably be for a while, and when it’s not anymore, the few units available will be gone in minutes.
So you need a way to be notified ASAP when it’s available, so you can have a chance to order it.

Here’s a simple way using cron.

1. Get the product URL from the Apple Store Refurbished page.
You can find it on Google by searching for: country refurbished product name

Example: canada refurbished Apple TV

The product URL for an Apple TV (2nd gen) in Canada is:

2. Under the price, on the right, you should see “Available: Out of stock” (or the equivalent localized in your language).

3. Create a cron to look for “Out of stock” (or the equivalent localized in your language), and email you when that string can’t be found on the product page.


* * * * * if [ "`curl -s "" | grep "Out of stock" | wc -l`" != "1" ]; then echo "" | mail -s "Your Refurbished Apple product is now available!" [email protected]; fi

Just change the product URL twice in the above, and change the email address, and you’ll receive an email within one minute of your product being available.

If you don’t have an always open Mac/Linux server that can send emails, to run this cron on, just send me your email address and the product URL you’d like to monitor. I’ll be happy to hook you up. Update: Just go to if you’d like to be notified of refurbished Apple products availability. It’s a little something I threw together that uses the above technique.

Show/Hide DesktopShelves using a Hot Corner

Here’s how I setup a Hot Corner to show or hide my DesktopShelves.

(Note that this trick can also be used to launch any program or AppleScript using a Hot Corner.)

The magic lies in a nice piece of software written by Matt Swann: ScriptSaver

This screen saver will in fact execute any AppleScript you specify instead (or before) launching a screen saver.

Here’s step-by-step instructions for how to use it to show & hide your DesktopShelves:

  • Download ScriptSaver
  • Download the AppleScript I created: ActivateDesktopShelves.scpt or, if you’d like to use the iPhoto screen saver instead of the standard ones (Arabesque, Flurry, …), use this script instead: ActivateDesktopShelves-iPhotoScreenSaver.scpt
  • Download MouseLocation* using (Just paste the complete line below in Terminal.)
    curl -so /tmp/ ; unzip /tmp/ ; sudo mv MouseLocation /usr/local/opt/
  • Extract the AppleScript from the above download, and put the .scpt file in ~/Applications (or anywhere really!)
  • If you’ll be using ActivateDesktopShelves.scpt, open it in AppleScript Editor (just double-click it) and change the 2nd line from the bottom to start your preferred screen saver. The default is “Flurry”, and the list of available screen savers appears just above that line. Save it once you’re done.
  • If you’ll be using ActivateDesktopShelves-iPhotoScreenSaver.scpt instead, there’s two additional steps:
    • Go in System Preferences, and select the iPhoto screen saver. Chooses the options you’d like to use.
    • In Terminal, create a copy of the screen saver preferences file. (Just paste the following 3 lines in Terminal.)
      uuid=`/usr/sbin/system_profiler SPHardwareDataType | grep 'Hardware UUID' | cut -c22-57`
      cp $file $file.iPhoto

  • Install ScriptSaver: double click the ScriptSaver.saver file
  • Click Options…
    • Activation Script: select the .scpt file you downloaded above (in ~/Applications)
    • Run asynchronously: checked
    • Screen Saver: None
    • Deactivation Script: empty
    • Show desktop while synchronous scripts execute: checked
  • Click Hot Corners… Assign one or more Hot Corner to Start Screen Saver.

The AppleScript will detect if the mouse is in a corner, and if so, will launch, which will in turn display your shelves.

If the mouse isn’t in a corner, then your screen saver will start.

Voilà! A nice way to start any app using a Hot Corner, and a nice way to use DesktopShelves only with your mouse.


* MouseLocation is a simple Objective-C executable created using the following code:

#import <AppKit/AppKit.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSPoint mouseLoc = [NSEvent mouseLocation]; //get current mouse position
NSString* locString = [NSString stringWithFormat:@"%.0f, %.0f", mouseLoc.x, mouseLoc.y];
printf("%s\n", [locString UTF8String]);

[pool drain];
return 0;

Compiled using the following command (Xcode required):

sudo gcc -o /usr/local/opt/MouseLocation MouseLocation.m -framework AppKit

Start iPhoto screen saver from AppleScript

Starting the screen saver from AppleScript is simple enough:

tell application "System Events" to start current screen saver

Even starting another screen saver than the default from System Preferences is simple, if you want one of the standard screen saver:

tell application "System Events" to tell screen saver "Arabesque" to start

But it becomes much more complicated if you’d like to start the iPhoto screen saver, and use another as the System Preferences default.
Here’s how I did it:

  • Go in System Preferences, and select the iPhoto screen saver. Chooses the options you’d like to use.
  • In Terminal, create a copy of the screen saver preferences file:
    uuid=`/usr/sbin/system_profiler SPHardwareDataType | grep 'Hardware UUID' | cut -c22-57`
    cp $file $file.iPhoto

  • Go back in System Preferences, and change the screen saver to the other screen saver you’d like to use as your default.

Once you did all that, here’s how to start the iPhoto screen saver from AppleScript:

tell application "System Events"
set uuid to do shell script ("/usr/sbin/system_profiler SPHardwareDataType | grep 'Hardware UUID' | cut -c22-57")
set theFolder to folder (preferences folder's path & "ByHost")
set theFile to "" & uuid & ".plist"
do shell script "cd " & POSIX path of theFolder & "; cp " & theFile & " " & theFile & ".orig; cp " & theFile & ".iPhoto " & theFile
start current screen saver
do shell script "sleep 5; cd " & POSIX path of theFolder & "; cp " & theFile & ".orig " & theFile
end tell


  • line 2: find the machine’s UUID; this is needed because the screen saver preferences file contains that in it’s name;
  • line 3: the folder where the preferences file is: ~/Library/Preferences/ByHost/;
  • line 4: the name of the preferences file:[UUID].plist;
  • line 5: create a .orig backup of the current preferences file, and then overwrite it with the iPhoto copy that was created manually above;
  • line 6: start the iPhoto screen saver;
  • line 7: wait 5 seconds, to allow the iPhoto screen saver some time to launch, then put back the .orig backup we made at line 5, so that your default screen saver will be used when it’s time.

Convoluted? Yes. Achieves the desired result? You bet!

I did this because I wanted to show the iPhoto screen saver when an AppleScript triggered by ScriptSaver was executed. More details in Show/Hide DesktopShelves using a Hot Corner.

Has Gmail spam filter become too aggressive?

I’m not sure if I’m the only one who noticed (I hope not!), but recently, the Gmail spam filter started marking as spam a lot of messages that were NOT spam.

Here’s the ones I found, while looking at only the first two pages of my Spam folder (about two days worth of spams):

  • A shipment notification;
  • My monthly Yak invoice;
  • My monthly ‘your invoice is ready’ from Citibank;
  • The OpenDNS newsletter;
  • Two commit notifications from Google Code;
  • Three ‘your password has been reset’ emails, from, and other less known bulletin boards.

This makes me sad for multiple reasons. One is that while I have been able to catch some of them easily enough (the various reset password systems I used did point out that their email could end up in our Spam folders), I just found the others. That means I probably missed at least some other emails.

The second reason I’m sad is that now, I’ll need to go through all those spam messages to find the ones I care about! Not something I expected to do this morning, nor something that is particularly pleasant… Plus, I’ll need to repeat that every day now!

And finally, this make me sad because I trusted the Gmail team. I understand that spam filtering is not simple, but I would have greatly preferred for them to tweak their algorithm to push the balance in the other direction. It’s much easier for us to flag the occasional spam emails that would end up in our inboxes than to have to go through thousands of emails to find important messages!

Let’s hope the Gmail-Spam-Filter team hears this, and works toward a good resolution in a timely fashion.

What about you? How many not-spam messages can you find in your Gmail Spam folder in the next few minutes?