What is a JSON feed? Learn more

JSON Feed Viewer

Browse through the showcased feeds, or enter a feed URL below.

Now supporting RSS and Atom feeds thanks to Andrew Chilton's feed2json.org service



A software development team that specializes in Security, Identity Management, Mobile, and Web Development


Codebook for macOS adds support for Little Snitch network monitoring

Permalink - Posted on 2019-02-20 15:00

The latest point release update of Codebook for macOS, version 3.7.4, is mostly a well-rounded bugfix release. However, it includes some new resources for our customers who use the popular Little Snitch network monitoring and defense app.

Little Snitch monitors a Mac’s network connections, and when run in Alert mode it will prompt the user about a new network connection with a handy dialog for approving or denying it, and for creating custom and dynamic firewall rules for the future.

Normally, there’s not much Little Snitch can tell you about a particular process’s intent when attempting to access the network. There’s a lot it can tell you, but little information from the app or process itself. However, if an app is properly code-signed, and includes an Internet Access Policy file, the app can describe the various types of network requests it makes and why. That information is then made available in Little Snitch’s connection alert dialogs. An application can even include links, for instance to helpful documentation!

Here’s an alert from Little Snitch in response to Codebook’s Password Review feature:

Little Snitch alert for Codebook

If we click on the bifocals icon to reveal the Research Assistant, we see detailed information about what’s going on, from Codebook:

Little Snitch Research View

If the user clicks on the Deny button, they are presented with a quick heads-up on what will happen:

Little Snitch Deny confirmation popup

Here’s what happens when Little Snitch intercepts Codebook’s stats feature:

Little Snitch alert for Codebook stats

All in all, a simple and handy integration from Objective Development that should be quite useful to those of our customers who also use Little Snitch.

Saying Goodbye to Codebook Lite and Codebook for iPad

Permalink - Posted on 2019-01-28 17:14

Having arrived at the end of a process begun a little while ago now, we’ve removed Codebook Lite and Codebook for iPad from the iTunes App Store. Now there’s only one version of Codebook for iOS available, a universal app for iPhone and iPad that offers a 14-day free trial.

These companion apps served us well over the years. It was more than a decade ago—2008—that we first released our password manager Codebook (then called STRIP) for iOS (then called iPhoneOS) in the App Store. At the time it was stand-alone, only supported iPhone, and required an upfront purchase to download and run (and would stay that way for a long time).

We wanted a way to allow people to try it for free, but In-App Purchases weren’t a thing yet and trials weren’t allowed in the App Store so we did what seemed the next best thing: we created the Lite version as a separate, free-to-download app limited to ten records and no Sync feature.

The Lite approach has its limitations! Offering a clear migration path to the paid version (we did this pretty well I think), difficulty if not outright inability to track conversions from free to paid, and the limitations themselves that prevented the customer from really trying out the app realistically and on more than one platform.

Then there’s the extra work to make sure this second application target is always as up to date as the full version, with every new version of iOS, any bug fixes, and any new features. To be sure, most of the code is shared, but this additional version needed to be maintained and tested and managed in the App Store.

When the iPad arrived on the scene, developers had a choice: build a separate app targeted at the iPad only, or adapt your existing iPhone app to handle both as a universal app. At the time, it seemed like the fastest and easiest way to get Codebook going on the iPad was to go the separate app route.

So now we had a third app, with all the attendant effort required as described before regarding the Lite version! Prior to the modern automation of code signing in Xcode this created some serious challenges to getting everything built and signed properly.

A few years back we began the work of whittling this down. We adapted the main iPhone version to be a universal app supporting iPhone and iPad, and began to let customers of the iPad-only version know that it would be eventually discontinued in favor of the universal version.

Fast-forward a couple years to recent changes in how Apple allows In-App Purchases to be used, and we were finally able to offer a free trial in the main, universal version of Codebook for iOS, and last year we jumped on it.

All this is a long way of saying it feels good to say goodbye to Codebook Lite and Codebook for iPad: we’ve come a long way with Codebook for iOS! And we’re in great shape for what’s to come. All of us here at Zetetic have been working hard on Codebook 4, now the primary focus of Codebook development. It’s a big upgrade to Codebook’s security and sync features, so we’ll be doing extensive testing, and looking for more beta testers. If you’d like to become a beta tester and help us make sure we’ve got Codebook 4 just right, please email us at support@zetetic.net and let us know!

SQLCipher 4.0.1 Release

Permalink - Posted on 2018-12-18 12:00

SQLCipher 4.0.1 is now available. This update to SQLCipher 4 includes several very important changes:

  • Based on upstream SQLite 3.26.0, which addresses the SQLite “Magellan” vulnerability
  • Adds PRAGMA cipher_compatibility and PRAGMA cipher_default_compatibility which simplify configuration of appropriate compatibility settings for different major SQLCipher versions
  • Filters out ATTACH statements which contain KEY parameters from readline history when using the command line shell
  • Fixes a crash in the command line shell when it is provided empty input (e.g. ^D)
  • Fixes various compiler warnings related to strict-prototypes

The Magellan Vulnerability

The SQLite Magellan issue is a remote code execution vulnerability. Discovered by Tencent Blade Team, this problem can potentially affect applications that use SQLite versions prior to 3.26.0. By extension, because SQLCipher is based on SQLite, this issue can also affect applications that use SQLCipher versions prior to this release of 4.0.1.

The scope of the vulnerability is such that it could be used to exploit applications that:

  1. Allow a potential attacker to execute arbitrary SQL; or
  2. Open untrusted databases (i.e. that could be specifically corrupted by an attacker)

Due to the potential severity of this issue, we strongly recommend that all applications upgrade to SQLCipher 4.0.1, especially if they meet the aforementioned criteria.


As with the recent SQLCipher 4.0.0 release, 4.0.1 contains changes that are not directly compatible with SQLCipher 3.x (or lower). These provide a much higher level of security than previous versions of SQLCipher, however, SQLCipher 4.x will not open older databases by default (i.e. those created by SQLCipher 3.x or lower). To enable backwards-compatibility, applications can easily adjust settings at runtime or migrate older databases:

  • To migrate and upgrade an existing database in place (preserving data and schema) to use the new default settings, use PRAGMA cipher_migrate.
  • To open an older database use the compatibility PRAGMAs to adjust settings back to their previous values. For example, to open a SQLCipher 3 database using SQLCipher 4, use the following statement after opening and keying the database: PRAGMA cipher_compatibility = 3;.
  • To attach and export data to a new database with fine-grained control, use the sqlcipher_export() convenience function.

Please review this additional guidance for detailed upgrade and migration scenarios. We have also published a migration guide for Commercial and Enterprise customers upgrading to SQLCipher 4.x using the SQLite-net API.


Commercial Edition - On-demand access to new releases of SQLCipher Commercial Edition are available to licensees with an active CipherCare subscriber subscription, along with private, prioritized support directly from Zetetic. CipherCare subscribers will receive a separate email notification regarding the update and can contact us to request the latest SQLCipher distribution and applicable software license codes.

SQLCipher Enterprise Program - Enterprise Program Subscription customers will receive a separate email notification about the release, and the latest SQLCipher packages and license codes will be provided directly via your organization’s private online software delivery share.

Community Edition - SQLCipher 4.0.1 in source format is directly available on GitHub. The Community Edition of SQLCipher for Android is available via AAR packaging. The Community Edition of SQLCipher for iOS can be compiled from source or using CocoaPods.

SQLCipher 4.0.0 Release

Permalink - Posted on 2018-11-30 12:00

We are incredibly excited to announce the much anticipated release of SQLCipher 4. This is a major update that includes new features, improvements, and fixes. Here are some of the most important highlights:

  • PBKDF2-HMAC-SHA512 is the new KDF algorithm
  • HMAC-SHA512 is now used for per-page HMACs
  • The default database page size has been increased to 4096 bytes
  • KDF iteration count has been increased to 256,000
  • Improved memory sanitization features
  • Significant performance improvements for common use cases on platforms including iOS, Android, and Windows
  • New baseline on upstream 3.25.2 enabling many new SQLite features
  • Completely revamped client API support for .NET based platforms including sqlite-net, Entity Framework, and Microsoft ADO.NET

The full list of changes in the release can be found below. Note that changes indicated by a * are high impact and will impact compatibility with prior version of SQLCipher!

SQLCipher Core

  • Default page size for databases increased to 4096 bytes (up from 1024) *
  • Default PBKDF2 iterations increased to 256,000 (up from 64,000) *
  • Default KDF algorithm is now PBKDF2-HMAC-SHA512 (from PBKDF2-HMAC-SHA1) *
  • Default HMAC algorithm is now HMAC-SHA512 (from HMAC-SHA1) *
  • PRAGMA cipher is now disabled and no longer supported (after multi-year deprecation) *
  • PRAGMA rekey_cipher is now disabled and no longer supported *
  • PRAGMA rekey_kdf_iter is now disabled and no longer supported *
  • By default all memory allocated internally by SQLite before the memory is wiped before it is freed
  • PRAGMA cipher_memory_security: allows full memory wiping to be disabled for performance when the feature is not required
  • PRAGMA cipher_kdf_algorithm, cipher_default_kdf_algorithm to control KDF algorithm selection between PBKDF2-HMAC-SHA1, PBKDF2-HMAC-SHA256 and PBKDF2-HMAC-SHA512
  • PRAGMA cipher_hmac_algorithm, cipher_default_hmac_algorithm to control HMAC algorithm selection between HMAC-SHA1, HMAC-SHA256 and PBKDF2-HMAC-SHA512
  • Based on upstream SQLite 3.25.2
  • When compiled with readline support, PRAGMA key and rekey lines will no longer be saved to history
  • Adds second optional parameter to sqlcipher_export to specify source database to support bidirectional exports
  • Fixes compatibility with LibreSSL 2.7.0+
  • Fixes compatibility with OpenSSL 1.1.x
  • Simplified and improved performance for PRAGMA cipher_migrate when migrating older database versions
  • Refactoring of SQLCipher tests into separate files by test type
  • PRAGMA cipher_plaintext_header_size and cipher_default_plaintext_header_size: allocates a portion of the database header which will not be encrypted to allow identification as a SQLite database
  • PRAGMA cipher_salt: retrieve or set the salt value for the database
  • Adds Podspec for using tagged versions of SQLCipher
  • Define SQLCIPHER_PROFILE_USE_FOPEN for WinXP support
  • Improved error handling for cryptographic providers
  • Improved memory handling for PRAGMA commands that return values
  • Improved version reporting to assist with identification of distribution
  • Major rewrite and simplification of internal codec and pager extension
  • Fixes compilation with –disable-amalgamation
  • Removes sqlcipher.xcodeproj build support

SQLCipher for Android

  • Substantial improvements to cursor access performance due to new loading heuristics
  • Define custom cursor allocation sizes for paging query results, including initial, growth size, and maximum memory allocations
  • Option to disable loading heuristic via setFillWindowForwardOnly on SQLiteCursor instance
  • JNI CursorWindow caching of chunk pointer offsets to minimize linked list traversal
  • Query total data size, and largest individual row in bytes based on provided query
  • WAL mode API to enable, disable, and check if enabled
  • Add API to get list of attached databases
  • Add API to perform integrity check of the database
  • Add API to enable, or disable foreign key constraints
  • Improvements to begin transactions to allow for immediate and exclusive modes
  • SQLiteOpenHelper supports onConfigure and onDowngrade callbacks
  • SQLiteOpenHelper exposes the database name, and current WAL mode
  • Improve exceptions thrown within JNI layer
  • SQLCipher for Android target SDK set to 26
  • Add support for AboutLibraries

SQLCipher for iOS

  • To allow the use of WAL mode databases in shared containers use PRAGMA cipher_plaintext_header_size and cipher_default_plaintext_header_size to allocate a portion of the database header which will not be encrypted to allow identification as a SQLite database.
  • Major (2x or more) performance improvements with hardware acceleration on 4K page size databases
  • Removes support for sqlcipher.xcodeproj integration method for Community Edition*

SQLCipher for .NET, Xamarin, and Windows

  • Client APIs now support a new sqlite-net compatible package based on the official praeclarum/sqlite-net library (was previously based on SQLite.Net-PCL) *
  • Adds support for Microsoft Entity Framework via Microsoft.EntityFrameworkCore.Sqlite.Core 2.x
  • Adds support for Microsoft’s ADO.NET implementation via Microsoft.Data.Sqlite.Core 2.x
  • Substantial performance enhancements for Windows UAP and Runtime packages (up to 50%+ improvement under certain tests)
  • Updates to all cryptographic support libraries including OpenSSL 1.1.1, OpenSSL 1.0.2p, OpenSSL FIPS 2.0.16, and LibTomCrypt 1.18.2
  • Windows Phone is no longer supported due to the product end of life

Note: .NET, Windows and Xamarin packages are available exclusively via Commercial Edition packages and under the SQLCipher Enterprise Program.


Many of these changes provide a much higher level of security than previous versions of SQLCipher. However, the new page size of 4096, 256,000 KDF iterations, use of PBKDF2-HMAC-SHA512 and HMAC-SHA512 all modify important database settings. Thus, SQLCipher 4 will not open older databases by default. As always, we have updated our migration feature to streamline the upgrade process. To enable backwards-compatibility, it is possible to adjust settings at runtime or migrate older databases:

  • To migrate and upgrade an existing database in place (preserving data and schema), use the new default settings, use PRAGMA cipher_migrate.
  • To open an older database used pragmas to adjust settings back to their previous values. For example, to open a SQLCipher 3 database using SQLCipher 4, you could use the following statements after opening and keying the database: PRAGMA cipher_page_size = 1024; PRAGMA kdf_iter = 64000; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;
  • To attach and export data to a new database, use the sqlcipher_export() convenience function. This would let you control migration using very specific or custom settings.


Commercial Edition - On-demand access to new releases of SQLCipher Commercial Edition are available to licensees with an active CipherCare subscriber subscription, along with private, prioritized support directly from Zetetic. CipherCare subscribers will receive a separate email notification regarding the update and can contact us to request the latest SQLCipher distribution and applicable software license codes.

SQLCipher Enterprise Program - Enterprise Program Subscription customers will receive a separate email notification about the release, and the latest SQLCipher packages and license codes will be provided directly via your organization’s private online software delivery share.

Community Edition - SQLCipher 4.0.0 in source format is directly available on GitHub. The Community Edition of SQLCipher for Android is available via AAR packaging. The Community Edition of SQLCipher for iOS can be compiled from source or using CocoaPods.

Additional Details

Over the coming weeks we will be posting more detailed blog posts that elaborate on specific features and improvements that have been made with the latest SQLCipher release.

Codebook Free Trials Replaces Codebook Lite

Permalink - Posted on 2018-11-01 12:00

Codebook Lite was originally introduced alongside Codebook to allow users a free option to try Codebook for iOS before they purchased. Now with the release of Codebook 3.6.0 we’ve introduced a 14-Day Free Trial option within Codebook. Because this functionality is now built into Codebook, we’re planning on discontinuing Codebook Lite development, so we can focus all our ongoing efforts on standard Codebook.

Similarly, standard Codebook has been a universal app (which works on both iPhone and iPad) now for a while and we’ve been phasing out Codebook for iPad (Legacy) for about a year, so we’re planning on pulling the plug at the same time as Codebook Lite.

Codebook Lite and Codebook for iPad Legacy will be fully removed from the App Store on January 1st, 2019. Please make sure to migrate your data to Codebook prior to this date or data loss could occur.

Migration Steps

Codebook Lite

Codebook for iPad Legacy

  1. Download the Codebook universal app
  2. Use the Codebook sync feature to sync your data from Codebook for iPad Legacy to a cloud service or a Desktop copy of Codebook.
  3. During the setup process for Codebook, you’ll be given the opportunity to use the sync feature to restore from the service or Desktop you synced with in step 2
  4. Once you’ve verified the data from Codebook for iPad legacy synced over to the new Codebook for iOS installation, feel free to delete the Codebook for iPad Legacy app

Codebook Password AutoFill and Free Trials on iOS

Permalink - Posted on 2018-09-19 00:00

Big news, folks! Codebook for iOS version 3.6.0 is available now in the App Store with support for the AutoFill Passwords feature in iOS 12. Here’s a quick demo video we made to show you how it works.

This feature requires iOS 12; if you can’t upgrade your version of iOS just yet check out Find in Codebook, which is quite similar if not as convenient.

Another big change in this version is that we are making Codebook free to download. Don’t freak out, we are not switching to a “freemium” model! Instead, Codebook will be free to try before you buy, and everyone who’s already bought the app is grandfathered in.

Until now Codebook for iOS has been available for an up-front, one time purchase of $9.99. Starting with the version 3.6.0, we’ll be making the app free to download, and free to use for two weeks, after which an In-App Purchase of Codebook Pro is required to unlock the editing and sync capabilities. Codebook Pro is a one-time purchase of $9.99, additional purchases are not required to use it with more than one device as long as you are using the same Apple ID in the App Store.

If you purchased Codebook for iOS before version 3.6.0, you are exempt from our use of In-App Purchases, because you paid up-front for the app, sight unseen, cash on the barrel, without even being able to try it first! We remain deeply grateful for your support. You will not be prompted to make an In-App Purchase, but you can see your grandfathered license status on the Settings view.

There are a few other minor changes to round out this release posted over on our discussion forum. Drop on by and let us know what you think!

Codebook Search Scopes

Permalink - Posted on 2018-04-24 15:00

The recent releases of Codebook for Windows and Codebook for macOS include a new search scope feature. Previously, searching within Codebook compared the search value against Entry names and Field values, which works great if you’re quickly trying to locate a record or specific data (i.e. Amazon, Chase Visa, records with a specific email address etc.).

We’ve run into situations ourselves and had users ask about searching over specific Label names as well (i.e. any record that has a “Password” label, or “Email” label). Some common usage scenarios we’ve come across related to this are:

  1. Your bank issues you a new card and you need to replace all records that contain the old credit card number (Search over “Credit Card” Label).
  2. You’re searching for data that you may not know the value of but you know the label name for (i.e. SSN, Bank Account #, License keys, Secret Question)

Codebook Search Scope from Zetetic on Vimeo.

The search scope feature also allows you to search over just Entry names or Field values (without having to search over both). For example, maybe you have an Entry named “Mike Gmail Account”, but you have many other entries that have email field values that contain your email address “mikemalibu@zetetic.net”, if you search for “mike” it will return every single entry that contains your email, along with the actual one you’re searching for “Mike Gmail Account”. But if you only check “Entries” under search scope, it will only search for entries that contain “mike” in the entry name.

Report from Teki Con

Permalink - Posted on 2018-03-22 11:00

Last week two of our developers, Micah Moore and Billy Gray, attended Teki Con, a three-day, single-track iOS development conference in Atlanta, Georgia hosted by Catamaran, LLC. Getting into WWDC can be tough these days so we’ve had our eye out for a focused and advanced discussion of iOS development and we sure got it! Among the speakers were a number of developers we already follow, and some seriously big names discussing application architecture and code design (did you know MVC stands for “Massive View Controller”? 😜). There were also quite a few speaking who were new to us and taught us a lot. Every session was fantastic, whether it was on the trials and travails of running a viral app, category theory (“a monad is just a monoid in the category of endofunctors”), accessibility, developer tools and debugging, or philosophy and approaches to common development patterns.

The tiki theme of the event wasn’t just a name—it kicked off with a wonderful hula dance performance and Mike Lee’s talk, “We’re Doing It Wrong,” which was chockfull of interesting facts about Hawai’i and how its culture evolved over time in his discussion of how we can better approach our work and the world around us.

Many of the speakers, including Michael Ayers, Krzysztof Zabłocki, and Dave DeLong (yep, a UIKit engineer!) focused on app architecture, in particular on coordinators and composition, as well as diving into how to use either delegation or dependency injection to keep an app true to its design pattern, whether that’s MVC or MVVM.

Among the more elucidating observations was perhaps the nut of Dave DeLong’s talk:

UIViewController is not a controller, it’s a view!”

He put this gif up on his slide right then, it ably demonstrates the profound affect this had on us. The name of this UIKit component has tended to suggest we use it in a way we should not, and over the years the documentation from Apple has also suggested it, creating a perceived conflict between what’s being advised and staying faithful to an MVC or MVVM design pattern. This perspective frees us from some concerns that have made us wary of experimentation.

The third day of the conference was set aside for labs, two awesome workshops run by Big Nerd Ranch. We had the choice between labs on advanced auto layout and advanced iOS performance; we chose the latter as it was of particular interest for some new things we are looking into. The lab was an abbreviated form of BNR’s day-long training classes on the same topic, and included a course book in PDF form along with before-and-after Xcode projects for each of the problems we worked on. The course instructors did a great job taking us though advanced uses of operation queues, Grand Central Dispatch, and layer transformations and animations. It was a bit of a crash course for both of us in Swift (we’re still new to the language, we seemed to be among the few primarily obj-c attendees who understand retain/release and what a zombie object is!) but it was quite a lot of fun and pretty easy for us to follow along.

Long story short: we highly recommend attending Teki Con assuming they hold it again next year! Kudos to Jonathan Crockett and Stephen Elliot for putting together such a great speaker line-up and conference.

SQLCipher 3.4.2 Release

Permalink - Posted on 2017-12-22 12:00

We are happy to announce SQLCipher 3.4.2 has been released. This release includes integration of the upstream SQLite release 3.20.1. Along with the many improvements included in SQLite, several of our client libraries included some nice additions with this release.

More details and instructions for accessing the latest version can be found in our official release announcement here.

Updated Icons for Codebook

Permalink - Posted on 2017-12-20 12:00

We’ve got some exciting news for customers of our password manager Codebook, just in time for the end-of-year holidays: a complete redesign of the app’s embedded database icons along with fifty new ones, expanding the set to 200! They are available now on all four platforms: Android, iOS, macOS, and Windows.

To get it done we worked with Icon Factory, whose work you may have seen around, and they really delivered on both the style updates and the new additions to the set. This is a big deal for us as it’s not something we can do often, and these icons tend to make up quite a bit of the interface of Codebook once it’s been populated with records.

For the new icons we drew in part from the many requests we’ve received over the last few years directly through our support mail account and in response to requests for comment on our discussion forum. We really appreciated all that input and welcome more, so if we’re missing something you’d like to see added, let us know, we do keep a list.

For the new style we wanted to go with a more business-friendly look that maintained the charisma and humor of the current set, with more depth and details to take advantage of today’s high-resolution displays. We hope you’ll agree that the result is impressive:

Before After Before After

All the existing icons got updated to the new style should be recognizable, but we did repurpose one of the–three!–phone-related icons to something for the shortwave or radio enthusiast:

Before After

As to the new icons, here’s a pseudo-random sampling:

Programming CI / Dev Ops Security Certificate GPG / Keypair
Amazon Home Security TOR Payroll
Rail Transit Card Outdoor Sports Healthcare.gov

It was a pleasure to work with Icon Factory on this project, many thanks to them for a job well done. Enjoy the new icons, and Happy Holidays from all of us here at Zetetic! 🎄

Codebook for iPad is Being Discontinued

Permalink - Posted on 2017-09-22 14:17

As noted earlier this year on our discussion forum, we’ll be discontinuing the iPad-only version of Codebook that’s currently available in the iTunes App Store. We’d like all our customers who purchased that version of the app to install the other, universal (i.e. runs on iPhone and iPad) version of Codebook now that it runs on both device types.

Previously, both apps used the same blue icon and had the same name on the Home screen, “Codebook”, making it hard to tell the apps apart. To aid in the transition and help give our iPad customers a heads-up that things are a-changing, we gave Codebook for iPad’s app icon an update, switching it to black and white.

Screenshot of iPad Pro 10.5 annotated to show the difference in the Codebook universal and iPad icons

Transitioning to the Universal Codebook

First, you’ll want to install the newest version of the universal Codebook for iOS app on your iPad alongside the old version with the black and white icon (don’t delete anything just yet!) Visit this link directly on your iPad to be taken to the right page in the App Store. If you don’t already own the iPhone version, not to worry: we created a bundle in the App Store allowing you to credit your iPad purchase towards the iPhone version, which should result in no charge for most customers.

Once installed, launch the app and go through the first-time setup process, using the same password you usually use to protect your Codebook data.

During setup you will be given an opportunity to use Codebook’s Sync feature to copy your data over from another install of Codebook on the desktop via WiFi, or via Google Drive or Dropbox. You’ll want to set the switch on this screen to Yes for a restore.

Screenshot of iPad Pro 10.5 displaying sync options during setup

Once you’ve loaded your data into the universal build of Codebook (the one with the blue icon) you can safely remove the version with the black and white icon. Currently Codebook for iPad is still being maintained, but everyone using it should switch over to the universal version as soon as they can, as we will eventually remove it from the App Store.

Advisory - SQLCipher with Xcode 9 and new SDKs

Permalink - Posted on 2017-09-22 14:17

Properly configured projects using SQLCipher shouldn’t experience problems using Xcode 9. However, changes in the new SDKs can cause compile time errors for misconfigured projects, e.g.

Implicit declaration of function ‘sqlite3_key’ is invalid in C99
Implicit declaration of function ‘sqlite3_rekey’ is invalid in C99

We have prepared important recommendations for SQLCipher developers on how to resolve these problems on the SQLCipher support forums:

Important Advisory: SQLCipher with Xcode 9 and new SDKs

Important Advisory - SQLCipher with XCode 8 and new SDKs

Permalink - Posted on 2016-09-14 17:20

Apple has released XCode 8 and new SDKs. We have published important guidance for using SQLCipher with the new platforms (e.g. for iOS, watchOS, macOS, tvOS, etc.) on the SQLCipher support forums:

Important Advisory: SQLCipher with XCode 8, iOS 10, etc

Critical recommendations include:

  1. Adjusting Project Build Settings to link SQLCipher first
  2. Including an Application Runtime Check for SQLCipher
  3. Testing and Validation

Please make it a priority to implement these recommendations and perform appropriate application testing when moving to these new platforms.

Getting Started Setup Assistant and Editing From Secret Agent

Permalink - Posted on 2016-07-25 11:00

We’re happy to announce the release of Codebook for Mac 3.0.11 and Codebook for iOS 3.1.3 which introduce a new setup assistant to guide you through setting up Codebook for the first time, or on a new device.

The assistant guides you through:

  1. Setting up your master password
  2. Enabling Touch ID on iOS (if available)
  3. Enabling Anonymous Statistics
  4. Setting up Sync or, if this isn’t your first time using Codebook, restoring your data.

The new first time setup experience may sound like it doesn’t apply to you, a long time and valued customer, but sometimes we need to install Codebook fresh or on a new device. The new first time setup experience provides the option of restoring your data during setup.

Editing From Secret Agent:

Sometimes we find ourselves needing to create or change a password and we automatically trigger the Secret Agent keyboard shortcut only to realize as soon as it comes up that it currently can’t help us with this. The Edit button on the entry view displays the Main Window, looks up the entry, and puts the interface in edit mode.

Codebook now available in French iTunes and Google Play stores

Permalink - Posted on 2016-07-18 10:00

Hey everyone, we have some very exciting news to share with all iOS and Android users in France: We are once again selling our well known password manager and note taker Codebook in the French iTunes App Store and the French Google Play Store!

It has been about 4 years since we had to stop selling Codebook (named STRIP at that time, Strip on your iPhone’s home screen) due to French laws regarding the selling of encryption software but we recently received approval to start selling our software in France again and we are really excited.

Upgrading from Version 1 to Version 3

Our existing customers in France stopped receiving iOS updates around version 1.6, and the current version is 3.1. We have tested the upgrade from the old STRIP versions to the new Codebook versions and there do not appear to be any issues. However, we recommend that you first backup your device to iTunes or iCloud or use the Sync feature to sync your data with a Dropbox account.

Name and Icon Changed - Codebook is STRIP!

STRIP was renamed to Codebook and it has a new icon on your iOS home screen:

New icon for STRIP, now Codebook

If you currently get automatic updates from Apple, once the app is released in France, it will automatically update the current STRIP app to Codebook and replace the icon on your home screen. If you leave this setting on and notice that your STRIP icon is gone and you now see a new Codebook icon, this is OK, DO NOT delete it as this is the new version of STRIP. You can login with the same password you have been using for STRIP and all your data should be intact.

While We Were Away

There have been quite a few other changes to Codebook for iOS since version 1.6. A modern interface, fixes and improvements, and lots of new features. We’ve also created ports of Codebook for Android, macOS, and Windows, making your passwords available on other devices you use.

An incomplete listing of new features and improvements:

Need Help?

Please contact us at support@zetetic.net if you have any questions. You can visit our original announcement of the change from STRIP to Codebook to learn more about the transition.

SQLCipher for Android 3.5.2 Release

Permalink - Posted on 2016-07-07 12:15

SQLCipher for Android 3.5.2 was just released, addressing two specific items since our recent Android N release. First, we have corrected an issue in which the UTF-16 encoded content was not translated correctly under a few specific situations. In a scenario where the underlying type affinity of the column of the database is TEXT, and numeric values were stored in that column, queries that returned that value and attempted to retrieve the value via getInt(…) or getDouble(…) would incorrectly translate the content, misrepresenting the stored value. This has been corrected, and tests have been added to the SQLCipher for Android test suite to track the correct behavior for the future.

The last change updates the C++ library support included within the native platform libraries, switching from the LLVM C++ static library to the STLport static library. This provides increased support on certain deployment scenarios specific to the armeabi platform. We have updated the SQLCipher for Android integration tutorial providing instructions for utilizing the latest binaries.

SQLCipher for Android Release—Android N Support

Permalink - Posted on 2016-06-23 12:15

We are happy to announce the release of SQLCipher for Android 3.5.1. This is an urgent and mandatory upgrade for applications wishing to support Android N when it is publicly released.

This release of SQLCipher for Android incorporates several major changes to facilitate operating on Android 2.1 through Android N, supporting armeabi, armeabi-v7a, and x86 platforms. The Google Android team contacted us directly, requesting many of the changes below. These changes were mandatory to make SQLCipher for Android compatible with Android N. Below is a highlight of the changes that are included with the latest release:

  1. All internal and third-party library dependencies except for OpenSSL (the crypto provider) have been removed. This includes libbinder, libandroid_runtime, libnativehelper, libcutils, libutils, and libicuc.
  2. Non-essential Google AOSP legacy provider code and supporting code has been removed
  3. The library has been converted to use native UTF-16 encoding internally instead of performing redundant on-the-fly translation
  4. Multiple related changes to the JNI layer
  5. Removal of collation sequences that are dependent on ICU or AOSP libraries

There have been some significant benefits to this effort:

  1. SQLCipher for Android is now compatible with the latest Android N Developer Preview 4 (i.e., build NPD56N)
  2. The build process has been drastically simplified and is now much easier to understand
  3. Issues with characters that fall outside of the basic multilingual plane (e.g. emoticons) have been resolved
  4. Less time is required to build the library from source
  5. Only a single native .so library is required for each platform
  6. The resulting libraries are much smaller that before (armeabi is only 1.6 MB), and no longer require a large supporting ICU database
  7. These architecture changes pave the way for future improvements like API modernization and improved x64 support


Instructions for installing the latest release of SQLCipher for Android can be found here.

If your previous usage of SQLCipher for Android was packaged as a zip archive that included 3 .so files per platform (i.e., libdatabase_sqlcipher.so, libsqlcipher_android.so, and libstlport_shared.so), you should remove all of those. Our new packaging will only include one .so file (i.e., libsqlcipher.so) for each native platform. In addition to the different native libraries, you should also remove the ICU zip file (i.e., icudt46l.zip) previously included within the assets directory of your application.

Important: This upgrade is required for all applications wishing to support Android N while using SQLCipher for Android. Without this upgrade, current installations of SQLCipher for Android will crash on Android N. We do not know the official release date of Android N, however Google is advising application developers to update their applications for imminent release in Q3. Therefore we strongly advise all applications to begin the upgrade and testing process immediately with this release.

SQLCipher Version Scheme

Permalink - Posted on 2016-06-23 12:00

SQLCipher core has long used the versioning scheme defined by semantic versioning, however many of our client libraries have utilized modified schemes to define their versions. As many of the client libraries we utilize as the basis for integrating SQLCipher are open source, often times their version schemes have already been defined.

Having different version schemes for our client libraries introduced confusion around a given library supporting a specific file format associated with a given SQLCipher core release. We may make changes to the upstream client library specific to SQLCipher integration and need a means of conveying that. To address this, we will utilize the X.Y.Z version scheme, for both SQLCipher core and client libraries, however we are adjusting the rules associated with the various version segments to properly align with our domain.

Modified X.Y.Z version rules for SQLCipher:

  • X will map to the major version of SQLCipher (i.e., file format compatibility)
  • Y will map to major changes in the client or core library (i.e., security fix)
  • Z will map to minor changes in the client or core library

We plan to adopt this scheme going forward as we release new and updated client libraries with the aim of simplifying and consildating the versioning schemes across our libraries.

Find in Codebook iOS App Extension Released

Permalink - Posted on 2016-06-14 09:00

Today we’re happy to announce the release of Codebook 3.1.0 for iPhone and iPad, featuring a new iOS App Extension, Find in Codebook, allowing you to securely lookup your Codebook records from Mobile Safari and fill out forms on the web. The option is disabled by default, you need to launch the new app once and sign in to make it available. Here it is in action:


Find in Codebook Demo from Zetetic on Vimeo.

Read on below for step-by-step instructions for setting up Find in Codebook.

This update also introduces an additional password generation option – Diceware. Diceware is a method of creating strong, random, yet easy to remember passphrases:

Version 3.1.0 is available now in the iOS App Store:

Enabling Find in Codebook

  • Update Codebook to 3.1.0
  • Launch Codebook once and sign in
  • Open Safari and visit a webpage
  • Tap on the Action/Share button at the bottom of the view (it looks like an arrow coming out of a box)

  • Swipe the bottom (grey icons) row to the end and tap More

  • Look for Find in Codebook in the list and set the switch next to it to On

  • Optionally, use the drag handle icon to move it higher up in the list
  • Tap Done

Using Find in Codebook

  • Visit a page with a login form (e.g. https://www.dropbox.com/m/login )
  • Tap on the Action/Share button

  • Tap on Find in Codebook

  • When prompted, authenticate

  • Tap the entry that best matches the website/URL (e.g. Dropbox)

The results list is broken up into 3 different sections:

  1. Exact Matches - match the URL exactly (e.g. https://www.dropbox.com/m/login)
  2. Host Matches - match the Host (e.g. www.dropbox.com)
  3. Suggestsions - match relevant part of the url (e.g. dropbox)

We recommend entering the full website into the “Website” field of the entry, so that when you visit the login page, the correct result will show up under “Exact Matches”

  • Find in Codebook will return you to Safari and use the record you selected to fill out the form

Generating Diceware Passphrases

  • Create a new (or edit an existing) password field

  • Select “Generate Random”

  • Select “Character Set”

  • Select “Diceware”

  • Choose the number of Diceware words, generate a Diceware password (by tapping the circular arrow), then once you have one you like, tap Done

SQLCipher 3.4.0 Release

Permalink - Posted on 2016-04-05 15:00

We are happy to announce a new release of SQLCipher, version 3.4.0. This release is based upon the upstream version of SQLite 3.11.0, which includes significant performance optimizations to SQLite, you may see up to a 22% performance improvement over the previous version for the same operations.

There are few new features we would like to draw attention to:

  1. JSON support
  2. FTS5 support
  3. PCL support
  4. PRAGMA updates
  5. WatckKit support

JSON support is a relatively new feature included within SQLite as an extension called json1. The json1 extension includes a set of scalar functions for composing, extracting, and manipulating JSON content - a very welcome addition for applications that often interface with JSON.

SQLCipher has long included support for both FTS3, and FTS4, the full-text search facility provided by SQLite. With the 3.4.0 release, we have also included FTS5 support which address issues that could not be fixed in FTS4 without breaking backward compatibility. A few highlights of FTS5 include:

  • FTS5 supports “ORDER BY rank” for returning results in order of decreasing relevancy
  • FTS5 features an API allowing users to create custom auxiliary functions for advanced ranking and text processing applications
  • FTS5 recognizes Unicode separator characters and case equivalence by default

The client libraries found in SQLCipher for Windows Phone and SQLCipher for Windows Runtime have been updated, continuing our transition from sqlite-net to the PCL compatible version based on SQLite.Net-PCL. Upgrading existing applications is rather seamless, requiring minimal code changes generally localized to how the connection to the database is made. The addition of PCL support allows for sharing much of the data model source code, minimizing duplication across platforms.

There are two PRAGMA updates that have been included in SQLCipher 3.4.0. First, we have deprecated the setter PRAGMA for manipulating the cipher used at runtime. Currently, you can still adjust the cipher used, on crypto providers that support switching, however this will return an error state and will be removed in a future release. We have added a new PRAGMA, PRAGMA cipher_provider_version that will provide the version of the crypto provider that was compiled within SQLCipher if available, this information will only be available following the keying of a database.

We are now offering commercial builds of SQLCipher targeting Apple WatchKit supporting i386, armv7k, x86_64, allowing you to further secure databases stored on the Apple Watch. ⌚


SQLCipher in source format is directly available here. The community edition of SQLCipher for Android is available via AAR packaging using the following line:

compile 'net.zetetic:android-database-sqlcipher:3.4.0@aar'

Updates to commercial builds are available now. Information regarding the purchase of both commercial and enterprise offerings of SQLCipher can be found here. The 3.4.0 version of SQLCipher includes many new, exciting features we are excited to share with you. Please give it a spin!

Codebook Journal and Improved Touch ID Security

Permalink - Posted on 2016-03-29 10:20

We’ve been putting a lot of elbow grease into our password manager Codebook since the 3.0 update at the beginning of the year and we got to share some of that work in recent updates this month for iOS and Mac. On Monday March 14th we released 3.0.3 for Mac and Tuesday the 15th we released 3.0.4 for iPhone and iPad. Many of our point releases focus on a small number of issues, but this is a pretty big update between the two with dozens of bug fixes, improvements, a new feature, and improved security for Touch ID login on iOS. This is a free update for all customers.

The new Journal view

Journal is a new view in Codebook for iOS and OS X that shows all the notes in your database in one place, sorted either by the date the note was created or the date it was updated (up to you.) Notes are still stored in categories alongside multi-field records, this view makes it possible to keep track of those notes over time.

Were you a user of Codebook 2 on iOS? You can rearrange your tabs in Codebook 3 on iOS to show the Journal view first if you prefer to use the app as a secure notebook. Just tap on the More tab, then Edit, and arrange your tabs as you like:

On OS X you can find Journal in the Views list (or access it directly by using the shortcut shift command 3), and the sorting preference is available under Preferences:

The Journal view will be coming to Windows and Android soon.

Improved Security for Touch ID Login

Codebook on iPhone and iPad offers a setting that allows the user to enable the use of Touch ID fingerprint authentication for logging in to Codebook. This makes it much easier to use a strong master password on mobile devices where typing it in can be a bit arduous.

Recently an attack on this was suggested by Per Thorsheim of Godpraksis and the Passwords conference, where another person with knowledge of your iOS device passcode (perhaps a family member) could use that to add their own fingerprint to the list of authorized fingerprints and thereby impersonate the owner at Touch ID prompts like the one in Codebook.

Fortunately, in iOS 9 Apple introduced some new security restrictions that we as developers can take advantage of to help prevent this. Version 3.0.4 improves Touch ID login for Codebook on iOS 9 in two ways:

  1. If Touch ID authentication is used with Codebook it will no longer allow fallback to the device passcode
  2. If changes are made to registered fingerprints in iOS Codebook will not allow Touch ID for authentication and require you to reenable this feature

To take advantage of these improvements sign in to Codebook, tap on the Settings tab, then Login Settings. There disable and then enable the Touch ID login feature.

Import and Export on Mac

Codebook for OS X has not always done a particularly stellar job when it came to importing data, especially large amounts of it. This version introduces a completely revamped Import feature that rips through large CSV files and is more tolerant of text files that aren’t encoded in UTF8.

Import on the Mac side no longer provides the ability to do bulk updates of existing records by including a column named EntryID. We never provided it on Windows and we’ve always been a bit skeptical of its utility. Now all rows are treated as new records to be created.

To facilitate the creation of Notes one can now include a column named Note Entry, each row with a value in this column’s field will be treated as Note rather than a multi-field Entry.

Export to CSV no longer includes the EntryID column, and provides the contents of Notes in the Note Entry field. There is also a new option on the Export dialog where you can select Plain Text output instead. This produces an unencrypted text document suitable for printing should you wish to have a hard backup of your data for safe storage.

Accessibility and Keyboard Shortcuts

Throughout Codebook for OS X we’ve been working to ensure that the application is fully accessible; any task one could accomplish with a mouse should also be available using the keyboard. We’re not all the way there yet but we’re on our way, adding new shortcuts where they were missing and improving the options available in the File and View menus. For instance, one can now access the new Views above the Categories list by using the shortcuts for them under the View menu (e.g. Use command 3 to select the Journal view). You can keep up with all our keyboard shortcuts here. We’ve also been going through the interface adding better labels for voice-over support for identifying controls. Coming soon: a Cut feature for entries, a keyboard shortcut for removing fields, and Undo for editing an entry (in case you really didn’t want to delete that field).

Stay tuned for more updates, we’ve got more good things coming for Codebook, big and small!

Codebook 2 Will Be Discontinued On July 4th, 2016

Permalink - Posted on 2016-02-22 11:00

Now that the dust is starting to settle with Codebook 3 it’s time to wind down Codebook 2. Currently the app is in maintenance mode; we have a minor bug fix update on the way, but no feature improvements planned. On July 4th, 2016 we will remove it from sale in the iTunes App Store. At that point it will no longer be available to download from the App Store, and may not be available for restore from an iCloud backup either. You will still be free to use the Codebook 2 software you purchased after that date, however, you must make regular backups in iTunes so that you have a copy of the app, or you will be at risk of losing access in the event of a device transfer or reset. It is also a good idea to ensure your Codebook 2 data is frequently backed up to Dropbox as well.

Backing up your Device (click Use iTunes)

If you are a Codebook 2 customer and are having trouble migrating your data (or deciding to upgrade), please get in touch with us at support@zetetic.net.

Introducing Codebook 3: STRIP renamed Codebook, with Notes and Favorites

Permalink - Posted on 2015-12-14 12:00

We are very excited to announce some new and very important changes to the STRIP Password Manager:

  1. STRIP has been renamed to Codebook: The STRIP icon will be replaced with a new Codebook icon. All the logos, icons and colors are updated.
  2. Dedicated Notes: You can now store dedicated Notes in Codebook. These are perfect for storing longer, free-form text.
  3. Favorites: You can now mark your most important entries with a Favorite Star to make them show up in a dedicated quick access view and as the first entries returned in searches.

STRIP to Codebook 3 (and a bit of history)

One of the most visible changes is that STRIP is being renamed to Codebook, version 3. The application now has a brand new logo, icon, and color scheme to match, professionally designed by the excellent team from the Icon Factory.

Some of our most dedicated users will remember that STRIP was first released over 17 years ago for Palm OS. The acronym, Secure Tool for Recalling Important Passwords, seemed playful and unique at the time. However, the name hasn not aged as well as the application itself. Over time:

  1. Searches for the product started returning unrelated adult content
  2. People found the name potentially offensive
  3. The name became generally unwelcome among our customers

Thus, even though the application has became well known as STRIP, the time has come to change.

So, if you don’t see STRIP after you upgrade, don’t panic! The old STRIP icon will be replaced with a shiny new Codebook icon like this.

Codebook Icon

A sidebar about the “old” Codebook

Some users may be aware that Zetetic previously released a different product named Codebook, a simple note taking tool for iOS, several years ago. After this release users of the old Codebook will have the option to migrate their data into the new Codebook application (more on that here - Migration Document).

Going forward, there will be only one Codebook!

Dedicated Notes

This brings us to one of the new features in this release: dedicated note entries. While standard entries are great for organizing the multitude of small fields and values that apply for most accounts, they are not optimized for larger bodies of free-form text.

A new “Notes” feature allows you to quickly and easily create text-based notes with a single tap, which can be organized separately or alongside other entries.

Notes on Codebook for iPhone


Another major feature in the release is the ability to mark important entries as “Favorites”. By marking an entry with a Favorite star, the record will automatically show up in a new Favorites view for quick access.

Favorites on Codebook for Android

Favorites automatically sort to the top of search results, both within the standard search function and in Secret Agent on the desktop. This allows you to very quickly access your most critical information in Codebook at a moment’s notice.

Windows Secret Agent

Other Improvements

Codebook 3 is also packed with other enhancements, improvements, and numerous bug fixes for every supported platform.

Upgrade Notes

Upgrading to Codebook is really easy. On most platforms, you’ll just need to run the update and look for the new icon. On iOS, if you have auto-update enabled, you may already have it installed!

Explicit instructions for updating Codebook are available on the upgrade FAQ, but here is the short summary:

  1. Please backup your mobile devices and desktop databases before upgrading, either via WiFi, Dropbox, or Google Drive!

  2. After the upgrade, the old STRIP icon will be replaced with a new Codebook icon. If you can’t find STRIP, look for Codebook instead. All your data will remain intact.

  3. When you log in to Codebook for the first time the database format will be updated. Due to database file and feature improvements, STRIP 2.x will not sync with Codebook. Therefore, you should plan to update all of your devices and applications to Codebook at around the same time.

Feedback and Support

We are here to help during this transition in case you have any questions or difficulties with the upgrade process. Don’t hesitate to contact us:

Finally, once you’ve had a chance to try Codebook, we’d really like to get your feedback about the new look and features.

PCL Support Now Available on SQLCipher for Xamarin

Permalink - Posted on 2015-12-10 12:00

Following the release of the SQLCipher for Windows Universal Application Platform package, we have issued a major update to our SQLCipher packages on the Xamarin platform which now includes PCL support.

SQLCipher for Xamarin iOS and SQLCipher for Xamarin Android include two different client libraries for interfacing with a SQLCipher database. First, the Mono.Data.Sqlcipher library for data access with an ADO.NET style interface. We have recently replaced our second client library, previously based on sqlite-net with that of SQLite.Net.Core-PCL. While the new library maintains much of the same behavior as its predecessor, providing a light weight ORM, it is now PCL compatible. This will allow developers targeting both iOS and Android devices using the Xamarin platform to share much of their data model source code, minimizing duplication across platforms.

A sample below shows how quickly you can construct a secured SQLCipher database connection for your Xamarin iOS application.

var password = "SQLCipher!";
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var libraryPath = Path.Combine(documentsPath, "..", "Library");
var databasePath = Path.Combine(libraryPath, "sqlcipher.db");
var conn = new SQLiteConnection(new SQLitePlatformIOS(password), databasePath);

If you are interested in giving either SQLCipher for Xamarin iOS, or SQLCipher for Xamarin Android a try, trials are available for both. Please feel to reach out if you have any questions.

SQLCipher for Windows Universal Application Platform

Permalink - Posted on 2015-12-01 12:00

We are happy to announce the immediate availability of our commercial SQLCipher for Windows Universal Application Platform package, available for purchase here. We have previously supported both the Windows Runtime and Windows Phone platforms as separate component packages, however moving to the Windows 10 platform allows for a different approach. We will continue to support the older individual packages with updates to SQLCipher, however for developers looking to strictly target Windows 10 on the desktop, and/or Windows 10 Mobile we now have a unified package option.

Application Integration

The new package is bundled as a Visual Studio extension and local Nuget package. The client library itself uses the SQLite.Net.Core-PCL component providing a lightweight ORM interface. Utilizing a PCL component at the base allows for shared database logic between Windows 10 and Windows 10 Mobile projects, further simplifying the developers ability to target multiple platforms and minimize code duplication.

The component packaging includes precompiled binaries, documentation, and demos to allow for quick integration of new or existing projects wishing to protect their data. A sample below shows how quickly you can construct a secured SQLCipher database connection for your Windows 10, or Windows 10 Mobile application.

var key = "SQLCipher!";
var databaseFile = "test.db";
var databasePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, databaseFile);
var connection = new SQLiteConnection(new SQLitePlatformWinRT(key), databasePath);

Please note, this new package requires usage of Visual Studio 2015. SQLCipher for Windows Universal Application Platform does not work within the Windows Phone 8.0/8.1 platforms, nor does it work on the Windows Runtime operating system; we offer separate packages for these environments. Please feel free to reach out to us if you have any questions.

Importing LastPass Data with STRIP

Permalink - Posted on 2015-08-27 03:00

Perhaps it’s because LastPass has been in the news—the company has recently been purchased by LogMeIn—we’ve gotten some inquiries as to how one can import LastPass data in STRIP. It’s pretty easy:

1. Log in to your LastPass Vault

2. Click on Tools > Export

3. Save the file and open it with a text or spreadsheet editor

4. Rename “name” to “Entry” and “grouping” to “Category

Note that Entry and Category are capitalized. Save your changes and close the file.

5. Launch STRIP, login, select File > Import

Select the CSV file you just edited.

That’s it!

What is STRIP?

Permalink - Posted on 2015-08-27 03:00

STRIP is a password manager and data vault. But much more than that, STRIP offers a flexible data model, cross platform sync, excellent customer service, and a high standard of data encryption. The history of STRIP began back in 1998 as an app for the Palm OS. Ever since then, STRIP has been advancing with its full database encryption using AES-256, user interface, and additional features which make it stand out. It is important to note that this is a standalone application: no account registration needed. Your data is yours to keep. Even when you sync, your data is fully encrypted and can remain cloudless if you sync over wifi. This video gives an overview of what STRIP is and dives into it’s features.

As always, if there are any questions, concerns, issues, or feedback please let us know.

Passwords 15

Permalink - Posted on 2015-07-29 02:16

Passwords conference logo

A hacker conference that’s all about passwords, PIN codes, and digital authentication.

We are excited to announce that we are sponsoring and attending Passwords 15 this August 4th and 5th in Las Vegas! It’s an annual conference held alongside the BSides hacker conference which brings together some of the brightest minds in the field—among them password crackers, researchers, and security experts.

Representing us will be two members of our development team, Micah Moore and Billy Gray. If you’re attending as well, don’t be shy, say hello. This is our third year attending Passwords; last year we sponsored the conference and delivered two talks ourselves. Here’s the one we gave on enhancing password-based key derivation techniques:

This year we’re just going to take it all in. The talks are really engaging, some demonstrate cutting-edge cracking techniques and delve into theory while others try to make sense of all the research out there and address wider issues. BSides is of the same caliber: there’s never a dull moment, and the pool party isn’t bad, either ;) Hope to see you there!

Secret Agent Is Awesome

Permalink - Posted on 2015-07-15 01:00

Hello readers. STRIP, our password manager, has a helpful feature named Secret Agent that makes it easy to access data stored in STRIP from other apps. We created a demonstration video on how to use Secret Agent effectively and we wanted to share it with you and describe the feature a bit more.

Ever get to a website login page and sigh at the annoyance of typing in your username and password? You don’t have to with Secret Agent. Just use the global keyboard shortcut to bring up the search bar. Search for your entry and hit enter, then select the field you want and hit enter again. Secret Agent will automatically fill in the field–without the need for an additional browser plugin. This works on more then just browsers: you can insert data from STRIP in any app using Secret Agent.

How to set it up:

  • On Windows go to File/Preferences/ Check off “Run Secret Agent at Windows Login”
  • On OS X go to STRIP/Preferences/General Check off “Enable Secret Agent with keyboard command”
  • NOTE FOR OS X USERS: Make sure user script is at the correct path: ~/Library/Application\ Scripts/net.zetetic.Strip.mac/

How to use it:

At a prompt you can use the hotkeys to bring up the search bar. These are the default keys which we recommend, but you’re free to change it to your liking.

  • Windows: Shift + Control + Backslash
  • OS X: Shift + Command + Backslash

Search for your entry. Hit enter on the field you want to fill. Make sure your insertion cursor (blinking vertical line) is on the field you want to fill before calling Secret Agent. When you call it again it will start from where you last left off incase your filling in multiple fields. Else, you can just start typing and it will search. Once you get the hang of it logging in becomes impressively quick, leaving on-lookers curious as to how you were able to login in so quickly without touching your mouse or typing all that much.

As always, if there are any issues please let us know.

Touch ID Support for STRIP

Permalink - Posted on 2015-06-29 16:00

If you take a look at the iTunes App Store US reviews for STRIP for iPhone, you’ll see this sentiment in a number of the more recent ones:

It’s a good app, however it’s missing a big thing here which other security apps have…simply NOT supporting “Touch ID” …whyyy!! Once this integrated will pump up the rate to 5*

I hope we’ve finally earned that fifth star, Kokiiiz78! Today we’re excited to announce that Touch ID authentication is now available in STRIP for iPhone and STRIP for iPad version 2.5.0.

TouchID Login for STRIP from Zetetic on Vimeo.

The feature is optional, disabled by default, and simple to use.

To enable Touch ID authentication:

  1. Update STRIP to 2.5.0
  2. Login to STRIP and tap on the Settings view tab
  3. On the Settings view tap on Login Settings
  4. Tap on the switch labeled “Enable Touch ID login”
  5. You may be prompted to authenticate with your Touch ID by iOS
  6. That’s it! The next time you are asked to login to STRIP you will be prompted for your Touch ID

As an aside, this feature works nicely in conjunction with the Auto Lock Timer preference, which allows you to keep STRIP unlocked for a chosen interval.

Changes in this version:

  • Provides new “Enable Touch ID login” feature under Settings -> Login Settings
  • Search view now searches your records as you type
  • Password Generator view maintains state when leaving STRIP

Additional changes to the iPad version:

  • Fixes search bar disappearing when tapped twice quickly

Thanks so much to our beta testers for helping us to identify bugs and edge cases early in the process. Your efforts and repeatedly installing beta builds over the last month really helped us as we vetted this version for release.

As always, if there are any issues please let us know. If you’d like to tell us what you think consider stopping by our discussion forum.

STRIP, Keychain, and XARA

Permalink - Posted on 2015-06-23 14:00

A customer wrote us regarding recent reports of vulnerabilities to the Keychain in iOS and OS X and whether or not these affect STRIP password manager:

Is STRIP for iOS vulnerable to this “0 days flaw” in Apple software and allows “cross-app resource access (XARA) attacks”? Is the password for the iOS STRIP app stored in the keychain of the iOS or anywhere else in the iOS system other than in the STRIP app itself?

STRIP does not store the user’s master password in the iOS or OS X Keychain (back to this in a moment).

However, STRIP makes use of the Dropbox and Google-supplied frameworks for authenticating against their services for sync if you choose either of these sync modes. Both of those frameworks store the OAUTH authentication credential in the iOS and OS X Keychains (open Keychain Access on your Mac and search for “STRIP” to have a look).

Touch ID Authentication on iOS

In the soon-to-be-released version of STRIP for iPhone and for iPad we’ve added the oft-requested feature of Touch ID login. This feature is completely optional, disabled by default, and only available on devices with Touch ID. The feature works by storing your master password for STRIP encrypted in the Secure Enclave on the device, through the Keychain.

Are these Keychain items vulnerable to attack?

It depends. There’s a great article on iMore.com explaining the attacks and what’s vulnerable (emphasis theirs):

Contrary to what some reports have said, while a malicious app cannot read your existing keychain entries, it can delete existing keychain entries, and it can create new keychain entries that are readable and writeable by other, legitimate apps. This means a malicious app can effectively trick other apps into saving all new password entries to a keychain it controls, and then can read.

iOS is unaffected:

The researchers note that one of the reasons iOS is unaffected by this is that iOS doesn’t have ACLs (access control lists) for keychain entries. Keychain items on iOS may only be accessed by an app with a matching bundle ID, or group bundle ID (for shared keychain items). If a malicious app created a keychain item that it owned, it would be inaccessible by any other app, making it entirely useless as any sort of honeypot.

Using the Touch ID login feature in the next version of STRIP for iPhone and iPad should not leave you vulnerable to this exploit.

In the end you always want to avoid suspicious, maliciously crafted software; once a host operating system is compromised it becomes very difficult to keep your data secure. Watch out for phishing attacks, where email is crafted to trick you into visiting a malicious website or downloading malware posing as normal attachments. On OS X you can limit the apps allowed to run on your Mac to those signed by Apple or by Apple-identified developers (like Zetetic):

If you are concerned about malicious keychain entries you can check for them easily:

  1. Open Keychain Access
  2. Search for “STRIP”
  3. Select the Keychain item in the right pane and select File -> Get Info (or type command+i)
  4. Select Access Control
  5. In the list of allowed applications you should only see STRIP

What about WebSockets?

While STRIP on the Mac provides a utility function for looking up your passwords and inserting them in other applications, it does not include a browser plugin and makes no use of WebSockets, another point of vulnerability detailed in the recently announced exploits.

Tempo Time Tracking is Closing

Permalink - Posted on 2015-05-11 12:00

Update, July 9th: We will be shutting down Tempo permanently on Monday, July 13th, to give our customers a couple more days for the transition.

After many happy years we have made the difficult decision to stop operation of the Tempo time tracking system in the near future.

When we started Tempo in 2007, the marketplace for online time tracking systems was limited. Existing systems were rigid and inflexible, often using antiquated desktop interfaces without mobile support. Tempo’s core ideas like flexible tagging, time entry via email / SMS / Twitter, and detailed trend reports, were fresh.

Since then, however, the number of cloud-based time trackers and mobile apps has grown substantially, and an increasing number of people have moved to consolidated project and billing platforms, or implemented their own time tracking solutions using simple and free cloud services. We believe strongly in working on projects that are sustainable and, unfortunately, Tempo is no longer sustainable in the long term.

Starting today we will be blocking new account registrations on Tempo. The system will be turned off permanently on July 10th, 2015. We will not be billing accounts during the transition period, so if you are a paying customer on a premium plan you will not be charged again for Tempo service.

In order to help you get data out of Tempo, you can use a new full account export feature to download a single compressed file containing the exports of your account’s time entries. The included CSV file can be easily opened by a spreadsheet program for manipulation, long-term historical archiving, or to provide a base data set to migrate to another system. The export function is now available to account owners and managers on the Accounts tab in Tempo.

All exports are refreshed daily and contain all of the information from the start of your account to the previous day. Please be sure to make a copy of your critical data before the system is shut off.

There are several other excellent project and time tracking systems that you might consider switching to. While we can’t recommend any particular system, we encourage you to try out a few over the coming weeks to see what you like. Some systems that we have seen recommended in the past include Harvest and Freckle, especially for advanced users.

Tempo is the only system that Zetetic is shutting down. Our other solutions, including SQLCipher, STRIP, and our Identity and Access Management services are unaffected. Despite Tempo’s lack of growth, Zetetic is still doing very well as a company, continuing to grow, and approaching our 10th year in business.

Finally, we want to say thank you to all of our Tempo users for providing feedback along the way, and helping to spread the word. We really appreciate you as customers and sincerely apologize for any inconvenience this difficult decision may cause. If there is anything we can do to help make the transition easier please don’t hesitate to let us know.

SQLCipher for Cordova

Permalink - Posted on 2015-03-30 12:00

We are happy to announce the availability of commercial licenses to SQLCipher for Cordova. Cordova allows a developer to quickly develop mobile applications using JavaScript and now secure database storage via SQLCipher is available as a commercially supported platform. SQLCipher for Cordova provides support for integrating a SQLCipher database within a Cordova project running on iOS, Android, and Windows Phone. All interactions will the database are perform through a simple JavaScript API. Now available for purchase or as a trial.

SQLCipher 3.3.0 Release

Permalink - Posted on 2015-03-26 12:00

We are happy to announce the availability of SQLCipher 3.3.0. This release is based on the upstream SQLite release which included many beneficial updates including a general performance increase of over 20% for the same number of CPU cycles from the previous release. Specifics for the SQLite release are covered here.

Directly within SQLCipher we have included a few additional items as well. First, we introduced a new PRAGMA, cipher_default_page_size, a mechanism which facilitates setting a non-default page size value to be used when attaching databases. Next we have added API hooks to support FIPS integration within the OpenSSL crypto provider. SQLCipher for Android has also been updated with community edition binaries available here. Binaries that ship with support for OpenSSL have been upgraded to the latest 1.0.2a release. Commercial binary updates to be available soon.

On App Store Pricing

Permalink - Posted on 2015-03-03 13:45

At the Daring Fireball blog John Gruber notes that he and his co-conspirators at Q Branch have increased the price of their excellent note-taking app Vesper:1

Put another way, we’re going to charge something sane or die trying. We tried following the iOS App Store trend by pricing Vesper at just $2.99 for months. It didn’t work. Prices like that are not sane, and not sustainable, at least for well-crafted productivity apps. So Q Branch is drawing a line in the sand, and we hope other iOS developers will follow.

We’re doing the same for our password manager app, STRIP. For a long time we’ve charged pretty low prices for both STRIP for iPhone (and for iPad), and STRIP for Mac: $4.99 and $9.99, respectively. The Android and Windows versions, same deal. Prices this low are not sustainable when we’re doing steady, iterative design and development while maintaining the apps and adapting them to major new hardware and operating system changes.

With the release of the 2.5 series of STRIP for Windows and OS X we’ve increased our prices. STRIP is now $9.99 on Android and iOS, $19.99 on OS X and Windows. The desktop releases are now available as 14-day free trials, which should help people get a feel for the software before deciding whether to make a purchase.

If you’ve purchased STRIP, thank you for supporting our work, it means so much to us!

1. I’ve always wanted Codebook to be more like Vesper, having based it on John’s writing on “The Untitled Note Problem,” and I love the design decisions that they’ve made.

I recently had the opportunity to bend the ear of Brent Simmons, one of the Q branch team making Vesper, during the CocoaLove2 conference in Philadelphia last October. I couldn’t help pitching SQLCipher as a datastore for Vesper. He listened thoughtfully and it was great having the chance to talk. Following the writing of these folks over the last few years has been really educational for me as a software developer and designer.

2. Yes, a footnote for a footnote! CocoaLove was fantastic. I highly recommend it. Check out the talks by William Van Hecke and Laura Savino to see what I mean.

STRIP for OS X 2.5.0 Release

Permalink - Posted on 2015-03-03 13:30

STRIP for OS X 2.5 Auto Suggest feature

STRIP for OS X 2.5.0 was released about 12 days ago, just wanted to make a note here for any who hadn’t seen the post in our discussion forum. For Mac App Store customers, the update should be available soon, the app is currently under review. This may be the nicest release of this version yet, with a lot of bug fixes, an improved login experience, window handling, and auto-suggest for frequently used values.

STRIP for Windows 2.5.4 Release

Permalink - Posted on 2015-02-02 14:30

STRIP for Windows 2.5.4 has just been released, a priority patch release that addresses application locking.

STRIP for Windows 2.5.4 Update Notification

You should receive a notification the next time you launch STRIP for Windows which looks like the above image. Please upgrade as soon as possible. Feel free to contact us at support@zetetic.net should you have any questions.

POODLE Response: SSLv3 Disabled for Zetetic Sites and Services

Permalink - Posted on 2014-10-15 19:30

Google has just published a serious new web vulnerability, POODLE, affecting SSL 3.0. Because this flaw that can leak data, and compromise user and system security, we have disabled SSL 3.0 for our sites and services, including zetetic.net and Tempo. Unfortunately there is no other viable workaround at this time.

Please note that this should not affect the vast majority of users running on modern supported browsers, however IE 6 on Windows XP will no longer be able to connect to these sites. Please feel free to contact us if you have an questions or concerns.

STRIP for iPhone and iPad 2.4.2 Released

Permalink - Posted on 2014-10-13 11:30

As noted on our community discussion site, there’s an update to STRIP for iPhone and STRIP for iPad out today in the iTunes App Store that addresses a couple of recent issues. Version 2.4.2 should start showing up in the iTunes App Store soon if you don’t see it just yet.

SQLCipher 3.2.0 Release

Permalink - Posted on 2014-10-13 10:00

The latest release of SQLCipher, version 3.2.0 which is based on the stable upstream release of SQLite 3.8.6 is now available. With this release, we would like to highlight a few specific changes that were introduced. First, a new PRAGMA, cipher_store_pass which allows for the source passphrase to be stored in RAM, even after key derivation. Typically the source passphrase is zeroed from memory once a key is computed. Now, if PRAGMA cipher_store_pass is set, operations such as an ATTACH database command will used the passphrase stored in memory, thus the requirement to provide a KEY value are not needed unless a different value is required for the key. Note, PRAGMA cipher_store_pass is disabled by default and the memory is locked when supported on the given platform to prevent the memory from being paged into a swap file. When PRAGMA cipher_store_pass is enabled, the stored passphrase is wiped when the database is closed.

In this release we are happy to announce commercial support of SQLCipher on Windows Phone 8.1. Finally, we have included a fix to the Common Crypto provider in which key derivation was occurring twice, this should reduce the first operation requiring KDF by 50%. SQLCipher for Android has been validaed on Android platforms 2.1 through Android L preview. Commercial builds for all supported platforms are available immediately. We are aware of the forthcoming SQLite 3.8.7 release, which promises to be up to 50% faster. We are planning to incorporate 3.8.7 in a follow-up release once it has been released and stabilized. We look forward to hearing your feedback with the latest release, please get in contact!

STRIP for OS X 2.4.2 Released

Permalink - Posted on 2014-09-18 17:00

Just a quick announcement here that we’re releasing 2.4.2 of STRIP for OS X to address some issues introduced in 2.4.0 alongside the new Secret Agent feature and other bugs. Main highlights: we added a keyboard shortcut preference for Secret Agent so you can set what you like (the default of shift+command+\ doesn’t work on many keyboards turns out), and we restored the old height of the rows in the Categories and Entries list.

Changes in this version:

  • New keyboard shortcut preference added for Secret Agent on the Preferences window
  • Changes keyboard shortcut for Lock to shift+command+L
  • Adjusts tab control loop on main window
  • Switches height of categories and entries lists back to system default by popular demand
  • Fixes various memory leaks
  • Ensures New Feature Tour window is visible on smaller screens and resizable
  • Updates Secret Agent to allow for use in full screen apps

Announcing SQLCipher support in SQLiteManager

Permalink - Posted on 2014-09-10 12:00

Many users interact with SQLCipher encrypted databases outside of application code for testing, database development, or troubleshooting. Yet until recently, we’ve only been able to recommend the use of the SQLCipher’s command line shell that is included in many of the SQLCipher Commercial Edition packages, or compiled under Community Edition distributions.

While powerful, many would prefer the experience of a native, graphical, desktop application instead of a command line shell tool, and we frequently receive inquiries about GUI tools that support SQLCipher.

For this reason, we are now very happy to announce that SQLiteManager, a popular and feature-rich database management studio from SQLabs, has released version 4.3.3 that adds native support for SQLCipher encrypted databases.

SQLiteManager for SQLCipher

SQLiteManager provides a suite of advanced features for SQLCipher database management, including:

  1. Query execution
  2. Inline editing with syntax highlighting
  3. Table / schema editing
  4. Graphs and Charting
  5. Data import/export functions
  6. Support for both Windows and OS X.

If you need a user friendly and graphical interface for SQLCipher, please check out SQLiteManager today. Best of all, when you purchase SQLiteManager using the button below, you will help support the ongoing development of the SQLCipher project!

Buy SQLiteManager »

How STRIP Syncs with Dropbox / Google Drive

Permalink - Posted on 2014-09-05 11:00

Syncing with Dropbox or Google Drive from STRIP is pretty simple: you just select the sync method and kick off a sync. The first time you use the feature you’re prompted to login, but then STRIP does its thing.

STRIP Cloud Sync in Progress

However, apparent simplicity masks the steps STRIP takes to ensure that your data stays secure. So, what does STRIP do behind the scenes, exactly?

The very first time STRIP syncs with your cloud account it creates an encrypted replica of the local database on your device and pushes it up to the service.1 It places this file named strip.db in a folder named Zetetic. On each additional sync STRIP downloads this replica file, exchanges changes with it, and uploads it again, replacing the previous version. On both Dropbox and Google Drive older versions of this file are maintained by the cloud services’ individual file history features, meaning you have more than one backup to serve as convenient snapshots over time. No unencrypted data is ever stored in your cloud service by STRIP.

Here’s all that you should see in your Dropbox folder for STRIP after a sync:

Drobox Zetetic Folder

Want to verify that strip.db is in fact an encrypted SQLCipher database and not a plain-text SQLite database, for instance? On OS X you can use hexdump from the Terminal app like so:

$ hexdump -C ~/Dropbox/Zetetic/strip.db 
00000000  f0 b2 48 80 17 54 eb cd  f0 92 28 8b e9 be cb 1b  |..H..T....(.....|
00000010  d2 e6 f2 24 b5 68 b4 0f  62 ae b6 51 9a 35 8f e5  |...$.h..b..Q.5..|
00000020  2c f5 4a b4 7e fc 4b f4  20 f3 2a 24 a1 99 de 88  |,.J.~.K. .*$....|
00000030  95 d6 b3 a4 9a b4 78 ed  55 c3 2a 53 ed 3e f3 17  |......x.U.*S.>..|
00000040  8e 3b 6f 6c 0a 51 4b ce  0e 32 b0 73 0b 86 38 bf  |.;ol.QK..2.s..8.|
00000050  9d ff 4a ab 65 68 aa 66  cf c3 d9 0c 47 3d 95 c3  |..J.eh.f....G=..|
00000060  12 e2 29 0d 92 7b 6c 24  d7 1f 62 a9 4c 8b b3 b2  |..)..{l$..b.L...|
00000070  a7 d3 04 9d 8d 5f ca 05  ed b5 33 5b 2e d6 d4 7d  |....._....3[...}|
00000080  f6 1b f9 8c 24 ba e0 88  be a1 f3 8b 05 71 08 55  |....$........q.U|

Nothing but random-looking noise!

When the encrypted replica file is created it is initialized with the same password the user has set on the local, original database. STRIP uses SQLCipher for encryption, which provides strong key derivation:

When initialized with a passphrase SQLCipher derives the key data using PBKDF2 (e.g. OpenSSL’s PKCS5_PBKDF2_HMAC_SHA1 on some platforms.) Each database is initialized with a unique random salt in the first 16 bytes of the file. This salt is used for key derivation and it ensures that even if two databases are created using the same password, they will not have the same encryption key.

Key derviation helps protect against brute force and dictionary-based attacks, and in conjunction with a strong master password, provides the security necessary to take advantage of these cloud services. Remember that no cryptography can protect your data from a determined attacker if the master password is weak, or can be easily guessed in a brute-force or analytical attack on the database key, so choose wisely! We generally recommend users choose a reasonably long, randomized master password for STRIP, and completely avoid PIN numbers for security purposes.

STRIP’s sync system is bi-directional, meaning that changes from more than one replica or instance of STRIP can be exchanged on each sync. Thus you can sync STRIP on your Android, STRIP on your iPhone, and STRIP on your PC all against the same Dropbox or Google Drive account. One of the major advantages of syncing with these cloud services is that they operate over HTTPS, which is rarely blocked on most networks. This means as long as you have a network connection you can usually sync to make sure you’ve got the latest data on your device.

That’s really all there is to it!

Cloud-based synchronization certainly isn’t for everybody, and many people are naturally distrustful of Cloud security, but STRIP goes to great lengths to protect your data and make sure that unencrypted contents are never stored in third-party services.

We’ve tried to make the Sync feature in STRIP for the Dropbox and Google Drive cloud services as straight-forward and secure as possible. In the future, we’re planning to make synchronization even easier through a background service that doesn’t need to be initiated by the user. This is a problem we’re working on now, though we’re being careful to balance security and ease-of-use, since the two are sometimes at odds!2

1 Usually we use the provided API from Google or Dropbox with the exception of STRIP for Windows which simply places the replica strip.db file in your local Dropbox folder, with the expectation that the Dropbox sync client is running on that computer and will handle the upload accordingly.

2 Security researcher Dan Kaminsky has a really great article on this very topic that’s quite timely.

STRIP 2.4 Released – Introducing Secret Agent

Permalink - Posted on 2014-08-27 10:00

We're very excited to announce the immediate availability of STRIP 2.4.0, along with a major new feature for OS X and Windows called Secret Agent. STRIP's Secret Agent adds a convenient way to quickly access your STRIP data from other Desktop applications. Today’s update also includes redesigned and new icons along with various bug fixes. Read on for more information!


For instructions on updating STRIP please visit the updating STRIP FAQ in discuss.zetetic.net, our new community forum.

Note: Secret Agent is an advanced Desktop-based feature for STRIP for Windows and STRIP for OS X only. However, new versions for iOS and Android are also avaiable with new icons and bug fixes. If you're a mobile user and don't own STRIP for Windows or STRIP for OS X yet, please check them out. They are great desktop companions to the mobile applications!

Secret Agent

With a quick keyboard command you can now quickly and easily access your sensitive STRIP data for use in other applications on your Mac or Windows computer without having to switch apps, interrupt your flow, or copy and paste values.

How It Works

Secret Agent operates in the background on your computer, so it's available anytime. Once you’ve enabled Secret Agent in STRIP Preferences you can type a global hotkey command at any time to bring STRIP up from any application.

When you want to insert secure data into an active text field, for instance entering a website password into your favorite browser, press the hotkey and Secret Agent's search interface will appear, allowing you to quickly locate the record and field you need.

Searching for Data

Start with your cursor focused on an active text field in any application. Type Shift + Control + Backslash on Windows or Shift + Command + Backslash on OS X to bring up the Secret Agent interface. If STRIP isn’t currently unlocked you’ll see a login prompt. Once you’re at the search bar just start typing what you’re looking for:

Once you locate the record you need, hit the enter key to bring up its detail view. Use the up and down arrow keys to navigate through the search results (or scroll and use your mouse, as you like.) While looking at the record detail in Secret Agent, arrow up or down to the field you want, then hit the enter key to automatically insert the field contents at the cursor location in the target application. Pressing the key combo again will bring the same record back up, making it easy to fill in multiple fields.

Secret Agent is a really fantastic and helpful addition to STRIP, providing easy access to data from any application. It's fast, keyboard driven, and most importantly, unlike some browser plugins or javascript-based integrations, Secret Agent is under your complete control. This minimizes concerns about malicious sites or applications stealing your data.

Redesigned and New Icons

One of the nicest visual improvements to the latest version of STRIP is the icons available to help you identify your categories and entries. We partnered with Jory Raphael at Sensible World design studio to completely redesign STRIP's entire icon collection, including the additon of sixty new icons created to our specifications. We couldn't be happier; they really make the app a pleasure to use. (Jory also designed the custom toolbar icons you see in STRIP for OS X and Windows!)

We're Here to Help

Please let us know if you have any questions about the upgrade process, how you like the new version, or if you run into any issues. We just launched a new community forum for STRIP at discuss.zetetic.net for discussion about the software. If you have a question or feedback about STRIP, please stop by, or send us an email to support@zetetic.net.

PasswordsCon 14

Permalink - Posted on 2014-08-13 14:28

If we've taken a little bit longer than usual to get back to you in the last week, it's because we had the great pleasure of attending PasswordsCon 14 in Las Vegas (and got into BSidesLV as well). Stephen and I presented "Enhancing Password Based Key Derivation Techniques" which focuses on two experimental developments in SQLCipher: adaptive key derivation and using hardware tokens. Billy presented "Password Generators & Extended Character Set Passwords," which was mostly an argument that it's time we started generating and using Unicode passwords.

There's an engaging sense of community at both of these conferences, and we had some really fun and interesting conversations with both the attendees and organizers. We would like to thank both Per Thorsheim and Jeremi Gosney, there is a lot of work involved in putting on a conference like this and they did an excellent job. Please find the slides to our presentations below, and don't hesitate to reach out if you have any questions or comments.

Testing STRIP 2.4 and a new feature – help wanted!

Permalink - Posted on 2014-06-17 18:02

its dangerous to go alone!

While cranking out the updates for the 2.3 series of STRIP over the last few weeks (2.3.2 for iOS was just submitted to Apple this afternoon,) we've been hard at work on 2.4 for Windows and OS X, building a new feature we're really excited about. Want to help us test it, get early access to The New Thing™, find bugs, recommend improvements? We're on a tight schedule so we're hoping to find customers who are able give it some thorough use over the next couple of weeks and review the new feature. If that sounds like you, please write us! support@zetetic.net.

STRIP for OS X 2.3.2 Released

Permalink - Posted on 2014-06-12 15:16

Today we're releasing an update to STRIP for OS X that fixes several bugs that could cause data to be lost if not explicitly saved and a crash where a field had been left in an editing state when the application locks due to inactivity. We've done a lot of testing of this update and with the help of a number of customers who wrote us about the problem and helped us test it's ready to rock.

Download STRIP for OS X 2.3.2

If you bought STRIP from the Mac App Store, click the badge below, and the "View in Mac App Store" button if not prompted by your browser, an update should be available in the App Store app:

Download STRIP for OS X from the Mac App Store

If you bought STRIP from Zetetic, click here to download STRIP for OS X:

Download STRIP for OS X

STRIP and Mac OS X 10.6 Snow Leopard

Permalink - Posted on 2014-05-27 17:00

If you haven't been able to install the latest versions of STRIP for OS X because you cannot upgrade a Mac running 10.6 Snow Leopard or 10.7 Lion (there are still some 32-bit Macs alive and kicking out there!) but you want to be able to sync with the latest version of STRIP (2.3) on other devices, we've got a new build of the 2.1 series available. STRIP for OS X 2.1.1 is sync compatible with STRIP 2.3 on iOS and Android as well as 2.3 databases on Dropbox and Google Drive:

Download STRIP for OS X 2.1.1

If you are using OS X 10.8 Mountain Lion or later, ignore this update.

We won't be able to guarantee on-going support for the 2.1 series but we're going to keep it sync-compatible while we can. No changes in the database schema are currently planned for 2.4 so that should be sync-compatible with 2.1 as well.

We've updated the auto-update configuration in 2.1.1 to look out for future updates to the 2.1 series. If we need to do another patch in the future, STRIP's autoupdate/check-for-updates feature will catch it.

STRIP’s New TOTP Feature Explained

Permalink - Posted on 2014-05-22 18:55

It seems that in announcing STRIP's new support for generating time-based one-time passwords (also known as TOTP passwords or TOTP access codes) for use with two-step verification in popular web services like Dropbox and Google accounts we may have confused some of our customers on its utility and use. Two-step verification (also called two-factor authentication and multi-factor authentication) is an additional check performed when you log in to a web service to protect your account should someone else obtain your password. When two-step verification is in use the web service prompts you for an access code to verify that the person using your password is really you. Google has a good explanation of what it is and how it works over here.

There are two main ways that you obtain the six-digit access code to prove your identity to the service:

  1. The service sends you a six-digit access code (the TOTP password) via SMS
  2. You generate the six-digit access code using a key supplied by the service

How does STRIP fit in?

When enabling two-step verification (for example with Dropbox or Google) you are typically prompted to choose either receiving the codes via SMS or generating them yourself. If you choose the latter, you can simply paste the key supplied by the service into STRIP and it will begin generating six-digit access codes you can use to verify your identity. We've got a short screencast that takes you through the process of enabling two-step verification in Dropbox and configuring STRIP to provide the correct access codes:

Enabling Dropbox 2-Factor Authentication with STRIP for OS X from Zetetic on Vimeo.

Once you've saved the key to a TOTP field in STRIP the current access code will always be displayed on the record. The next time you need to supply the code on login to the service, just pop over to STRIP and copy the current code, no need to do anything else with they key.

Two-step verification is not used for logging into STRIP, we didn't mean to suggest that it was. To log into STRIP you only need to provide your master password as before.

If you are having trouble using the feature or any questions at all, please get in touch at support@zetetic.net.

STRIP 2.3.0 Released with Time-based One Time Passwords

Permalink - Posted on 2014-05-20 16:00

This morning we're excited to introduce the next revision to STRIP with a great new feature: Time-Based One Time Password (OATH TOTP) fields that generate one-time access codes for Google, Dropbox, AWS, Microsoft and other services that use compatible 2-step authentication. Available now for Android, iOS, OS X and Windows, just save a TOTP key from your service provider in a TOTP field after you update STRIP and you'll begin seeing access codes and a count-down timer.


Instructions for upgrading STRIP on all platforms are available here. If you're new to STRIP and you'd like to pick up a copy, head on over to getstrip.com.

Clipboard Timer for Android and iOS

Hot on the heels of our introduction of a preference to erase values copied to the clipboard after two minutes in STRIP 2.2 for OS X and Windows is a clipboard timer for Android and iOS, along with a matching preference to enable and disable the feature. Once you've exited STRIP the timer fires, clearing any data saved to the clipboard after two minutes.


STRIP for Android:

  • Adds TOTP support
  • Adds timer for clearing clipboard after two minutes
  • Fixes entry editor scrolling on KitKat

STRIP for iOS:

  • Adds TOTP support
  • Adds timer for clearing clipboard after two minutes


  • Adds TOTP support
  • Restores support for OS X Mountain Lion (by popular demand!)

STRIP for Windows:

  • Adds TOTP support
  • Disable sync menu when in edit mode
  • Add 4 and 8 hour autolock timeout periods within preferences
  • New toolbar/menu icons

Passwords 14

Permalink - Posted on 2014-05-19 17:45

Last year we learned about Per Thorsheim and Jeremi Gosney's Passwords conference, an annual and free conference on all things related to passwords, so I headed out to Las Vegas at the beginning of August to attend. It was such a fantastic, fun and deeply informative experience that this year we're heading back with our engineering team and are proud to announce our sponsorship of Passwords 14!

If you deal with passwords, password and security policies, hashing them, cracking them, protecting them with key-derivation, or you just want to know what makes a good password these days, this is the conference for you. Last year's single-track format never had a dull moment, with both high-level conceptual talks and in-depth demonstrations of newly-developed password hashing attacks—really some mind-blowing stuff even if you follow the topic regularly. Rare was the talk that did not involve oclHashcat at some point, and the Q&A sessions at the end of each talk were engrossing engagements. This year they'll be featuring two tracks of presentations, offensive and defensive, and I hear there's going to be a pool party! I'll let the guys give you the main pitch:

Passwords is the first and only conference of its kind, where leading researchers, password crackers, and experts in password security from around the globe gather in order to better understand the challenges surrounding digital authentication, and how to adequately address them. While large mainstream conferences tend to focus on current hot topics in the information security industry, Passwords events explore fringe conversations on everything from analysis and education to creating, securing, cracking, and exploiting authentication solutions. And unlike other events where the speaker is rushed in and out, Passwords provides an intimate environment for participants to directly engage speakers before, during, and after their presentations.

No need to register, Passwords 14 is being held at Tuscany Suites & Casino August 5-6th, so just book yourself a flight and a room.

Hope to see you there! Look for the guys wearing Zetetic shirts and say hello. Here's one of the talk from last year:

STRIP for Android Permissions

Permalink - Posted on 2014-04-21 14:18

STRIP for Android stores sensitive information, which may cause some to pause when they see the permissions required to run the application on their Android devices. STRIP for Android requires access to the Internet, access to your Google accounts, and telephone permissions to name a few. We would like to clarify the need for those permissions, and in doing so, explain a feature available in STRIP for those unaware.

STRIP for Android provides a mechanism when long tapping on any given field to allow you to perform context-specific actions on the data you store. For example, if you long tap on a URL, STRIP for Android will offer to launch that URL in a browser. Likewise, if you have a telephone number stored, a long tap will offer to dial that number for you. You can think of it as a quick action feature associated to the data you store, should you wish to invoke it. With regard to account access, that is to allow STRIP access to your Google Drive account, should you wish to perform backups/synchronize your data to your Google Drive account. That said, we do not make phone calls without your request, we also do not access your account information without your permission. An example of the context sensitive menu within STRIP for Android is shown below.

STRIP for Android Context Menu

With this, we hope you can use the quick action features within STRIP to streamline your experience within the application when accessing your information.

STRIP 2.2.1 for Android and OS X released

Permalink - Posted on 2014-04-15 14:02

This morning we're excited to pull the switch on two important updates to STRIP for Android and OS X. STRIP for Android is carrying numerous bug fixes we've been working on for a while and a new full-screen theme. STRIP for OS X has been updated to fix the previously noted data persistence bug and is now quite a bit more robust in that department.

To get the latest:


Bug in STRIP for OS X 2.2.0

Permalink - Posted on 2014-04-10 21:01

We've tracked down an ugly little bug in the latest update of STRIP for OS X, 2.2.0, involving data persistence for newly added or edited fields on entry records. While the bug itself has one main root due to a recent change in STRIP's plumbing, it can be demonstrated in a couple of ways outlined below. These bugs can be worked around and we have a bugfix release 2.2.1 in the App Store review pipeline now. With any luck we'll have the update in the Mac App Store next week.

Avoiding Data Loss

To edit a record in STRIP the customers clicks on the Edit button (or command+E) to begin editing. Edits to field values are not being saved immediately, but are being delayed until the user again clicks on Edit. Therein lies a good deal of the problem. If the customer chooses to then launch Sync before ending editing, or uses the "Create new label" feature the field values get whacked and are lost.

To avoid any data loss with STRIP 2.2.0 for OS X avoid using the Create new label feature until we get 2.2.1 out, and remember to end editing by clicking on the Edit button to ensure your chanages are saved. You can add new labels in the interim by going to the File menu and selecting Customize Labels.

STRIP 2.2.1 ensures edits are persisted to the encrypted database immediately as before. We apologize for the oversight, it's an embarassing bug.

If you would be interested in joining our private STRIP for OS X beta group, which will provide you with early access builds, please contact us at support@zetetic.net.

Heartbleed Security Statement for Tempo

Permalink - Posted on 2014-04-10 16:04

We've been working hard at Zetetic to assess the impact for our Tempo Time Tracking customers resulting from the recent OpenSSL security disclosure known as the OpenSSL Heartbleed bug.

This issue has undermined the security of many internet platforms by allowing attackers to read arbitrary memory from services using the popular OpenSSL library to provide secure communications over the web. This attack can allow extraction of private keys, session data, and user information from affected websites.

Web Security for Tempo

Zetetic's public Tempo web services do use OpenSSL, but are not secured by a version that is vulnerable to the Heartbleed attack. In addition Tempo utilizes Amazon Web Services, widely reported to be susceptible to the Heartbleed attack, but does not terminate SSL on the Elastic Load Balancers that were discovered to be vulnerable.

As a result, users who currently rely on Tempo for time tracking should not need to be concerned with Heartbleed exposure through the Tempo web sites.

Even though the Tempo services should not be directly affected, out of an abundance of caution, we have still taken the step of revoking and reissuing new SSL Certificates for all Zetetic web applications.


This is a good time to review the strength of your application passwords. You should change your Tempo password immediately if you:

  1. Are currently sharing the same password for Tempo as any other application

  2. Are currently using a weak password for Tempo that doesn't meet the recommendations below

We recommend using a strong alphanumeric password with a combination of upper case, lowercase, digits, and meta-characters of the maximum length possible to allow for convenient entry.

We take security seriously and we are happy to communicate with customers about the details of this issue, or how to take appropriate action, so please don't hesitate to contact us if you have any questions.

Heartbleed Security Statement for STRIP Password Manager

Permalink - Posted on 2014-04-10 15:19

Like most service and software providers, we've been working hard at Zetetic to assess the impact for our customers resulting from this week's OpenSSL security disclosure, commonly known as the OpenSSL Heartbleed bug. More specifically referred to as CVE-2014-0160, this issue has undermined the security of many internet platforms by allowing attackers to read arbitrary memory from services using the popular OpenSSL library to provide secure communications over the web. This attack can allow extraction of private keys, session data, and user information from affected websites.

STRIP, SQLCipher, and OpenSSL

Users of the STRIP Password Manager may recall that the application uses Zetetic's SQLCipher encrypted database library to protect all underlying application data. While SQLCipher does make use of OpenSSL, it only relies on low-level encryption interfaces. Since there is no use of OpenSSL's SSL functions, there is nothing that would expose SQLCipher or STRIP to direct attack via Heartbleed. More details on the use of OpenSSL in SQLCipher are available separately in our Heartbleed Security Statement for SQLCipher.

As a result, we're pleased to report that users who currently rely on STRIP for their data security need not be concerned with Heartbleed exposure on their local computers and devices a result of the software.

STRIP Cloud Sync

It's important to note that STRIP does provide a variety of optional synchronization features that use cloud services like Dropbox and Google Drive. Both of those services used affected versions of OpenSSL in the past, and may have been vulnerable to the Heartbleed bug.

STRIP's synchronization features do keep copies of the encrypted STRIP data on the cloud service. However, STRIP is very careful never to expose any unencrypted data to cloud services during synchronization. All STRIP data stored in Dropbox or Google Drive is fully encrypted using a strong encryption key derived from your master password.

While there haven't been any public reports of attackers using Heartbleed against Google or Dropbox, the nature of the bug make it possible that data on those services could have accessed without knowledge. However, since the database is fully encrypted at rest using STRIP, there is no risk of plaintext data exposure.


Even with STRIP's advanced protections, this is a really good time to review the strength of your master password, because STRIP's security really comes down to the security of your passphrase.

We recommend using an alphanumeric passphrase with a combination of upper case, lowercase, digits, and meta-characters of the maximum length possible to allow for convenient entry.

If you are currently using a weak password, especially in combination with Cloud sync, we'd strongly recommend that you change your STRIP password now to ensure the long term security of your data.

Finally, many internet sites have been affected by the Heartbleed bug, and are issuing statements suggesting that users change their passwords, log out of mobile applications, and reset authentication tokens, etc. Please take these notices seriously and update your credentials for affected systems as soon as possible.

We take security seriously and we are happy to communicate with customers about the details of this issue, or how to take appropriate action, so please don't hesitate to contact us if you have any questions.

Heartbleed Security Statement for SQLCipher

Permalink - Posted on 2014-04-10 15:16

Like most service and software providers, we've been working hard at Zetetic to assess the impact for our customers resulting from this week's OpenSSL security disclosure, commonly known as the OpenSSL Heartbleed bug. More specifically referred to as CVE-2014-0160, this issue has undermined the security of many internet platforms by allowing attackers to read arbitrary memory from services using the popular OpenSSL library to provide secure communications over the web. This attack can allow extraction of private keys, session data, and user information from affected websites.

We are pleased to report that SQLCipher is not directly impacted by the Heartbleed bug and subsequent disclosure. Many SQLCipher platforms, including SQLCipher for Mac OS X, Android, Xamarin.Android, ADO.NET, and Windows C++ do make extensive use of OpenSSL. However, they only utilize the low level "libcrypto" interfaces to access encryption algorithms. Specifically, SQLCipher's OpenSSL provider uses the EVP interfaces, random number generator, and PKCS5_PBKDF2_HMAC_SHA1. There is no use of OpenSSL's SSL functions, and thus nothing that would expose SQLCipher to direct attack via Heartbleed.

As a result, applications that currently rely on SQLCipher for local data security need not be concerned with Heartbleed exposure as a result of the SQLCipher library. Of course, application and service providers should be sure to carefully audit their software and infrastructure to ensure that there aren't other components or services that rely on affected versions of OpenSSL.

Finally, even though Heartbleed does not impact SQLCipher, we will include the latest OpenSSL 1.0.1g in upcoming releases of SQLCipher Commercial Edition for those customers using our commercially supported libraries to ensure dependency on the latest stable version.

We take security seriously and we are happy to communicate with customers about the details of this issue, so please don't hesitate to contact us if you have any questions.

STRIP for iPhone and iPad 2.2.2 Released

Permalink - Posted on 2014-03-31 16:27

We released a point update for STRIP for iPhone and STRIP for iPad today alongside today's update to STRIP for OS X. The new versions contain various bug fixes and a handy new improvement: a cancel button on the Sync view. STRIP for iPhone and STRIP for iPad are available now in the iTunes App Store (if you don't see 2.2.2 yet try again in a few minutes, the App Store doesn't always get the update out quickly after we Release.)


  • New Button to Cancel sync in progress
  • Fixes direct IP / Hostname view for WiFi Sync
  • Fixes masking switch on Note labels
  • Fixes login interface on device rotation
  • Fixes crash on resume when menu showing on iPad

If you're enjoying the changes we've been making or if you'd like to see more, please consider reviewing STRIP in the iTunes App Store and letting us know. If you have any issues whatsoever or if you'd prefer to get in touch with us directly please write us at support@zetetic.net. Thanks!

STRIP for OS X 2.2.0 Released

Permalink - Posted on 2014-03-31 15:55

Today we released STRIP for OS X 2.2.0, a major improvement over 2.1.0 in terms of stability, resource utilization and convenience. If you take a look at the image above you'll see some new additions to the interface—toolbar buttons! The icons for these were lovingly designed by Jory Raphael at SensibleWorld.com, and we'll be seeing more artwork from Jory in STRIP soon.

OS X 10.9 Mavericks Required

This version of STRIP requires a minimum OS X version of 10.9 Mavericks, do not install it without first upgrading OS X. STRIP for OS X 2.2.0 is sync-compatible with the previous version 2.1.0 allowing some time to upgrade, but with all the fixes in this update we're hoping you'll make the leap with us sooner than later.


Download STRIP for OS X from the Mac App Store. If you purchased the independent build of STRIP for OS X from Zetetic, simply launch the app and select "Check for Updates" from the STRIP menu in the menu bar if you are not prompted to update.

What's New

Toolbar: We probably should have added these buttons a lot sooner, but hopefully this is a reasonable initial set with obvious functionality. One of the buttons however, with the flashlight icon, does something new. This button (and the associated keyboard combo shift+command+M) allows you to quickly show and hide all masked fields on the entry view and we find ourselves using this all the time now.

Entry view: There's so much we have planned here but for now a minor update to the display of field labels and values along with a slew of fixes for the actions presented in the context menu when you right-click on a field (in view and edit modes).

Import: If you've ever tried to import a lot of records into STRIP for OS X via CSV (like say 500), it was very slow, consumed a ton of memory and was prone to crashing. All fixed up! Although, there is a hard limit of 998 records in one import at the moment. We'll be looking to fix that in future updates.

Memory use: Such memory leaks, many fixes. We'll be paying a lot more attention to this from here on out, making heavy use of profiling tools to manage resource utilization and ensure STRIP is a good citizen on the OS.

Sync: Some bug fixes here as well, along with a fully functional Cancel button. Sometimes there are errors on sync or the network connection is interrupted—you need to be able to cancel the operation and STRIP should handle errors gracefully.

Guts: We found some ugly bugs in how STRIP handled data persistence and put a lot of effort into fixing that up. We're constantly trying to improve and here's one area where we couldn't ignore code written three years ago. There will be no bit-rot in STRIP!

As always, if you have any questions or issues please contact us at support@zetetic.net. If you like this update to STRIP and want to see more please consider leaving a rating or a review in the Mac App Store, tell us what you'd like to see next.


  • Adds new timer to erase field values copied to clipboard after 2 minutes
  • Now uses internal, private pasteboard for copying category and entry records
  • Adds preference to sort labels alphabetically (defaults to enabled)
  • Adds new toolbar buttons
  • Adds Start Sync button to toolbar
  • Adds Password Generator button to toolbar
  • Restores global availability of Password Generator (shift+command+P)
  • Adds new show/hide all masked fields feature to toolbar and View menu (shift+command+M)
  • Adds right-click and keyboard command to launch selected field (command+return)
  • Adds shift+command+J for masking and revealing the selected field
  • Adds 4 and 8 hour intervals to preferences for Auto-lock
  • Includes minor improvements to entry view display
  • Fixes crash during import
  • Fixes poor/slow performance during import
  • Fixes memory leaks during import
  • Fixes memory leaks in main window interface
  • Fixes Auto-lock engaging during import for lengthy imports and shorter lock intervals
  • Fixes sync failure regression on passwords with a single-quote character
  • Fixes window restore location after Auto-lock
  • Fixes preventing access to Preferences window while locked
  • Fixes right-click commands on fields improperly mapped to selected row instead of click target
  • Fixes sorting of new and edited category and entry records to maintain alphabetic sort
  • Fixes any missing or duplicate replica IDs on sync
  • Fixes dysfunctional cancel button on sync progress sheet

Could SQLCipher Improve WhatsApp Security?

Permalink - Posted on 2014-03-19 18:54

WhatsApp, a popular cross platform messaging application, has been in the news recently, not only for the high-profile acquisition from Facebook, but also due to security concerns. A recently published article disclosed the WhatsApp database is exposed to third-party access and is not properly secured.

The Issues

The published analysis showed that WhatsApp can store both plain-text and encrypted databases on the SD card, where they could be accessed by malicious 3rd party applications. The only protection for the database is a simple AES cipher with an easily derived key, which leads to real security issues.

Because the database is encrypted as a whole, it’s very likely that at some point during application usage, the entire database itself must exist somewhere in a plain text form in order for the SQLite library to use it. This could pose a risk if the raw data became available to an attacker.

However, the most significant issue is that WhatsApp uses easily discoverable keys on the the encrypted database. Originally a static key was used to perform the encryption on all Android installations, though WhatsApp has now been updated to use a derived key based on the name of the email account on the device. In either case, this renders the encryption key available to applications running on the device, allowing exploits.

A Note on Key Management

Key management is a difficult issue, requiring careful consideration during application design. Storing the key directly within the application, or derived solely based on data on the device, is a poor practice. Decompiling a binary to access the key or determine the process used to create it is a rather straight forward process. Once the key has been identified, the data is at risk.

We strongly recommend that applications ensure that key data is provided by the user (e.g. a user supplied password). It’s fine to combine that with with device data to generate a password, but that is an additional precaution. It’s equally important to pass the key material through a key derivation function with a salt in to generate the actual key for encryption. This helps protect against dictionary and brute force attacks.

How SQLCipher Could Help

In the case of WhatsApp, SQLCipher can help address some of the factors above by providing a more secure environment for application data. Coupled with a user-supplied password or pin, SQLCipher’s built in security controls would automatically provide key derivation and encryption using a unique per-database salt. This would ensure that even if two databases are created with the same password they will not have the same encryption key. Furthermore, using SQLCipher, data is only decrypted as needed, decreasing the risk of plain-text data exposure. Finally, using SQLCipher would provide additional security features to ensure the integrity of the data, preventing tampering and closing off other potential attack vectors.

Many companies both small and large depend on SQLCipher to protect their data across a variety of platforms. Because WhatsApp is already using SQLite to store data, converting to use SQLCipher in its place would require minimal modifications, something WhatsApp might consider.

Tempo Maintenance, Tuesday February 27th at 9:00 PM EST

Permalink - Posted on 2014-02-26 22:52

This Thursday night, February 27th at 9pm EST, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we believe it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

Apple’s SSL/TLS Bug

Permalink - Posted on 2014-02-22 20:27

If you weren't already aware, Apple released iOS update 7.0.6 yesterday to patch a hole in their use of SSL/TLS that could allow an attacker to compromise encrypted communications. If you haven't updated your iOS devices you'll want to do so as soon as possible. A little bird tells me OS X updates are on the way next week, although I imagine that's no surprise and I've seen it speculated elsewhere.

There's a great explanation of the bug here by Adam Langley, but I'd like to point out an interesting comment by John Gruber on Daring Fireball where he links to Langley's post:

I don’t want to start a coding-style war, but I think this bug would not have happened if the code had been written using curly braces after the if statements.

I think there's no doubt about that. A little while ago I gave up my stubborn use of BSD-style in my C and Objective-C code and now wherever I see it I cringe a little and then go about fixing it up to be more "proper" in my mind. It's a nuisance, but worth it. For some time now, I think perhaps at the recommendation of Zed Shaw in his online book Learn C the Hard Way, I've been making sure to always use braces to encapsulate anything depending on an if statement or other conditional to avoid scenarios like the one that caused Apple's exploit. Other rules I now keep are no more braces on the next line, and avoiding blank lines. This gist should give a good example of what I mean, even though it's a bit silly:

I even use braces to encapsulate the branches of switch statements these days! I like to zap blank lines because I think it forces me to review code more closely; it's harder to skim and encourages me to keep things nice and DRY.

A minor aside: Learn C the Hard Way is really great even if you know C already. Worth a couple of hours, it's a fun read and good for tightening up your skills.

Update: I also avoid assignment operators in if statements, and I tend to keep conditional expressions very explicit. This way I know what in my code above, self.fugeez is a BOOL, or returns that type. If I want to check that a pointer is nil, then if (self.fugeez == nil), not if (self.fugeez). If I want to test that my BOOL fugeez is false, then if (self.fugeez == NO), an explicit comparison. Just makes it easier to see what's going on later. I'm not quite as religious about this, but I'm trying to stick to it and adjust where I see my old ways.

Strong Password Hashing for ASP.NET, 2014 Refresh

Permalink - Posted on 2014-02-17 19:39

As a follow-up to the original Zetetic.Security library that adds PBKDF2 and BCrypt-based HashAlgorithms to .NET, we're pleased to announce the release of Zetetic.Security, which provides options for greater work factors when generating password hashes.

The original hash implementations use 5,000 rounds of PBKDF2, and a BCrypt work factor of 10^10.  The 1.1 release adds support for 64,000, 128,000, and 256,000 rounds of PBKDF2, and BCrypt work factors from 10^11 to 10^16.  As before, the best way to use these hash algorithms is by installing Zetetic.Security to the Global Assembly Cache, and updating machine.config to register the new classes.  (Hint: you can find the path to the effective machine.config file in System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile).


Once installed and registered, the new HashAlgorithms can be used in code as per the following sample (I wrote this one in LinqPad for simplicity's sake):

Of course, bear in mind two important caveats before updating your applications to use any new password hashing strategies:

1. .NET MembershipProviders don't have any way to know what HashAlgorithm generated any particular user's hashed password in storage.  Therefore, changing the hash algorithm will cause your users' logins to fail until they reset their passwords.

2. A stronger hashing algorithm is likely to eat up significantly more CPU cycles.  Plan accordingly so that applying 10^16 rounds of BCrypt doesn't open the door to a denial-of-service attack (or blow your AWS or Azure budget!).

Download from Github

View on NuGet

STRIP Status Update

Permalink - Posted on 2014-01-28 20:12

At our STRIP meeting today we discussed providing more regular, up-to-date information about what versions of STRIP are currently available and what's on the way, a sort of status page. We haven't decided exactly how we'll implement this but for now we'd like to provide an update here on the blog.

STRIP for iOS 2.2.0 - Released - Jan 22, 2014

Minimum iOS version: 6.0

  • Features a new interface customized for iOS 7
  • Various bug fixes, minor feature improvements
  • Sync-compatible with 2.1.0
  • Crashes on sync with Google Drive on 64-bit devices

STRIP for Android 2.2.0 - Released - Jan 22, 2014

Minimum Android version: 2.1

  • Various bug fixes, minor feature improvements
  • Sync-compatible with 2.1.0

STRIP for Windows 2.1.0 - Released - Nov 12, 2013

Minimum Windows version: Windows XP

  • Updates encryption engine to SQLCipher 3
  • Increases PBKDF2 key derivation from 4,000 to 64,000
  • Requires min version 2.1.0 for sync

STRIP for OS X 2.1.0 - Released - Nov 12, 2013

Minimum OS X version: 10.6 Snow Leopard

  • Updates encryption engine to SQLCipher 3
  • Increases PBKDF2 key derivation from 4,000 to 64,000
  • Requires min version 2.1.0 for sync

STRIP for iOS 2.2.1 - Submitted

Minimum iOS version: 6.0

  • Awaiting review from Apple
  • Fixes crash on 64-bit devices during Google Drive sync

Tempo Maintenance, Tuesday January 28th at 10 PM EST

Permalink - Posted on 2014-01-27 20:53

This Tuesday night, January 28th 10pm EST, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we believe it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

STRIP 2.2.0 for iOS and Android Released

Permalink - Posted on 2014-01-23 17:12

We just released STRIP 2.2.0 in the iTunes App Store and the Google Play store for Android. The iPhone and iPad versions feature a new interface adapted to iOS 7, and both iOS and Android versions bring various bug-fixes, stability improvements, and minor feature updates and adjustments. We're quite curious to hear what our customers have to say about the new look, so we'll spare you the screenshots and ask that you go check it out and tell us what you think.


STRIP 2.2.0 is sync-compatible with all versions of STRIP 2.1.0. For iOS versions, the new minimum OS version is iOS 6.0. For Android versions, the minimum OS version remains Android 2.1.

iOS changes:

  • Clean, elegant new iOS 7 style user interface
  • 64 bit support for newer iPhone and iPad devices
  • Allow sorting of field labels alphabetically
  • Moves auto-lock settings to encrypted database
  • New preference to clear pasteboard on exit
  • Allows masking of note fields on entry view
  • Fixes issue where backup database might not properly be removed
  • Fixes issue authorizing Drive sync with 2-step authentication
  • Fixes keyboard switching login bug

Android changes:

  • New integrity check feature in Settings
  • Secures STRIP from screenshot capture during application switching
  • Various bug fixes and stability improvements

Download the latest:

Note: Amazon 2.2.0 version update may take a little while to appear in the Amazon App Store for Android, if it's not available now please check again later.

Introducing SQLCipher for Windows Phone 8 and Windows Runtime

Permalink - Posted on 2014-01-13 15:59

We are happy to announce the immediate availability of new SQLCipher Commercial Edition packages for Windows Phone 8 and Windows Runtime 8/8.1. Over the past year, interest and adoption of these platforms has increased dramatically, and SQLCipher is now able to provide a quick and easy way to secure application data. This is particularly exciting because SQLCipher libraries now offer a common, interoperable, secure database solution across major mobile, tablet, and desktop platforms.

Application Integration

The new SQLCipher libraries integrate seamlessly within Visual Studio. The client API based is on the popular sqlite-net library that provides a compact ORM and both synchronous and asynchronous interfaces. As with other integrations, applications use the high level API to manipulate data using the ORM and/or SQL, while SQLCipher works behind the scenes to manage all aspects of security, including key derivation and on-the-fly encryption and decryption of the database pages.

This architecture supports rapid implementation on both platforms, and applications that already use SQLite on Windows Phone or Windows Runtime can be converted to SQLCipher in as little as a few hours. Application using these new SQLCipher libraries for Windows Runtime can easily inter-operate and access SQLCipher databases generated on other platforms, including iOS, Android, and Windows Desktop. Furthermore, both packages include CipherCare Plus, providing prioritized and confidential email support directly from the SQLCipher development team to help integrators get up and running quickly.

Technical Details

SQLCipher for Windows Phone 8 and Windows Runtime are based on the latest version of SQLCipher 3, and take advantage of many of the newest features. For example, porting SQLCipher to run on Windows Phone 8 and Windows Runtime introduced some unique challenges. On some other platforms, SQLCipher relies on OpenSSL for underlying cryptographic operations, however, it is not easily supported on either Windows Phone 8 or Windows Runtime. Thus, the new packages take advantage of SQLCipher's pluggable crypto providers, allowing the use of LibTomCrypt's AES implementation and the Fortuna PRNG. Particular care is taken to seed the PRNG entropy pool with a rich, externally sourced cryptographically secure random data block, which is feed into the the crypto provider using the new PRAGMA cipher_add_random. Finally, databases created using SQLCipher benefit from strong default key derivation using 64,000 iterations of PBKDF2 to protect against brute force and dictionary based attacks.

Get Started

SQLCipher continues to support critical application developer requirements for easy to use data storage security. If you are interested in using SQLCipher on Windows Phone 8 or Windows Runtime, please checkout our Commercial Edition page to order now or request a trial. If you have any questions reach out to us and we'd glad to help!

STRIP Holiday Sale - 40% Off Until New Year’s Day 2014

Permalink - Posted on 2013-12-20 23:12

Since a lot of our customers are buying new devices this time of year and inquiring about discounts for STRIP (as well as being kind enough to tell their friends about our password manager), we figured it's time to do a sale. Starting this evening until New Year's Day 2014, all versions of STRIP are on sale at 40% discount. That's Windows, OS X, Android, iPhone and iPad. That's a big discount!

Android and iOS

Just visit the store links, you'll see STRIP for Android, iPhone and iPad are all available now for only $2.99:

Windows and OS X

STRIP for Windows and STRIP for OS X can be purchased at 40% off ($6! A bowl of delicious Pho!) using the coupon code STRIPHOLIDAY2013. Visit the links below to purchase either app with the discount applied:

STRIP for OS X is also available in the Mac App Store at 40% off.

Pass It On!

Have a colleague, friend or family member using the same password for everything? Someone who wants a rock-solid password manager that's tried and true? Please forward this discount to whomever you like, it's good until New Year's Day.

Tempo Maintenance, Monday December 16th at 10 PM EST

Permalink - Posted on 2013-12-16 14:33

This Monday night, December 16th 10pm EST, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

SQLCipher 3.0.1 Release

Permalink - Posted on 2013-12-06 19:55

This release contains a fix for the PRAGMA cipher_migrate feature we added with the 3.0.0 release. A migration issue existed when a passphrase that was longer than 64 characters, or a raw hex key was provided which caused a failure during migration. In addition to the bug fix, we've added a new PRAGMA called cipher_add_random that allows one to add externally sourced entropy to the entropy pool of your configured crypto provider. Currently there is support for this via the OpenSSL and libtomcrypt providers. The format must be provided as blob literal containing a hex sequence. An example would look like this:

sqlite> PRAGMA key = 'test';
sqlite> PRAGMA cipher_add_random = "x'deadbaad'";

Please take a look at the 3.0.1 release and let us know if you have any questions or feedback.

Tempo Maintenance, Sunday November 17th at 10 PM EST

Permalink - Posted on 2013-11-15 18:51

This Sunday night, November 17th 10pm EST, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

STRIP 2.1.0 Released

Permalink - Posted on 2013-11-12 14:46

This morning we've released STRIP 2.1.0 for all versions of STRIP in the various App Stores and made it available via auto-update in the desktop apps. This version of STRIP includes a major security upgrade and is not backwards compatible or sync compatible with earlier versions of STRIP. Thus, you should be prepared to upgrade all copies, and please back up your data before proceeding.

Important Upgrade Notes

Instructions for updating each STRIP are available on our FAQ.

  • Please backup your mobile devices and desktop databases before upgrading, either via WiFi, Dropbox, or Google Drive.
  • When you log in to STRIP 2.1.0 for the first time the database format will be updated. Due to database file and feature improvements, STRIP 2.1.0 will not sync with earlier versions of STRIP. Therefore, you should plan to update all of your devices and applications to STRIP 2.1.0 at around the same time. More information is available on our upgrade FAQ.

What's New

STRIP 2.1.0 features our updated SQLCipher encryption engine, and increases the number of PBKDF2 iterations used to derive your database key from 4,000 to 64,000, providing substantial security gains against increasingly sophisticated brute-force attacks. 

STRIP for Android

  • Increases PBKDF2 iterations from 4,000 to 64,000
  • Upgrades SQLCipher to version 3.0.0
  • On the fly searching - search as you type
  • Sync with other copies of STRIP requires minimum version of 2.1.0

STRIP for Windows

  • Increases PBKDF2 iterations from 4,000 to 64,000
  • Upgrades SQLCipher to version 3.0.0
  • Sync with other copies of STRIP requires minimum version of 2.1.0
  • Fixes ObjectDisposedException during data import


  • Increases PBKDF2 iterations from 4,000 to 64,000
  • Upgrades SQLCipher to version 3.0.0
  • Sync with other copies of STRIP requires minimum version of 2.1.0
  • Fixes erroneous caching of field value heights on record view
  • Fixes truncation of long notes in view
  • Adds a Choose button to password generator view, corrects value copy into editor
  • Fixes masking of newly created fields after editing is completed
  • Auto-lock timer now stores setting in the encrypted database to prevent tampering
  • Adds preference to lock STRIP on start of screensaver and screen lock


  • Increases PBKDF2 iterations from 4,000 to 64,000
  • Upgrades SQLCipher to version 3.0.0
  • Sync with other copies of STRIP requires minimum version of 2.1.0
  • Uses Apple's CommonCrypto for hardware-accelerated cryptography
  • Fixes crash adding date fields on iPad version
  • Prompts for current password before allowing password reset
  • Fixes appearance of "Export Data..." button on Lite version
  • Changes minimum supported OS to iOS 5.0 for iPhone versions (still 6.1 on iPad)

SQLCipher 3.0.0 Release

Permalink - Posted on 2013-11-11 22:14

We're excited to announce that SQLCipher 3 is now available. This release includes several substantial improvements:

  • New default key derivation iteration count of 64,000, a 16x PBKDF2 work factor increase over the previous version
  • New PRAGMA cipher_migrate, a simple utility command to upgrade an existing 1.x or 2x. database in place
  • New sqlite3_key_v2 and sqlite3_rekey_v2 functions to allow keying and rekeying of named databases
  • New ATTACH behavior, requiring an explicit key to be passed for encrypted databases
  • Extended Raw Key/Salt feature, making it possible to set both the encryption key and database salt via a raw key specification
  • Based on SQLite, a recent stable release of SQLite

Detailed notes about the differences are available in the original SQLCipher 3 beta announcement post.

It's important to note that these key derivation changes enable a much higher level of security than previous versions though, by default, SQLCipher 3 will not open older database. To enable backwards-compatibility, it is possible to adjust settings at runtime or migrate older databases:

  1. To open an older database using SQLCipher 3, set the KDF iterations back to the old value of 4000 using PRAGMA kdf_iter = 4000
  2. To attach and export data to a new database, use the sqlcipher_export() convenience function
  3. To migrate and upgrade an existing database in place, use the new PRAGMA cipher_migrate feature

Finally, as a result of the increased key derivation count, users may notice that opening and keying a database takes longer in SQLCipher 3 than with previous release. Noticeable performance issues can almost always be avoided by ensuring that applications do not frequently open and close connections. That said, while we strongly recommend using the new default KDF settings, it is possible to set the default back to 4,000 iterations before any databases are open by calling the global PRAGMA cipher_default_kdf_iter = 4000; before invoking the SQLCipher library.

The latest source code can be found in the official project repository, and SQLCipher Commercial Edition libraries are already available in the SQLCipher Store. Commercial edition customers with CipherCare may contact us with their original order number for details on how to download an update.

Please take a look, try out the new library changes, and let us know if you have any feedback. Thanks!

STRIP Update Fall 2013

Permalink - Posted on 2013-10-31 17:16

STRIP is our password manager—we put a lot of love and work into it, we want it to be as secure and easy to use as possible, we really want it to be the best password manager out there. But we don't usually publish our long-term plans because we like to set our own timelines and we don't want to over-promise and under-deliver. STRIP is a pretty big project, involving four native applications that sync together, so our planning process is quite careful and iterative. This can give the impression that we're moving slowly when we're actually doing a ton of work behind the scenes. Since folks are asking a lot lately, we'd like to tell you about the next version of STRIP, and provide some insight on where we're going from here.

STRIP 2.1.0

The next, soon to be released version of STRIP for all platforms is version 2.1.0. We've been testing it all summer alongside a major update to our encryption engine SQLCipher. We're preparing the iOS and Mac versions for app store review now and hope to release all versions simultaneously (including Windows and Android) as soon as we're approved for release. This version will be available for free to upgrading customers.

Here's what you should know about STRIP 2.1.0:

  • It increases the number of PBKDF2 SHA-1 iterations used to protect your database key from 4,000 to 64,000
  • We believe this change is critical to protecting our customers from increasingly sophisticated attacks
  • It is not backwards compatible, once the database is upgraded it cannot be used with older versions
  • It will not sync with earlier versions of STRIP, you'll need to upgrade STRIP on all your devices
  • It's important that you upgrade to this version for future compatibility

This change to your encrypted database is an enormous gain in security at a time when powerful, well-funded organizations as well as individuals and researchers are developing sophisticated means for attacking encryption systems, and in particular brute-forcing passwords. With computing power increasing rapidly it is time to make attacks on STRIP's encryption literally more expensive, massively so.

Some additional things to note about the iOS and OS X versions:

  • iOS versions now use Apple's CommonCrypto library for hardware-accelerated encryption
  • The iPhone version supports iOS 5 up to iOS 7
  • The iPad version supports iOS 6.1 up to iOS 7
  • The OS X version supports OS X 10.6 up to OS X 10.9

We had to drop support for iOS 4.3 finally, because CommonCrypto hardware acceleration support is not available to us there, and it's absolutely necessary due to the increase in PBKDF2 iterations on the database key. Hopefully anybody still running 4.3 out there has the ability to upgrade to the latest iOS. We realize that's not everybody, but numbers suggest there are very few folks in that position, and we do have a contingency plan for anyone who does (if that description fits you, please get in touch with us soon.)

It's important that you upgrade to 2.1

Device and sync compatibility are really important to us and minimizing disruption is best for our customers. In STRIP 2.2 we won't be changing the database format again, but we may start changing the minimum supported OS versions of the various apps as we seek to improve them and take advantage of new APIs. This means that STRIP 2.1 running on older devices that either can't upgrade STRIP to 2.2 or can't upgrade to the latest version of their OS in order to upgrade will remain sync-compatible with STRIP 2.2, allowing us to proceed with needed enhancements without leaving customers on 2.1 out in the cold.

That's why we think you should upgrade as soon as possible, once STRIP 2.1 is released. We've been testing this upgrade for many months to make sure we've got it right, and we'll be standing by to help if there are any issues.

STRIP for iPhone and iPad version 2.2

STRIP for iPhone and STRIP for iPad are going to get face-lifts for iOS 7, we're working on them now and we think you're really going to enjoy the change, it's already a pleasure for us as we work on it, make changes, and test. Here's a sneak peak at the Sync screen in progress:

Work in progress, not final by any means

We're revisiting all of our interfaces as we go over them, to see if we can do a better job, and that was certainly the case for the Sync view. I always wanted to provide better indicators of current sync status. Not only is it a pleasure to watch the red-tinted progress bar zoom across the screen, this will be a big help when debugging issues with our customers by providing them with more information.

This version will also be available for free to upgrading customers.

What's Next

Image and media storage is one of our biggest and oldest feature requests, and we've already done some proof-of-concept work there. It presents challenges in speed and efficiency when it comes to sync operations. Another of our biggest feature requests is background sync—it should just work. And the other biggest feature request is sharing databases—allowing you to decide which of your data you share with whom, with seamless synchronization of your records. The magic word here is sync.

These are not easy problems to solve well and we want to make sure we get it right in the experience department, in making STRIP as easy to use as possible while providing these great new features. On top of that, we need to make sure we maintain and improve the high level of security and diligence our customers have hopefully come to expect from us. Putting aside the interface changes, what we need is a new sync system. We think solving these problems together is critical to providing the best version of STRIP yet, and work is already underway. We call it STRIP 3 and it's pretty much where we've always wanted to take the app, ever since we launched as a stand-alone app on the iPhone.

Beta Testing

Want to help us make STRIP better? Please consider joining our beta testing program. We're looking for testers who are excited to run the latest betas as we go forward, test with (backed up) real-world data, and provide lots of feedback. If that sounds like you, please get in touch!

STRIP Tips: Launching SSH Logins

Permalink - Posted on 2013-10-30 18:22

This is a quick post about STRIP, our password manager, and how you can use it to make life a little easier. Say you have a Foo Web Services account and you run virtual machine instances there—you'd typically store three pieces of information in STRIP so that you can log into the console and access your instances:

  • username
  • password
  • web browser console login URL

Thus when you need to log in, you can just pull up STRIP, start typing the record name, quickly copy the password and then double click on the URL to launch it in your browser to get going:

Okay, nothing new there, right? But maybe the reason you're logging in to the Foo Web Services console is because you need to get the DNS names for your virtual machine instances so you can log in to one or more of those servers via SSH. Now it's a nuisance, now you have to copy each URL out of the web interface and into your Terminal.

But STRIP can take care of this for you, cutting out the step to your web console, by using URL fields. Let's create a new label just to make clear what's going on here by going to the File menu and selecting Customize Labels, which produces a sheet showing all your labels in STRIP:

Create a new label, name it SSH for now, and set the Mode to "url," then click Done to dismiss the Customize Labels sheet.

In our Foo Web Services record we'll add a new field for each of our virtual machine instances, setting the label to SSH for each. If we use the SSH URL connection string format in the field itself, ssh://user:password@hostname:port, we'll be able to double-click these fields to launch SSH connections in Terminal (or the preferred SSH app/client on your computer/device). In the following screen, I've added two such SSH urls:

  • ssh://frank@ec2-not-a-real-node1.compute-0.fws.example.com
  • ssh://frank@ec2-not-a-real-node2.compute-0.fws.example.com

Now when I double-click these fields on the record in STRIP my operating system offers to launch to launch Terminal for me (with a warning, I should add):

After I click Allow, a new Terminal window launches and fires up an SSH connection so I can do whatever I normally do to verify my identity (password login, public key, etc). 

This also works on iOS or Android if you have an SSH client installed. Simply tap on the URL fields in STRIP for iOS or Android to get the option to launch the URL in your preferred SSH app:

(Yes, that's a sneak preview of the iOS 7 interface, don't hold us to it, work in progess!)

When I tap on Launch SSH, iOS opens up an app on my device that's registered for handling ssh: connections, in this case it's good old TouchTerm:

As you can see, TouchTerm attempts to open the connection with the details supplied in the URL string (and in the case of example.com, gives up for good reason).

Creating labels with a mode of url is a powerful way to make it easy for you top pop into STRIP and fire up a connection to a system that requires credentials you've stored in STRIP.

Off-topic: have a favorite SSH client for iOS or Android that we should check out? Feel free to leave comments! 

iOS 7 Compatibility Issue: Keyboard Switch and Password Masking

Permalink - Posted on 2013-09-22 17:10

We've become aware of a compatibility issue with STRIP running on iOS 7 that is affecting users who switch between the numeric and text keyboards during login. The problem occurs when toggling between the "abc" and "123" modes while the Mask on. When switching between keyboard modes with the application switch, the contents of the password entry box is cleared. If you don't realize that the password box has been cleared, this have the appearance of being unable to log in following on iOS 7.

For example, with a mixed password of "6789abcd", one might start off in the numeric entry mode to enter the first part of the password. However, under iOS 7, if one were to tap the "abc" toggle to switch into the standard keyboard mode to enter the remainder of the password, the contents of the password field would be cleared, removing the 6789 from the password text field. A user who didn't notice this could continue entering text, but only "abcd" would be passed into STRIP, resulting in an incorrect password error.

The good news is that there are two simple workarounds for this issue that will allow you to log into STRIP:

  1. Our recommended approach is to use only the "abc" mode to log in for the time being. To do this, switch the mode to "abc", then tap the "123" button in the bottom left corner of the iOS keyboard to bring up the numeric keyboard. The numbers will be arranged across the top of the keyboard. Enter any digits, then tap the "ABC" button on the bottom left of the keyboard to toggle back to text.
  2. If you are in a secure location where other people can't observe your screen, toggle the "Keep password hidden" switch to "off". While the Mask switch is off the keyboard toggle will operate normally.

We are treating this as a high priority issue and will make sure there is a fix for this issue in the next release of STRIP. Please contact us at support@zetetic.net if you have any questions or other issues.




Permalink - Posted on 2013-09-18 14:53

Update: We've become aware of a minor issue with iOS 7 that may cause difficulty loggin in if you use the application "abc / 123" keyboard switch. Please read this follow-up post for information on this issue and simple fixes.

Here at Zetetic we're always on alert when a new iOS version is released, and iOS 7 is upon us. We've seen our password manager STRIP through four previous major upgrades to iOS (from iPhoneOS 2 to iOS 6) and we've learned a few things over that time. If you are preparing to upgrade to iOS 7 and are wondering if STRIP is ready and what you need to do, this post is for you.

Ready to Rock

We've been testing STRIP 2.0.3 (the current version in the iTunes App Store) on iOS 7 for some time now, and we're pleased to report that the app works just fine as it is. It looks and works just the same as before. We've worked hard to see if there are any bugs lurking, and there very well may be some, but so far so good, STRIP is ready. The next major version of STRIP (2.1.0) has also been extensively tested on iOS 7 and we hope to submit that for release soon, as it contains significant improvements for protecting your data along with various minor features and adjustments. Stay tuned for that in the coming weeks.

Take a Backup Before You Upgrade

Major upgrades to iOS involve backing up your data, installing the new version of iOS, and then restoring your data. If the restore does not complete, you could be left with missing data (music, apps, etc) after the upgrade. Usually repeating the restore part of the process takes care of that, but we advise that you to take your own backup of your device's and STRIP's data before beginning the iOS upgrade process.

If you use STRIP's sync functionality to replicate your data to Dropbox, Google Drive, or a desktop over WiFi, you already have another snapshot of your data you can use to restore STRIP in the event that the iOS upgrade wipes out your data. If you haven't synced STRIP to one of these targets, or it's been a while, do a fresh sync before starting the iOS upgrade so the data in your backup is up-to-date.

You can also backup your entire device to iTunes or iCloud for restore after the iOS upgrade. We strongly encourage you to do this as well. Apple provides updated, step-by-step instructions on backing up and restoring via iTunes and iCloud.

One thing we'd like to point out is that a Restore post-upgrade is part of the iOS upgrade process. Your music, data, and third-party apps are restored (somewhat slowly) after the upgrade and after the device becomes available. If you are upgrading via iTunes, be sure to watch the iTunes display and do not disconnect your device from your computer until the restore completes fully.

Send Us Your Feedback

After you upgrade to iOS 7, please give STRIP a shot and let us know how it goes. If you have any problems at all, please reach out to us directly at support@zetetic.net, we'll be standing by. Feel free to leave comments on this post, let us know how the app is running on iOS 7 and if you have any ideas for improvements.

SQLCipher 3.0.0 Beta Release

Permalink - Posted on 2013-09-03 18:05

We are happy to announce the SQLCipher 3.0.0 beta release. Included with this release are the following:

  • New default KDF iteration count is 64000, up from 4000
  • New PRAGMA cipher_migrate
  • New sqlite3_key_v2 and sqlite3_rekey_v2 functions
  • New ATTACH behavior
  • Extended Raw Key / Salt feature
  • Based on latest SQLite

KDF Changes

With this release the default iteration count used for PBKDF2 is 64000, up from the previous default of 4000 - an increase of 16 times our previous cycle count. The intent of this change is to provide an increased level of security and protection from brute force attacks by extending the work factor needed to derive a database key.

PRAGMA cipher_migrate

The KDF default iteration change establishes a new standard database setting, and thus existing databases must be migrated to the new version. To ease the process, we've introduced a new PRAGMA that will aid in the conversion process from an old SQLCipher database, given that default configurations were previously used during creation.

Below shows an example of migrating a 2x SQLCipher database to the new 3.0.0 format. SQLCipher will upgrade the database in place:

> ./sqlcipher 2xdatabase.db
> PRAGMA key = 'YourKeyGoesHere';
> PRAGMA cipher_migrate;

The cipher_migrate PRAGMA can migrate both standard SQLCipher 1.x and 2.x databases. Note that if non-default settings, such as a different cipher or kdf_iter were used in the original database, a manual migration would be required with the use of sqlcipher_export.

SQLite API Additions

In SQLite 3.8.0 sqlite3_key_v2 and sqlite3_rekey_v2 were added; specifically they introduce the alias name of the database during key and rekey operations. This further becomes available when accessing key and rekey commands via PRAGMA. To show an example scenario we will explicitly key the attached database using a separate PRAGMA command:

> ./sqlcipher database.db
> ATTACH DATABASE ‘new.db’ as new;
> PRAGMA new.key = ‘foobar’;

Attach Changes

This release also changes the behavior of the ATTACH command. In previous versions, you could attach a database using same password as the main database by leaving the optional KEY parameter off of the ATTACH statement. For instance, the following statement would attach a database using the same password as the main database, but derived using the attached databases salt.

ATTACH ‘new.db’ AS new;

In the new version, ATTACH will not re-derive a key unless it is explicitly provided via the KEY parameter, like so:

ATTACH ‘new.db’ AS new KEY ‘password’;

In practice, this means that calling applications will need to provide the key on the ATTACH parameter, via sqlite3_key_v2, or PRAGMA .key, in order to set passphrase, or the salt and derived encryption key from the main database will be used instead.

The change to ATTACH is supported by a new feature for providing raw key material. In the new version, it is now possible to provide both a raw encryption key and a raw salt header value in the key using BLOB notation:

If the raw key data is formatted as x'hex' and there are exactly enough hex chars to fill the key (i.e., 64 hex chars for a 256 bit key) then the key data will be used directly. If the raw key data is formatted as x'hex' and there are exactly enough hex chars to fill the key and the salt (i.e 92 hex chars for a 256 bit key and 16 byte salt) then it will be unpacked as the key followed by the salt.

This allows a caller to specify a matching raw key and salt combination that can later be derived from a passphrase.

Together, these change allows SQLCipher to securely wipe the source passphrase from memory after key derivation.

SQLite Changes

Along with all the changes to SQLCipher, the source is now based off the latest SQLite source. This release includes support for the new next generation query planner, partial indexes as well as an addition of the notindexed option within FTS4.

The source for SQLCipher 3.0.0 can be found here, we have included SQLCipher for Android binaries here. Please take a look and let us know if you have any feedback, it is always welcome!

SQLCipher for Android 2.2.2 Release

Permalink - Posted on 2013-08-28 16:28

Google has recently confirmed that there is a serious issue with improper seeding of the pseudo-random number generator (PRNG) found on some versions of the Android platform. As a result, we've released a new version of SQLCipher for Android which addresses potential risks introduced by this vulnerability. SQLCipher for Android 2.2.2 binaries can be found here.

The issue itself centers around improper default initialization of the OpenSSL PRNG; specifically, it appears from the fix that /dev/urandom was not included in the seeding process to the entropy pool. This increases the likelihood that low-entropy data could be provided when requesting random data from calls to OpenSSL’s RAND_bytes.

Previously, SQLCipher for Android was dynamically linking the system provided version of the OpenSSL library on the device. This means that SQLCipher was using the version of OpenSSL on affected platforms. This reduced complexity and allowed for a smaller binary payload when integrating the library into an application. Unfortunately, it also means that older versions of SQLCipher used the affected versions of OpenSSL on those Android versions.

To address this issue, SQLCipher for Android will no longer rely on Android’s system-provided OpenSSL library. Instead, new binaries statically link the 1.0.1e tag of OpenSSL, currently the latest release. We have verified locally that OpenSSL 1.0.1e includes data from /dev/urandom in the entropy pool during initialization. This change has the added benefit of normalizing behavior, as there are outdated distributions of OpenSSL embedded in certain Android platforms. We estimate that the statically linked library will add 1.0 MB to most ARM-only applications, although it could be as high as an additional 2.3 MB if other architectures are supported (e.g., x86).

SQLCipher relies on random data for two purposes: initial generation of the random database salt, and generation of per-page initialization vectors (IVs) for AES-256-CBC encryption. Happily, neither usage will result in catastrophic failure, as was the case with Bitcoin wallet applications, where poor randomness led to the generation of weak asymmetric keys. That said, it is likely that existing databases created on older Android platforms will have low-entropy salts and IVs. Theoretically this weakness in the underlying PRNG could facilitate optimized attacks in certain circumstances.

As a result, we strongly recommend that you upgrade to the latest SQLCipher for Android binaries as soon as possible. Out of an abundance of caution, we’d also recommend that those concerned with the security of existing databases generated on affected Android platforms perform a database export via the sqlcipher_export convenience function to re-encrypt the database. This process will generate a new random database salt and initialization vectors for all pages in the database.

If you have any questions, please feel free to ask. Thanks!

Tempo Maintenance, Thursday August 22nd at 10 PM EDT

Permalink - Posted on 2013-08-21 21:22

This Thursday night, August 22nd at 10pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

STRIP for OS X 2.0.2 Released

Permalink - Posted on 2013-07-24 17:32

STRIP for OS X version 2.0.2 is now available in the Mac App Store, providing numerous bug fixes and adjustments. We recommend all customers install this update. Among the changes in this release:

  • Fixes disabled editor due to untitled labels 
  • Fixes persistence of changes to fields and sort order
  • Fixes crash on login when last-accessed entry is no longer available 
  • Fixes display of WiFi sync service status in Preferences after launch 
  • Fixes add field control on first launch creating untitled label 
  • Fixes crash on export due to untitled labels

Customers who're using the version of STRIP for OS X purchased from the Zetetic store will also see the update shortly. Select the STRIP menu and choose "Check for Updates" if automatic update checking is disabled under Preferences.

Tempo Maintenance, Thursday July 18th at 10 PM EDT

Permalink - Posted on 2013-07-17 18:10

This Thursday night, July 18th at 10pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

SQLCipher for Android - Urgent Upgrade Required

Permalink - Posted on 2013-07-10 21:27

The latest release of SQLCipher for Android includes a high-priority fix to address a compatibility issue with an upcoming Android OS release. When the new Android version is released, most likely later this year, applications using older SQLCipher for Android versions may crash on first use of the library.

We have been working closely with Google to address the problem, which stems from changes to android::MemoryBase, a wrapper around the Android shared memory functions previously used in the native CursorWindow implementation. The new version of SQLCipher for Android eliminates the use of android::MemoryBase in CursorWindow in favor of allocated heap memory.

Google has confirmed that the latest version of SQLCipher for Android addresses the compatibility issue with the new Android OS version.

Since applications that continue to access the legacy shared memory function will break at some point in the future, Google has recently introduced a warning trigger on API usage in a recent AOSP commit [1].

As a result of this upcoming change, we strongly urge all developers using SQLCipher for Android to upgrade to the newest version. We do not have a specific release date from Google, so it’s important that applications update as soon as reasonably possible.

The latest SQLCipher for Android binaries can be found here [2].

1. https://android-review.googlesource.com/#/c/61890/
2. https://s3.amazonaws.com/sqlcipher/SQLCipher+for+Android+2.2.1.zip

SQLCipher 2.2.1 Release

Permalink - Posted on 2013-07-10 17:08

We would like to announce a patch release of SQLCipher. It includes the following:

  • Addresses a potential threading issue when copying the cipher provider.
  • General improvements to the lifecycle of the provider.
  • Applied a mutex around RAND_bytes for OpenSSL usage to prevent concurrent calls in applications that have not configured OpenSSL threading callbacks.

The latest source can be found here [1] along with new SQLCipher for Android binaries here [2].

[1]. https://github.com/sqlcipher/sqlcipher
[2]. https://s3.amazonaws.com/sqlcipher/SQLCipher+for+Android+2.2.1.zip

SafeWallet Alternative: Migrating from SafeWallet to STRIP

Permalink - Posted on 2013-07-01 15:43

UPDATE Oct 10, 2013: We've made great progress, and we're opening the download links up below, the latest build of Convert to STRIP for Windows should be processing the SafeWallet XML files correctly now. Please give it a shot and let us know! -WG

UPDATE Oct 8, 2013: The latest versions of SafeWallet (3.0.x) are NOT compatible with our converter. We're working hard with a number of our customers and lots of sample data to resolve this as soon as we can, but it's turned out to be quite a bit more complex than anticipated. We will get it! But be advised that if you are planning to purchase STRIP and to use the converter specifically for SafeWallet data, it does not work right now. Please get in touch with us if you have any questions, and thanks for your patience! -W.Gray

One of the more popular password managers out there is SafeWallet. A few new customers have been checking out STRIP as an alternative after reading about our password manager and have asked us about how they might import their SafeWallet data directly into STRIP. On Friday we posted an updated version of our Convert to STRIP utility to add this new option for both Windows and OS X. Read on to see how it works.

Get STRIP Now »

Convert to STRIP for Windows »

Convert to STRIP for OS X »

Export your SafeWallet data

Launch SafeWallet, login to your wallet, and then select File -> Export, and a simple export wizard will appear allowing you to save a .XML file of your data anywhere on your computer.

Convert SafeWallet data

  • Download the STRIP Data converter onto your desktop and Unzip it. Double click the icon to run it.
  • Click "Source File" button and choose SafeWallet XML export file.
  • Click the Save As button and save strip.csv on the desktop.
  • Make sure the "SafeWallet XML" radio button is selected for Source Format.
  • Click "Run Conversion" to migrate the file to the Strip export format.

Verify your data

There is now a 'strip.csv' file on your Desktop. You can open it in a spreadsheet editor to check its contents (e.g. OpenOffice.org, Numbers, Excel), or open it in a simple text editor. It's a good idea to check the data over for accuracy before importing it into STRIP.

Note: if you decide to edit your CSV data before import, be sure to save the file as CSV data when done. Additionally, if your data contains international characters (e.g. ü, é, etc) do not attempt to edit the file in Excel, your best bet to preserve these characters correctly is to use the free Calc spreadsheet editor from OpenOffice.org.

Import into STRIP

Log into STRIP on your PC or Mac and choose the strip.csv file on your Desktop.

Once the import is complete you'll see all of your SafeWallet data right in STRIP! Once you've checked that everything looks okay in STRIP you should delete the two plaintext import/export files (remember to empty your trash, or even better, securely delete them).

SQLCipher 2.2.0 Release

Permalink - Posted on 2013-06-27 16:45

We would like to announce the release of SQLCipher 2.2.0. The follow highlights changes included in this release:

  • Configurable crypto providers including experimental support for CommonCrypto and LibTomCrypt
  • A change to the native CursorWindow to remove usage of private android::MemoryBase
  • Renaming of generated binaries from sqlite3 to sqlcipher
  • Based on SQLite version 3.7.17

We have renamed both the library and shell from sqlite3 to sqlcipher (e.g. previously libraries which have been named libsqlite3.so are now named libsqlcipher.so, and the command line tool is now called sqlcipher instead of sqlite3). As the use of SQLCipher grows, this change will aid in isolating conflicts from system installed versions of SQLite. We have also narrowed the usage of non-static interfaces within the source. Thanks to Hans-Christoph Steiner from the Guardian Project for contributing the patches he used to prep SQLCipher for Debian.

We are also introducing configurable crypto providers in this release. OpenSSL remains the default provider, but we have included experimental support for both the Apple CommonCrypto library and the open source LibTomCrypt library.

To support this change, we have added an additional configure flag called --with-crypto-lib. Currently, you can specify one of the following values: openssl, commoncrypto, libtomcrypt, or none for amalgamation builds. If this flag is not included at configure, OpenSSL is used by default.

An example of building SQLCipher with CommonCrypto follows:

./configure --enable-load-extension --enable-tempstore=yes \
--with-crypto-lib=commoncrypto \

Applications that are compiling in the SQLCipher amalgamation or using the Xcode project can experiment with Common Crypto support by removing the openssl-xcode sub project and link dependencies, defining SQLCIPHER_CRYPTO_CC (i.e. adding a -DSQLCIPHER_CRYPTO_CC compiler flag), and adding Security.framework to the link libraries for the project.

An example of building SQLCipher with LibTomCrypt follows:

./configure --enable-load-extension --enable-tempstore=yes \
--with-crypto-lib=libtomcrypt \
-I/Users/nparker/src/libtomcrypt-1.17/src/headers" \
LDFLAGS="-L/Users/nparker/src/libtomcrypt-1.17/ -ltomcrypt"

Please note that the LibTomCrypt implementation is still in the formative stages, and should not be used for any real production implementations at this time due to limited entropy in RNG seeding.

Following compilation, once a key has been provided to properly initialize a cipher context, you can verify which provider you are using by executing the following read-only PRAGMA:

PRAGMA cipher_provider;

Finally, this release includes a fix to the native CursorWindow that removes the usage of android::MemoryBase. This resolves an issue under an upcoming Android platform release that marks this API as private and causes a crash.

The latest source can be found here [1]. We've also prepared a binary package of SQLCipher for Android here [2]. Please take a look, try out the new library changes and give us your feedback - we welcome it! Thanks!

[1]: https://github.com/sqlcipher/sqlcipher
[2]: https://s3.amazonaws.com/sqlcipher/SQLCipher+for+Android+2.2.0.zip

Tempo Maintenance, Thursday June 20th at 10 PM EDT

Permalink - Posted on 2013-06-18 14:50

This Thursday night, June 20th at 10pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

STRIP for OS X release 2.0.1

Permalink - Posted on 2013-06-03 17:01

Monday morning we released STRIP for OS X version 2.0.1 in the Mac App Store, it should be available now. This is a minor but helpful maintenance update with some good bugfixes for version 2.0.0. All customers are encourage to upgrade (rememer to take a backup before upgrading). This release includes the following changes:

  • Adds option to show password generator on edit entry context menu
  • Shows number of entries below entries list
  • Clarifies labels for operations under Sync menu
  • Selects previously selected entry after login
  • Fixes selection of entry upon tab from search field
  • Fixes repeated locking notifications when application is already locked
  • Fixes issue with CSV file import creating empty entries
  • Fixes numeric-only password generation

Customers who're using the version of STRIP for OS X purchased from the Zetetic store will also see the update shortly. Select the STRIP menu and choose "Check for Updates" if automatic update checking is disabled under Preferences.

Mobile App Security+ exams from CompTIA and viaForensics

Permalink - Posted on 2013-05-30 12:32

CompTIA and viaForensics have just launched a new set of in-depth exams on mobile application security. The Mobile App Security+ exams are structured to ensure that candidates have the specific knowledge required to build native iOS or Android applications that secure local data, off-device communications, and back-end services.

Zetetic had an opportunity to review the exam objectives before launch, and they promise to ensure a solid foundation in a wide range of mobile security topics. If you're not yet convinced that mobile applications need an even greater focus on security, the article that accompanies the test program, Why Mobile App Development is a Risky Business, will change your mind by providing an realistic overview of common risks and challenges.

Registration for the Beta exams is free for a limited time (use promo codes "MAPS ADR Mkt beta" or "MAPS iOS Mkt beta") and definitely worth checking out for anyone building mobile applications today.

Building Secure Applications: June 6th at New Work City

Permalink - Posted on 2013-05-14 17:40

Discussing new tools and good techniques with Zetetic and The Guardian Project

On Thursday June 6th Zetetic and The Guardian Project will be hosting an evening of short talks and conversation about the how and why of building secure mobile applications that keep the user's data encrypted and hidden from prying eyes. We'll have a few short presentations on tools like SQLCipher, IOCipher, and NetCipher and how they can be used in modern applications. We'll answer questions about general strategies and specific toolkits, and our developers will be available to chat afterwards over pizza and beer.

The event will be held at New Work City in New York, a fantastic coworking and event space at the edge of Tribeca and Chinatown, from 7-10pm. If you'd like to join us, please RSVP on eventbrite.com (it's free) so we can have an idea of how many folks to expect.

The evening's agenda will feature two or three short presentations discussing what's involved in building more secure applications, why this should be a critical focus for all developers, and how to easily integrate tools into your own projects, followed by Q&A for each. We'll also hold a slot open for short talks from members of the community who would like to share information on security-related projects they are working on (send us a note if you'd like to present a bit about your project).

After the discussions wrap up, we'll break for snack and chat time, and will be available to discuss the toolkits involved and approaches to application security in general. We can answer questions in a one-on-one capacity, discuss future plans for these projects, and we'd love to get your feedback if you're already using SQLCipher or one of the Guardian toolkits.  

This will also be a good opportunity for those interested in the further development of these libraries to meet up in person, we're really looking forward to that. So please join us! Bring your own projects, tell us what you're working on, let's talk some crypto!

Zetetic Participating in the Google I/O Developers Sandbox

Permalink - Posted on 2013-05-13 17:02

We're very excited to announce that Zetetic has been invited by Google to participate in the 2013 Developer Sandbox at the Google I/O conference.

We'll be featuring the newest release of STRIP, our highly rated secure password manager and data vault, and talking about our experience implementing multi-device synchronization using Google Drive and SQLCipher encrypted databases across four development platforms.

The Developer Sandbox will be a great opportunity to meet other developers. If you're at Google I/O this year and are interested in Google Drive integration, database encryption, or just need a password manager, please stop by and meet with us on Thursday, May 16.

STRIP 2 Released with New Features and Native iPad App

Permalink - Posted on 2013-05-07 14:26

We're excited to announce the release of STRIP 2, our most significant version yet, featuring several new features, bug fixes, and strengthened database security. Some of our favorite new features include:

  • Sync via Google Drive
  • A brand new iPad application
  • Auto-lock for STRIP for Windows and STRIP for OS X
  • Configurable field masking to hide sensitive data from view
  • 40 brand new professionally designed icons 
  • Improved synchronization speed
  • Improved database security and tamper resistance
  • Many other improvements and bug fixes

The new version of STRIP is available immediately for all platforms: iPhone, iPad, Android, Windows, and OS X. Read on for a full list of changes.

Introducing STRIP for iPad

We’re especially proud to release a new native version of STRIP for the iPad, with all features optimized for your tablet's interface.


Checkout STRIP for iPad in the iTunes App Store

Important Note: STRIP for iPad is available as an optional separate purchase from the App Store. Please be assured that we are still very committed to STRIP for iPhone, which has received all of the same feature updates in STRIP 2, still works on the iPad, and will continue to be a core supported STRIP platform.

Important Upgrade Notes

Instructions for updating each STRIP are available on our FAQ.

  • Please backup your mobile devices and desktop databases before upgrading, either via WiFi or Dropbox.
  • After the upgrade, password and PIN fields will be masked by default using dots to hide your most sensitive data from onlookers. You can quickly reveal these values, copy them to the clipboard, or disable this feature globally. Learn More about Masking »
  • To improve security and accomodate service updates you will need to reconfigure Desktop synchronization in OSX and Windows under the Preferences Window after upgrading. Learn More about Syncing »
  • When you log in to STRIP 2 for the first time the database format will be updated. Due to database file and feature improvements, STRIP 1.x will not sync with STRIP 2. Therefore, you should plan to update all of your devices and applications to STRIP 2 at around the same time. More information is available on our upgrade FAQ.

Goodbye, StripSync

Finally, we must announce the final end of support for StripSync, the old and venerable backup application that was officially retired in May 2012. While StripSync continued to work over the past year, the new version of STRIP breaks compatibility in order to provide new features and security improvements.

STRIP mobile customers using StripSync can now backup and synchronize multiple devices for free using Google Drive or Dropbox. Users interested in a desktop application are encouraged to check out STRIP for Windows and STRIP for OS X which provide a full-featured editing interface plus support for both WiFi and cloud synchronization. Learn more about replacing Strip Sync ».

We're Here to Help

This release has been under development for a long time, and we appreciate your patience! Please let us know if you have any questions about the upgrade process, how you like new version, or if you run into any issues at support@zetetic.net


Full List of Changes

Here is a full list of all the changes in the new version.

STRIP for Windows and OS X

  • Sync with Google Drive or Local Folder
  • Optional masking and hiding of fields from display (automatically enabled for passwords and PINs) 
  • Automatic lock when not in use (configurable in Preferences) 
  • New field control with options to create new labels and random values 
  • Improved long note editing and line breaks 
  • Right-click on fields for quick access Context menu with Copy, Delete, Hide / Show, and Random generator options 
  • New random password generator available
  • 40 new professionally designed icons 
  • Enables new database security features (tamper resistence via per-page HMAC protection)
  • Allows renaming of backup files in Backups 
  • Optional OS X notification when STRIP locks automatically 
  • Integrity Check detects and fixes missing local replica ID 
  • Quick "Lock Now" hotkey and menu item
  • New Sync options, Menu, and Preferences 
  • WiFi sync service no longer enabled by default, see Preferences to enable
  • Fix: Height of note field is properly redrawn to fit content of note field after editing 
  • Fix: Launch web URLs entered without leading "http://" scheme 
  • Fix: Errors during backup include actual error message 
  • Fix: Integrity Check adds entry records to the Unfiled category 
  • Fix: Re-ordering of fields on edit is now saved immediately 
  • Fix: Sort labels by name in Customize Labels 
  • Fix: Non-default backup preference is retained 
  • Fix: Diacritic characters in password no longer cause authentication failure during WiFi sync 
  • Fix: Allows large note field editing on Mac OS X 10.6 
  • Fix: Command+Q will quit STRIP for OS X even when when application is locked

STRIP for iPhone and Android

  • New option to sync with Google Drive
  • Optional masking and hiding of fields from display (automatically enabled for passwords and PINs) 
  • Improved random password generator
  • 40 new professionally designed icons 
  • Quick "Lock Now" button added to Preferences
  • Remembers manually entered Sync addresses and hostnames
  • New alternate font display preference
  • Enables new database security features (tamper resistence via per-page HMAC protection)
  • Displays preview of note fields on entry view 
  • Improved sync performance



SQLCipher for Android Private Beta Group

Permalink - Posted on 2013-04-26 15:03

We are planning to gather a group of users to participate in a private beta of SQLCipher for Android. We are looking for individuals who already have some experience integrating SQLCipher for Android into their application and have an interest how the library evolves in the future. This group will have access to new builds of SQLCipher for Android along with private communications with Zetetic to provide feedback as changes are made.

We have recently been in discussion with members of the Android development team at Google where they have been helpful in testing out some changes to SQLCipher for Android on an upcoming Android platform release. While this is very benefitial, we would like to reach out to the community to further understand how changes to the library may impact you in the future.

If you are interested in helping SQLCipher for Android evolve in the future, and are willing to actively test, provide feedback on new builds, and contribute test cases, you can contact us to be considered for the private beta. Please send emails to support@zetetic.net and include a bit of inforomation about your app and how you currently use SQLCipher in your request. Thanks!

STRIP 2 for OS X Release Candidate

Permalink - Posted on 2013-04-08 14:57

Update: STRIP 2.0.0 for OS X has been released. Upgrade instructions can be found here.

We've been posting the last few beta update notices for the STRIP 2 for OS X beta here so we have a handy place to refer to the update. If you're not part of the beta test, please ignore this post. If you would like to help us beta test in the future, please write us at support@zetetic.net. We don't have any open slots at the moment, but we always need new folks to help and will gladly add you to the list!

This should be the final test version of STRIP 2 for OS X, barring any show-stoppers, so please give it a good shake. The version number is 1.3.0b6, it's the third and hopefully final release candidate we've done (I know, we've been testing for a long time).

Some re-arrangement has happened with the Sync menu, Preferences, and there's a secret new sync feature we're looking forward to announcing on release day. We're going to submit this one to the Mac App Store for review soon, so we might be able to do the official release in a month (our review times for STRIP for OS X have been over 30 days in the past so we'll have to see). If you see anything askew, please write us at support@zetetic.net. 

One more thing—we've been going through the apps and correcting use of "Strip" to the capitalized STRIP, including dialogs, the application name itself, etc. If you see any that we missed, please let us know.

Updated versions of STRIP for iPhone and STRIP for iPad are on the way to beta testers registered with our TestFlight service, please check your email or get in touch with us if you didn't get the notice.

Thanks everyone for all your help, we're really excited about this release!

Tempo Maintenance, Thursday February 21st at 10 PM EDT

Permalink - Posted on 2013-02-20 20:35

This Thursday night, February 21st at 10pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

Announcing the new SQLCipher for Xamarin

Permalink - Posted on 2013-02-20 14:47

We're pleased to announce that we've partnered with Xamarin to make SQLCipher available directly from Xamarin's new Component Store.

Developers using the new Xamarin Studio can now easily install SQLCipher (and other 3rd party libraries) through the component store. There are no longer additional steps for packaging native .so libraries for Android and we've eliminated the configurations for linking static archives on iOS. Everything is bundled into a single library and automatically configured in your application project, making secure database integration using C# on Android and iOS quick and painless.

Please check it out and let us know what you think!

STRIP 2 for OS X beta 1.3.0b5

Permalink - Posted on 2013-02-19 20:04

We'll be posting the last few beta update notices for the STRIP 2 for OS X beta here so we have a handy place to refer to the update. If you're not part of the beta test, please ignore this post. If you would like to help us beta test in the future, please write us at support@zetetic.net. We don't have any open slots at the moment, but we always need new folks to help and will add you to the list.

1.3.0b5 Release Notes

Note: This release includes a database update which requires you to update your other copies of STRIP as well to maintain sync compability. Click here to download this release directly. Only registered beta testers with a license from us can run this build, please don't download it if that's not the case for you.

  • Disables "Install & Relaunch" due to incompatibility with OS X Sandbox
  • Updates sync service to support non-ascii UTF-8 characters in password during HMAC authenticaiton
  • 50 new icons to supplement the current set
  • Fix crash on edit

As always, if you have any issues, please email us at support@zetetic.net.

Note: if an issue you've already reported isn't mentioned above, we're still working on it. Thanks!

SQLCipher available on Homebrew

Permalink - Posted on 2013-01-21 16:30

Many of us here at Zetetic use Homebrew, a command-line tool used to build and manage various software packages on OS X. Currently there are over 2200 recipes available to be installed via Homebrew. While building SQLCipher is not difficult, installing from Homebrew is just as easy and also affords you the ability to easily upgrade your installations as updates are released, all managed within a central location. We have submitted a recipe for SQLCipher that is now available to the masses. If you already have Homebrew installed, you will want to update your current list of recipes:

brew update

To install our current release, simply run:

brew install sqlcipher

If you wish to run the bleeding edge of SQLCipher, you can request the install perform a build from our master branch:

brew install sqlcipher --HEAD

This will install what is called a keg-only package of SQLCipher to minimize conflicts with other dependencies on SQLite due to the shared binary name. In order to make SQLCipher available on your PATH you can run:

brew link sqlcipher --force

Happy brewing!

Updated convert-to-strip for 1Password

Permalink - Posted on 2013-01-07 16:22

We've been notified by a few customers looking to switch to STRIP from 1Password about problems reading the 1Password export file. These ranged from blank fields to improperly processing place-holders for deleted records and an older export format. If you've had trouble using this utility, this update will probably help you out. If not, please contact us at support@zetetic.net and we'll get to work on it! This app also allows you to convert SplashID export files to a CSV you can import into STRIP.

Convert to STRIP for Windows »

Convert to STRIP for OS X »

Update: Feb 11, 2013 In response to comments below, bugs have been fixed, and the download links above have been updated/corrected.

Announcing SQLCipher 2.1.1

Permalink - Posted on 2012-12-07 18:24

We're pleased to announce the availablilty of SQLCipher 2.1.1. This is a significant release including the following improvements and new features:
  • New PRAGMAs to query the current values for all SQLCipher settings (for example, "PRAGMA cipher" will now return "AES-256-CBC" by default, with similar behavior for other SQLCipher PRAGMAs) 
  • Tracking of activation calls and OpenSSL initialization, automatically executing EVP_cleanup to free associated memory on behalf of applications
  • Fix for an issue where the page number was included in HMAC calculation using native byte order. SQLCipher now converts to little endian by default (for backwards compatibility on popular ARM, i386 and x86_64 platforms). This allow interoperability between big endian and little endian platforms. 
  • New PRAGMA cipher_hmac_pgno = ( be | le | native ) to set behavior for page number byte ordering, and to convert older databases on big-endian platforms
  • New PRAGMA (cipher_hmac_salt_mask) to change the value used to permute the database salt before HMAC key derivation. This facilitates databases upgrades from old SQLCipher 2.0-beta settings to the latests defaults. With this change all key derivation settings are changeable via PRAGMA!
  • Improvements to memory wiping to avoid compiler optimizations, constant time memory comparison routines, and detection of context initialization problems (i.e. out of memory errors)
  • Code refactoring to move custom PRAGMA handling out of pragma.c into crypo.c (to minimize differences with SQLite upstream releases) and fix compilation errors for non-amalgamation builds
  • Uses the latest SQLite as a baseline
Community edition users can now update to the latest SQLCipher on GitHub, and a new download of SQLCipher for Android is also available.  The SQLCipher for Android library has added support for x86 Android devices in this release.
New versions of the SQLCipher Commercial Editions for iOS, MacOS, Windows, ADO.NET, MonoTouch, and MonoDroid are already on sale in the SQLCipher Store. Note: commercial users who have purchased the binaries within the past 6 months may contact us for a complementary update.

Tempo Maintenance, Monday December 3rd at 9PM EST

Permalink - Posted on 2012-11-28 20:56

This Monday night, December 3rd at 9pm EST, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services. We will also be updating Tempo's API end-points to respond properly to JSON requests. 

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

STRIP for OS X 1.2.7 Released

Permalink - Posted on 2012-10-26 14:33

Yesterday, version 1.2.7 of STRIP for OS X was released. This update provides makes a couple of minor changes:

  • Provides a warning/confirmation before deleting a label and associated fields
  • Fixes bug where main window could be duplicated on setup
  • Fixes bug where sync service would hang after attempting a restore from a database with a different key
  • New STRIP icon

You can download this update from the Mac App Store.

Known Issues:

  • Attempts to sync with a Dropbox folder stored on another volume (e.g. not the system disk) will fail
  • Multi-line text is not always displayed correctly

More fixes and new features are on the way!

Tempo Maintenance, Thursday October 25th at 10 PM EDT

Permalink - Posted on 2012-10-24 22:21

This Thursday night, October 25th at 10pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

SQLCipher Now Supports iPhone 5, XCode 4.5, and armv7s

Permalink - Posted on 2012-09-27 19:56

We're please to announce that SQLCipher now officially supports the new iPhone 5, XCode 4.5 and the armv7s architecture!

Community edition users can now update to the latest on the SQLCipher master branch to get the XCode project updates.

New versions of the SQLCipher Commercial Editions for iOS and MonoTouch with these same improvementsare available immediately in the SQLCipher Store! Commercial users who have purchased the binaries within the past 6 months may contact us for a complementary update.

Note: XCode 4.5 no longer supports armv6 so support for this architecture has been removed from both the community and commercial editions.

STRIP for OS X 1.2.6 Update Released

Permalink - Posted on 2012-09-17 16:31

STRIP for OS X has been updated, version 1.2.6 was released last week, and since then we've been catching up on some support mail. It features a few minor convenience improvements, based on our customers' feedback and suggestions:

  • Verify that Dropbox folder selection is the Dropbox path and not Dropbox/Zetetic 
  • Preferences window now has a Reset button for the backups directory path
  • Preferences now has a switch for disabling creation of a backup on every sync
  • Dropbox folder selection now displayed in Preferences along with chooser button

Known Issues:

Upgrading from Strip Sync

There does seem to have been a bug introduced by our adoption of sandboxing a few months back for the Mac App Store as required by Apple. On first-time setup, Strip for OS X checks for the old Strip Sync database and offers to migrate your data—currently this check occurs inside of the Sanbox, so the old data is never detected. There are several ways to work around this, the easiest being an Overwrite from Strip for iOS, but we advise any new users to get in touch with us.

Double windows on setup

On OS X Lion and OS X Mountain Lion, the system takes note of any windows open when you close an app and attempts to automatically restore them. When you start up Strip for OS X the first-time, and quit without setting the program up, and you relaunch the app later, you'll see two windows appear, a setup window and login window. You'll want to quit the plain login window and proceed with the setup window. We should have a fix for this out as soon as we can get it reviewed by Apple (note: version 1.2.6 had to wait 30 days before going into review, so it can be a bit). If you are experience this problem or related issues, please contact us.

Tempo Maintenance, Saturday September 15th at 10 PM EDT

Permalink - Posted on 2012-09-13 22:46

This Saturday night, September 15th at 10pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 2 hours, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

Secure Active Directory Password Reset with FIM 2010 R2

Permalink - Posted on 2012-09-04 17:18

While perusing Troy Hunt's article Everything you ever wanted to know about building a secure password reset feature, I thought it might be interesting to map Troy's notes on good processes against Forefront Identity Manager 2010 R2's SSPR flow, which allows users to reset their own Active Directory passwords from both the company intranet and from the Internet.

We're going to skip over concerns about password hashing and encryption for now, as FIM SSPR only works with Active Directory Domain Services, of which the password encryption and hashing options are a separate topic.  Suffice it to say that existing passwords in AD:DS are normally hashed, not recoverable in plaintext, and not available in hashed format without attacking the domain controller at a fairly low level.

Starting with FIM 2010 R2, the self-service password site is just an ordinary web app, with none of the MSIE / ActiveX requirements of the past.  Out of the box it follows the familiar pattern of asking for your username, displaying a set of security questions--an administrator configures the text for each question, as well as the total number of displayed and required questions--and if you get them right, you get to reset your account password.  The entire flow looks like this:

Step 1. Enter your username

The first step is to enter your username, either in "DOMAIN\username" or "user-principal-name@domain.local" format, or just "username" if a default domain is configured.

If the user ID doesn't exist, or even if the ID does exist but the user hasn't registered for SSPR, FIM does a reasonable job of minimizing information disclosure.  Otherwise, if the user account is valid, and is enrolled for SSPR, we see a list of security questions.

This is a little bit of a concern, as a third party may be able to use the initial SSPR page to discover valid logon IDs that are enrolled for SSPR, provided the organization uses logon IDs in the very typical "first.last" or "<first initial>last" and related formats, and also assuming the third party knows the Active Directory domain name (which they might not).  It should go without saying that most IT/infosec organizations are not particularly eager to ask their users to remember an opaque logon ID, although in my own experience, these IDs are extremely easy to remember after a few days of regular use--I still remember opaque logon IDs from ten years ago, and even a Prodigy ID from a very, very long time ago.

Highly security-conscious organizations could configure the SSPR portal to require username entry in UPN format, with a validation to reject any other style, in conjunction with assigning values other than the implicit UPN.

Notably, it is not possible to attempt to use FIM SSPR with knowledge of only a person's email address, nor can one use FIM SSPR to test the validity of any email addresses.  There's also a lockout mechanism that restricts each account to 3 unsuccessful SSPR attempts in 15 minutes (this is configurable).

Step 2. Answer security questions

There's really nothing new here: the FIM SSPR page presents some or all of the security questions you answered during enrollment.  It's up to the FIM administrator to decide how many questions to offer, how many the user must answer, and then out of these, how many will be displayed and required during a reset; there's no capability for the user to type in custom questions like "What's the secret word taped to the bottom of my keyboard?"

The upshot is that your Windows password is only as strong as the difficulty of answering the reset questions correctly.  Can one come up with questions that are memorable, unambiguous, stable, apply to practically everyone, and extremely difficult to research?  Certainly some questions are better than others, but there's absolutely an argument to be made that it's impossible to present any set of security questitons that is as strong as a long, reasonably random password.  For example:

QuestionIssues / Security
What was your childhood nickname?
  • Limited number of likely values
  • Often based on individual's name
  • Researchable (especially by childhood friends)
  • Not everyone has a nickname
What street did you live on in third grade?
  • Very small number of likely values
  • Researchable 
  • Guessable (by anyone with Google Maps and some time)
What is your oldest cousin's first and last name?
  • Researchable; having a cousin is not a secret
  • Not everyone has a cousin

My own practice is to answer questions like these with random gibberish, or sometimes with silliness: "Why yes, my first pet's name was 'Mister Bitey.'"  In any event, the answer is outside the set of common responses, it's really not researchable, and right into STRIP it goes in case I need it later.

At this point, in a default FIM SSPR configuration, FIM will let you pick a new password.  The new password will (optionally) be validated for compliance with the account's effective password complexity policy, and we're done.  It's easy, but... it's not very secure, especially if the user has answered the security questions in a straightforward manner (that is to say, the user has not entered "Cthulhu M. Wiggington III" or "R7z_al4nep5" as his or her oldest cousin).  But let's think about this--I mean, what's the point of demanding complex, 12-character passwords that must change monthly and not repeat any of 15 prior passwords, in Active Directory, if we've got these simple, non-complex, never-changing password reset questions kicking around--and on the Internet to boot?

Step 3. 2-Factor Authentication / One-Time Passwords

One of the excellent improvements in FIM 2010 R2 is that the self-service password reset process doesn't have to end with Step 2: we can plug in one of two additional One-Time Password, or OTP, authentication gates.  The choices are the One-Time Password Email Gate, which sends a confirmation code to the user's recovery email address, and the One-Time Password SMS Gate, which sends a text message to the user's mobile phone.  

The addition of the One-Time Password gates is critically important, especially in an Internet scenario, because it reduces the security questions to merely a precursor, or filter, to an additional check that improves process integrity.  Both of the OTP gates send a message like "Enter code 205839 to reset your password," which code the user must re-enter in the FIM SSPR dialog to proceed on to choosing a new password.  Fundamentally this is a good approach, as the user has only one try per SSPR session to enter the right temporary PIN, and we haven't sent a new password, or anything else extremely sensitive, over insecure public networks.  (See the video linked farther down this page for a view of one-time passwords in action.)

Email One-Time Passwords

I'll talk about the Email OTP gate first:  To cut to the chase, it isn't a very secure option.  Since we're working with Active Directory here, the user has almost certainly enrolled for SSPR with some third-party email provider like Hotmail / Live, Gmail, AOL, etc.--they can't very well reset a lost or locked-out Active Directory account by logging in to a mail system that uses that same Active Directory for authentication.  The problem is that the security of the external webmail account is totally outside IT's control--it's not auditable, the user may have a very weak password, share the same password across multiple other websites, or the webmail provider might have an insecure password recovery process with questions an attacker already researched to attempt to get through FIM SSPR.

Emailing a PIN adds another step, but it really does not add another factor to authentication, because we are still in the realm of "something you know," and this is all stuff a determined attacker could know.  However, it is slightly better than emailing a "password reset URL," as the PIN is only useful within the time-limited context of one session with the FIM SSPR website.

Mobile Phone / SMS OTP

The SMS OTP gate works much the same way: after answering the security questions, the system sends a SMS to your mobile number, e.g., "Your password reset PIN is 582048."  Type in the PIN to FIM's waiting prompt, and you're ready to choose a new password.  This may seem like a small step from the Email OTP, but it's really a very large difference as a legitimate second authentication factor that requires, in addition to "something you know," the "something you have"--possession of the mobile phone.  While it might be practical for a determined attacker halfway around the world to research security questions and even to break into a webmail account, the effort and expense would be several orders of magnitude higher to discover the user's mobile number and actually intercept its traffic without alerting the user.  (If you're facing attackers with the resources to spend on this kind of effort, it's probably high time to do away with passwords entirely and move on to certificates and smartcards exclusively.)

While FIM 2010 R2 provides the basic framework to enable the SMS One-Time Password, it does not include any implementation or SMS gateway interface.  We'd like to encourage organizations interested in SMS authentication for FIM Self-Service Password Reset to check out Zetetic's SMS Provider for FIM, which includes a plugin for the FIM Service and integrated SMS services.

Here's a video of the entire FIM password reset process including SMS PIN.


Overall, with the addition of the SMS One-Time Password facility, FIM 2010 R2 Self-Service Password Reset gets a lot of stuff right:

  • Limited information disclosure
  • Lockout interval discourages brute-force guessing
  • Flexible security question enrollment allows for good diversity
  • Users securely enter a new password, rather than receiving a system-generated one
  • Security questions provide a reasonable barrier against spamming users with SMS PINs
  • Extensible after the password is reset (e.g., could send the user an email to confirm)
  • Time-limited opportunity to complete the reset activity
  • SMS PIN provides 2FA

As for areas for improvement, we might like to see the addition of a CAPTCHA or some other mechanism to dissuade using the initial SSPR page to probe for valid logon IDs.  This would not be an issue for organizations that decide to not to deploy FIM SSPR on the Intranet, or for those who might guard frontend web access with whitelisted IP ranges or with an intrusion detection system to throttle or eliminate malicious use.


Dropbox Two-step Verification on Mac with Yubikey and OneTime

Permalink - Posted on 2012-08-31 03:12

Dropbox has made security-conscious users very happy with the recent addition of two-factor authenitication using OATH-TOTP. We are now pleased to announce that the latest version of OneTime for Yubikey adds support for Dropbox, allowing Yubikey owners to use their USB devices for 2-step verification on Mac OS X.

Unlike mobile applications or SMS delivery, a Yubikey with OneTime is highly portable and doesn't require a smartphone, cell coverage, or SMS service. Nor does OneTime make you re-type passwords from your device into login fields on the computer.

Getting started with Dropbox 2-step, OneTime and a Yubikey is very easy. You'll need to install OneTime on your computer and launch the application. Then, login to your Dropbox account page, locate the two-step verification status, and click "change".

Follow through the informational screens until you are prompted to choose a 2-step verification method. Choose to use a Mobile App instead of SMS.

On the next screen, above the QR code, click the link to "enter your security code manually" to view the raw Base32 encoded key data.

Select the raw key and copy the value to the clipboard. Then click the OneTime for Yubikey Icon in the Mac Taskbar, then Preferences, and switch to the Personalization tab.

Paste the secret key into the key field, choose the Yubikey slot to use (usually Slot 2), then "Write Config". Important Note: "Write Config" will irrevocably overwrite any existing configuration in the specified Yubikey slot. When shipped from the Yubico, slot 1 is programmed for the Yubico OTP services and slot 2 is empty, so it is usually the right default. However, if you already use slot 2 with a different service (i.e. GMail) you may want to buy a new Yubikey for Dropobox. Please be careful!

Once the configuration is written to the Yubikey you can start using it immediately. On the next Dropbox screen you'll be asked to enter the current one time password. Just use OneTime's "Insert OTP" menu item, or your global hotkey (⇧⌘Y by default).

Complete the setup process and write down your emergency backup code. Now you're ready to use your Yubikey for Dropbox access on any Mac with OneTime installed! 


Learn More » or Buy OneTime Now »


P.S. existing OneTime for Yubikey users can contact us to request a free upgrade to the latest version.

STRIP for Android Release

Permalink - Posted on 2012-08-27 15:19

We are proud to annouce that STRIP for Android, the secure password manager and data vault, is now available in the Google Play store!

STRIP has been protecting data on mobile devices since 1998, and we've continued to evolve the product over the years to run on iOS, Mac, Windows, and now Android. Like its peers, STRIP for Android has many advanced features and the best security available:

STRIP for Android

  • A flexible data format that allows you to organize your information how you want into categories, entries and fields (you can even create your own labels and specify their data type)
  • Full text search, providing quick access to find data where ever you are in the application
  • Synchronization via Dropbox and replication out to STRIP for Windows and STRIP for OSX (also ensuring that a reliable data backup is always available)
  • A secure random password generator
  • Assignment of icons to entries and categories for easy visual identification
  • Launch websites, dial phone numbers and address emails

Most importantly, STRIP for Android features complete data encryption, protecting your most valuable information with SQLCipher. An open source extension to SQLite, SQLCipher uses 256-bit AES to encrypt the entire application database. We began the process of porting SQLCipher to Android late last year in conjunction with The Guardian Project to ensure a stable and secure platform, before even starting work on STRIP for Android. SQLCipher has been independently reviewed by many security professionals; for instance Elcomsoft presented findings about STRIP at the BlackHatEU conference, concluding that the application backed by SQLCipher was the "the most resilient to password cracking".

If you are looking for a password and data manager on the Android platform that provides a high degree of security and user flexibility, check out STRIP for Android and let us know what you think.

Get it on Google Play

Tempo Maintenance, Thursday August 23rd at 9 PM EDT

Permalink - Posted on 2012-08-21 22:05

This Thursday night, August 23rd at 9pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

Tempo Maintenance, Thursday August 16th at 9 PM EDT

Permalink - Posted on 2012-08-15 16:31

This Thursday night, August 16th at 9pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour, however we hope it will be completed much more quickly. If you need to get in touch with us for any reason, please don’t hesitate.

Strip for Android Preview

Permalink - Posted on 2012-07-25 19:15

We mentioned awhile back that we were busy working on a port of Strip for the Android platform. Development has been coming along smoothly and we launched a beta testing program to get feedback from some of our most enthusiastic users which has been very successful. Below you can see what some of the interface looks like:

If you are interested in using the same technology that was identified in the most resilient application to password cracking at the BlackHatEU conference on the Android platform be sure to sign up here to be notified when Strip for Android is released.

Tempo Maintenance, Thursday July 19th at 9 PM EDT

Permalink - Posted on 2012-07-17 16:08

This Thursday night, July 19th at 9pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will also affect the Tempo API, the the Connect website, and the site for Codebook.

Down time could last up to 1 hour (though we hope it will be completed more quickly). If you need to get in touch with us for any reason, please don’t hesitate.

Secure Password Hashing for ASP.NET in One Line

Permalink - Posted on 2012-07-03 15:38

Following up to my earlier post about improving the security of the ASP.NET SqlMembershipProvider, and to Troy Hunt's excellently thorough article Our Password Hashing Has No Clothes and further discussions with @thorsheim, @blowdart, and @klingsen (all of whom I recommend following), I took a second look at how to use the algorithms in the Zetetic.Security package without mucking about with machine.config and the .NET Global Assembly Cache, which really complicate the deployment picture.

The bad news is that the .NET base class libraries only read "name-to-algorithm" mappings from machine.config.  I was pretty surprised to see this, but it's plain as day in System.Security.Cryptography.CryptoConfig.OpenCryptoConfig().

The good news is that adding to the HashAlgorithms an application can use is super, super easy.  Start by grabbing the Zetetic.Security package from NuGet; next, one line of code will do the trick (in Global.asax's Application_Start, for example):

System.Security.Cryptography.CryptoConfig.AddAlgorithm( typeof(Zetetic.Security.Pbkdf2Hash), "pbkdf2_local");

Adjust the membership settings in Web.config as per usual:

<membership hashAlgorithmType="pbkdf2_local"><!-- other stuff --><membership>

Voila, your ASP.NET application is now using a much, much stronger password hash algorithm than the (really rather embarrassing) defaults of SHA1 and SHA256.


STRIP for Windows 4th of July Sale

Permalink - Posted on 2012-07-03 14:03

Starting now until July 6th, STRIP Password Manager for Windows is on sale, just enter the discount code STRIPHAPPY4TH at check-out for 25% off. If you've been using STRIP on your iPhone and you want reliable backups, and a desktop editor, STRIP for Windows is for you. 

Tempo Maintenance, Thursday June 21st at 9 PM EDT

Permalink - Posted on 2012-06-19 21:21

This Thursday night, June 21st at 9pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will affect the Tempo API, the purchase site for Strip for Windows, the Connect website, and the site for Codebook.

Down time could last up to 1 hour (though we hope it will be completed more quickly). If you need to get in touch with us for any reason, please don’t hesitate.

SQLCipher comes to Mono

Permalink - Posted on 2012-06-07 20:01

As mobile development continues to grow at a rapid pace, the increased need for developers to take advantage of their existing expertise in programming languages grows with it. To this point, we've ported SQLCipher to run on both MonoTouch and Mono for Android. You can now develop .NET applications, secured by SQLCipher running on both iOS and Android platforms. We have prepared licensed binaries for sale here and have tutorials on integrating SQLCipher for MonoTouch as well as SQLCipher on Mono for Android. If you've been looking for a good way to secure your data on major mobile platforms running .NET with SQLCipher we now have the solution. Take a look!

SQLCipher Core/Android 2.0.5 Released

Permalink - Posted on 2012-05-24 21:51

We released version 2.0.5 of SQLCipher Core and SQLCipher for Android. This release builds on the many new changes we introduced in SQLCipher 2.0. Source for SQLCipher Core can be found here. SQLCipher for Android is available as a binary package here and in source format here. Here are some of the changes/additions highlighted in this release:

SQLCipher Core:

  • Based on SQLite
  • Add PRAGMA cipher_version to identify the SQLCipher version
  • Improved reporting of HMAC validation failure
  • Enable secure delete (wipes deleted page contents)
  • Detect and report errors if cipher context becomes corrupted

SQLCipher for Android:

  • Everything listed above in SQLCipher Core
  • Add SQLiteDatabaseHook interface providing preKey/postKey hooks into SQLiteDatabase
  • Adjustment to how RO/RW databases are handled in SQLiteOpenHelper
  • Restructure package from info.guardianproject.* to net.sqlcipher.*
  • Removed the build step for OpenSSL, we dynamically link to it
  • Add SQLiteDatabase.upgradeDatabaseFormatFromVersion1To2 to automate migrations from the 1.x to 2.0 database format
  • Add overload to SQLiteDatabase.loadLibs to specify an alternative directory for unzipping the ICU dat file

Please take a look, we welcome feedback. Thanks!

Tempo Maintenance, Thursday May 24th at 9 PM EDT

Permalink - Posted on 2012-05-23 14:28

This Thursday night, May 24th at 9pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will affect the Tempo API, the purchase site for Strip for Windows, the Connect website, and the site for Codebook.

Down time could last up to 1 hour (though we hope it will be completed more quickly). If you need to get in touch with us for any reason, please don’t hesitate.

Tempo Maintenance, Sunday April 29th

Permalink - Posted on 2012-04-26 20:39

This Sunday night, April 29th at 9pm EDT, Tempo and other web systems will be temporarily unavailable while we perform critical patch updates to ensure the stability of our services.

This maintenance outage will affect the Tempo API, the purchase site for Strip for Windows, the Connect website, and the site for Codebook.

Down time could last up to 1 hour (though we hope it will be completed more quickly). If you need to get in touch with us for any reason, please don’t hesitate.

Virtual List VIew (VLV) and Active Directory - What’s it Good For?

Permalink - Posted on 2012-04-23 16:17

One of the lesser-understood topics in working with Active Directory and LDAP is the Virtual List View, or VLV.  In a nutshell, VLV lets you, the LDAP application developer, query a very large directory container in efficient, bite-sized chunks.  Consider, for example, a directory with one very large "Users" OU; e.g.: 

     + ou=DemoGroups (50,000 groups)
     + ou=DemoUsers (50,000 users)

 If you'd like to present the contents of this OU in a scrolling or paged window in an application, retrieving 50 pages of 1,000 results each is probably not the most efficient option; this will tax the directory server, waste network traffic, and suck up a lot of memory in your app too (especially if you aren't picky about retrieving just the necessary attributes).

VLV aims to solve this problem by providing a way to seek to positions within a very large LDAP result set, in conjunction with a sorting rule.  Want to show just the first, or fiftieth, set of 20 users in an OU, ordered by displayName?  Then it's time for VLV!  We use Virtual List Views in Connect's web and mobile interfaces to ensure a reliable, responsive user experience when when browsing large directories... on the other side of the coin, Windows' Active Directory Users & Computers administrative tool should use VLV when possible, but doesn't--it'll just complain when an OU has more than 2,000 child objects and gives up.

This is actually a pretty common problem we see in LDAP client applications; often time the developer has built and tested against a small directory, and/or tests with highest privileges to avoid LDAP administrative limits.

Here's a screenshot of Connect using Virtual List Views over AD to provide a very efficient slider control.  Even though the OU has several thousand objects, clicking or dragging the slider provides nearly instantaneous results (about 70 milliseconds per click):

When including a VLV Request control in an LDAP query, we need to tell the directory server:

  1. How to sort the result set (without ordering, the idea of a "page" makes little sense)
  2. The position of the target entry (i.e., where in the list are we)
  3. How many entries before the target entry to fetch
  4. How many entries after the target to fetch
  5. An estimate of how many objects we think are in the view

Of particular note, the ordering rule is expressed by including a Sort Request Control.  And #5, the estimated content count, helps the server seek to approximately the correct place in the result set.  For example, if we ask the server for offset 500 in a view we think has 1,000 entries, but the directory data have changed so much that there are now 1,500 entries in the view, the server can adjust its answer to provide results at the position we probably wanted.

A couple other things to keep in mind when using VLV are that it works best when the sort control and LDAP filter line up; e.g., if we're sorting on the displayName attribute, then "(&(displayName=*))" is often a good search filter.  Also, a "one level" LDAP search usually makes the most sense in conjunction with VLV, although a subtree search may sometimes do the right thing.  If you issue a complicated or very specific filter along with a VLV control, the results may not quite be what you expect.  Of course, you'll want to confirm that the attribute is VLV indexed by checking the attribute's searchFlags settings in the Schema container.  Here's a quick way to find all the subtree (VLV) indexed attributes using Joe Richards' excellent adfind -- this'll find both one-level indexed attributes (searchFlags & 2) and subtree indexed (searchFlags & 64):


adfind -schema -flagdc -bit -f searchFlags:OR:=66 searchFlags ldapDisplayName


You might know the subtree index flag better from the Active Directory Schema Management console, where it's labeled as "Index this attribute for containerized searches" (is "containerized" a word?  But I digress):

The Zetetic.Ldap project, available on Github and Nuget, provides code you can use directly or as a baseline for writing your own VLV requests. 

Finally, here's a table of sample results on an Active Directory 2008R2 domain controller with some reasonably large OUs and various VLV options.  This will help to give you a general idea of what VLV results to expect when applying specific vs. very general LDAP searches, using attributes that are or aren't indexed for VLV support.  I'll just reiterate that this should support the conclusion that VLV works best on searches for an OU's immediate children, sorted and filtered on an attribute that has the subtree index bit set.

Strong Password Hashing for ASP.NET

Permalink - Posted on 2012-03-29 16:55

A question on Twitter [1] [2] prompted us to take a look at the password hashing mechanisms available to the .NET Framework, and specifically to the standard SqlMembershipProvider.  

For those who don't work with this aspect of ASP.NET, the .NET framework provides a simple, SQL Server-based store for web application user data, which includes user details like logon ID and email address, logon count, password failures, plus the password salt and password hash.

The membership provider can be configured to use any CLR class that implements System.Security.Cryptography.HashAlgorithm, always with a 16-byte salt, and the out-of-the-box hash algorithms are:

  • MD5
  • RIPEMD160
  • SHA1
  • SHA256
  • SHA384
  • SHA512
  • (Keyed) HMAC
  • (Keyed) HMACTripleDES

These algorithms are generally good for showing data integrity, but they aren't well-suited for password hashing because it's possible to run them at an extremely high speed--millions or hundreds of millions per second on a modern GPU--which means a low overall cost and effort to crack a list of leaked password hash data, despite salting.  See here for Hacker News's favorite article about why these are unacceptable for hashing passwords.  

In short, if an attacker were to gain access to the SQL database, it would be feasible to discover many of the passwords within via brute force because all of these hash algorithms are too fast.  An attacker could then use these discovered, plaintext passwords to attempt to access other sites, impersonating your users (who, we suspect, have not diligently used an unique, random password at each site... all the more reason they should use STRIP).

Now, there are alternatives, one of which is already built in: The .NET Framework has included an implementation of Password Based Key Derivation Function 2 (PBKDF2) in the Rfc2898DeriveBytes class, going all the way back to .NET Framework 2.  However, Rfc2898DeriveBytes does not implement the HashAlgorithm method that would make it compatible with the ASP.NET SqlMembershipProvider or with other general-purpose programmatic .NET hashing interfaces.

The bcrypt algorithm is even more resistant to brute-force attacks (i.e., it's more computationally expensive), and there's already a .NET implementation of bcrypt, but it also does not implement HashAlgorithm.  

Importantly, both PBKDF2 and bcrypt are adaptive algorithms: scaling up the effort needed to compute them is built into their design, such that if computers were 10x faster, you could ratchet up their work factors to make them do 10x more computation.

Taking all this into account, we decided to build a simple .NET library that makes PBKDF2 and bcrypt work with SqlMembershipProvider and other areas within the .NET crypto API.

View the code here

Download a binary build here

Using the new hash algorithms

First, install Zetetic.Security.dll into the .NET Global Assembly Cache: you can either:

  • Drag the file into C:\Windows\Assembly via Windows Explorer (which may require turning off UAC on Windows 7 / 2008), or
  • Launch an elevated command prompt and use gacutil:  gacutil /i Zetetic.Security.dll

Next, you'll need to register the new algorithms and aliases for them in the .NET Framework's "machine.config" file.  For example, if you want to use the new algorithms with .NET 4 64-bit applications, launch an elevated command prompt and edit the file C:\Windows\Microsoft.NET\Framework64\v4.0.30319\machine.config.  (Do this for each .NET Framework version that will need to take advantage of the new hash algorithms.)  You'll want to add the following section just before the end of the file (or at least, not before the configSections area, which must always come first): 

 Almost there -- the only remaining task is to associate the new hash algorithm to your SqlMembershipProvider in the web application's Web.config file:

And, that's all there is to it.  Of course, bear in mind that any pre-existing users in the database will need to reset their passwords, as the SqlMembershipProvider doesn't include any per-password details about the hash algorithm used to create it... so, simply applying this new configuration to an existing user database will cause every login attempt to fail, considering that the default algorithm is salted SHA1 or SHA256.

One important note: in order to achieve a balance of server performance and security, the version of Zetetic.Security uses 5,000 computations of PBKDF2, and 2^10 rounds of bcrypt.  It is certainly possible to increase these factors, but we'd opt to do so in separate classes, so that no easily-forgotten configurations are needed to maintain consistent hash results.

Tempo Maintenance: Wed Mar 28th, 10pm EDT

Permalink - Posted on 2012-03-27 19:35

Our time-tracking service, Tempo, will be temporarily unavailable at 10pm EDT tomorrow evening (Mar 28, 2012) will we perform some minor maintenance. This includes a few security related updates, and a fix for admins who need to manage access to multiple projects. We expect the outage to be brief. Thanks in advance for your patience!

1Password Alternative: Migrating from 1Password to the STRIP password manager

Permalink - Posted on 2012-03-21 15:32

In ElcomSoft's recent presentation demonstrating attacks on popular password managers, the researchers discovered an optimized brute force attack against 1Password due to the use of PKCS7 padding and lack of key strengthening. They suggest that this flaw makes it easy to brute force 1Password, unless a sufficiently complex password is used (e.g. that it would take less than a day to crack a 14 digit numeric or 7 character, fully random and alphanumeric password).

1Password is a popular and flexible application. They have rapidly responded to the concerns, encouraging the use of stronger passwords with the tool, planning to plug gaps by eliminating the use of PKCS7, adding PBKDF2 key derivation, and ensuring that all data is encrypted with the master key. These are excellent steps that should help to strengthen 1Password against brute force attacks. 

Despite these planned changes, we've recently seen increased interest from users wanting to migrate data to STRIP because it was recognized at the same conference as the "most resilient to password cracking" and one of the only applications that properly implemented strong cryptography. As a result, we've expanded our previously announced Strip conversion tool to provide simple migration of 1Password exports.

The Convert to STRIP utility is free to use and runs on Windows and Mac OS X. This process assumes that you have already downloaded and installed STRIP Desktop or STRIP Sync and the Conversion tool. Once you have migrated the data on your desktop you can simply sync with STRIP for iOS to get the data onto your mobile device.

Get STRIP Now »

Convert to STRIP for Windows »

Convert to STRIP for OS X »

Export the 1Password data

Launch 1Password and login. Once the application is unlocked, go to the application's File menu, select Export All -> 1Password Interchange File.... In the dialog that appears, you can keep the suggested name for the file, click on Where to select your Desktop, and then Export


Convert 1Password Export

  • Download the STRIP Data converter onto your desktop and Unzip it. Double click the icon to run it.
  • Click "Source File" button and choose the 1Password export file.
  • Click the Save As button and save strip.csv on the desktop.
  • Make sure that "1Password .1pif" radio button is selected for Source Format.
  • Click "Run Conversion" to migrate the file to the Strip export format.

Verify Data (Optional)

There is now a 'strip.csv' file on your Desktop. You can open it in a spreadsheet editor to check its contents (e.g. OpenOffice.org, Numbers, Excel), or open it in a simple text editor. It's a good idea to check the data over for accuracy before importing it into STRIP.

Import into STRIP

Log into STRIP Desktop or STRIP Sync, go to the File menu, and select "Import...", and choose the strip.csv file on your Desktop. 

Once the import is complete you'll see all of your 1Password data right in STRIP! Once you've checked that everything looks OK in strip you should delete the two plaintext import/export files (remember to empty your trash, or even better, securely delete them).

SplashID Alternative: Migrating from SplashID to the STRIP password manager on Windows and Mac OS X

Permalink - Posted on 2012-03-20 15:57

Hot on the heels on of the Mac OS Splash ID migration script, we've now prepared an easy to use, graphical SplashID converter called Convert To Strip, for Mac OS X and Windows.

In case you missed it, ElcomSoft recently presented a paper demonstrating attacks on several popular Password Managers. One of the most critical flaws was identified in SplashID, where the researchers found that a global key was used to encrypt the master password, rendering it instantly recoverable.

This converter is intended to help users migrate all of ther sensitive data from a SplashID export file into STRIP, the password manager recognized at the same conference as the "most resilient to password cracking" and one of the only applications that properly implemented strong cryptography.

This process assumes that you have already downloaded and installed Strip.

Get STRIP Now »

Export the SplashID data

Launch SplashID Safe and login. Once the application is unlocked, go to the application menu, select Export, choose the first SplashID vID format, choose Export All Records, and un-check Export Attachments. You can keep the suggested name for the file, click on Where to select your Desktop, and then Save. When prompted, enter a blank password.

Convert SplashID Export

  • Download the STRIP Data converter onto your desktop and Unzip it. Double click the icon to run it.
  • Click "Source File" button and choose the Splash ID export file.
  • Click the Save As button and save strip.csv on the desktop.
  • Click "Run Conversion" to migrate the file to the Strip export format.

Convert to STRIP for Windows »

Convert to STRIP for OS X »

Verify Data (Optional)

There is now a 'strip.csv' file on your Desktop. You can open it in a spreadsheet editor to check its contents (e.g. OpenOffice.org, Numbers, Excel), or open it in a simple text editor. It's a good idea to check the data over for accuracy before importing it into STRIP.

Import into STRIP

Log into STRIP Desktop, go to the File menu, and select "Import...", and choose the strip.csv file on your Desktop. 

Once the import is complete you'll see all of your SplashID data right in Strip! Once you've checked that everything looks OK in strip you should delete the two plaintext import/export files (remember to empty your trash, or even better, securely delete them).

SQLCipher at the BlackHatEU ElcomSoft Presentation

Permalink - Posted on 2012-03-20 13:26

During the third day of the BlackHatEU conference, Andrey Belenko and Dmitry Sklyarov of ElcomSoft presented an analysis of iOS and Blackberry password managers entitled “Secure Password Managers” and “Military-Grade Encryption” on Smartphones: Oh, Really?. It was a complete analysis of 17 of the most popular password management programs showing that many password managers store data in an unencrypted format, "encrypted so poorly that they can be recovered instantly", or are susceptible to basic cracking techniques.

One of the apps reviewed in the paper was Zetetic's Strip Lite, which is backed entirely by SQLCipher. As such, the results of their findings hold true for all apps using SQLCipher. From the reports we've heard it was noted as the one exception that properly implemented strong cryptography, was "by far the most resilient app to password cracking", and the most secure app for iOS.

However, the paper includes some brute force cracking estimates that serve as an important reminder about the need to use a strong passphrase when encrypting data. Their estimates show clearly that given suitably fast GPUs it would be possible to brute force standard numeric PIN numbers due to their low entropy / small search space. 

This topic has been discussed exhaustively on the SQLCipher mailing list in the past, but the security of SQLCipher is highly dependent on the security of the key used. Even though we take great pains to increase the difficulty of brute force attacks using PBKDF2, and avoid dictionary / rainbow table attacks with the per database salt, these techniques can only be successful if a suitably strong key is chosen.

The original whitepaper contains all of the source information, and you can also read more about our initial thoughs on the analysis.

SplashID Alternative: Migrating from SplashID to the STRIP password manager on Mac OS X

Permalink - Posted on 2012-03-18 20:52

Update 3/21/2012: We've released a graphical tool for Windows and OS X called Convert to Strip since we published this article. It's for converting your SplashID (or 1Password) data to STRIP's CSV format, read about and download Convert To Strip here.

At BlackHatEU last week, ElcomSoft presented a paper where they demonstrated attacks on several popular Password Managers. One of the most critical flaws was identified in SplashID, a popular password manager for iOS. The researchers found that a global key was used to encrypt the master password, rendering it instantly recoverable. A working exploit has already been published.

In light of this critical problem, there has been some interest from prospective customers in migrating to STRIP, which was recognized at the same conference as the "most resilient to password cracking" and one of the only applications that properly implemented strong cryptography.

To help support migration of users from SplashID to Strip, we we developed this conversion script that can run through the SplashID file and create a CSV file that you can import into STRIP Desktop or the free StripSync helper app. The following example assumes some familiarity with the Terminal app for OS X, that the SplashID export file is named "SplashID Export.vid," and that it's in the same directory as the Ruby script.

Note: There is now a free conversion tool available for windows too!.

0. Download the script and save it to your Desktop

Download this zip file containing convert.rb and expand it. Copy the convert.rb file to your Desktop.

1. Export the SplashID data

Launch SplashID Safe and login. Once the application is unlocked, go to the File menu and select Export, then SplashID vID.

On the panel that appears (below) select Export all records, and un-check Export Attachments. Keep the suggested name for the file, click on Where to select your Desktop, and then Save. When prompted, enter a blank password.

2. Convert the data

Open the Terminal.app and enter the following commands:

    cd ~/Desktop
    ruby convertb.rb

You should see output similar to the following:

    $ ruby convert.rb
    Examining SplashID Export.vid...
    We've found 11 entries, composing output...
    Your file strip-import.csv is ready for import into STRIP!

3. Check the data

There is now a 'strip-import.csv' file on your Desktop. You can open it in a spreadsheet editor to check its contents (e.g. OpenOffice.org, Numbers, Excel), or open it in a simple text editor. It's always a good idea to check the data over before importing it into STRIP.

In my case, since I already had data in STRIP, I set the Category to "SplashID Data" in the spreadsheet for each row so that all the new entries would show up together in the next step.

4. Import the data into STRIP

Log into STRIP, go to the File menu, and select "Import...", and choose the strip-import.csv file on your Desktop.

Once you've checked that everything looks OK in strip you should delete the two plaintext import/export files and remember to securely empty your trash.

ElcomSoft’s Password Manager Shakedown

Permalink - Posted on 2012-03-16 20:29

During the third day of the BlackHatEU conference, Andrey Belenko and Dmitry Sklyarov of ElcomSoft presented an impressive analysis of iOS and Blackberry password managers entitled “Secure Password Managers” and “Military-Grade Encryption” on Smartphones: Oh, Really?.

The results are shocking: of the 17 password management programs analyzed, they showed that most of the products, including many of today's most popular password managers, are either:

  • storing data in an unencrypted format, 
  • "encrypted so poorly that they can be recovered instantly"; or 
  • susceptible to basic cracking techniques (i.e. rainbow tables)

The sole exception in the study was our own password manager, Strip, backed by SQLCipher.

The presenters noted that Strip, using an encryption key derived through 4,000 iterations of PBKDF2-SHA1 was "by far the most resiliant app to password cracking" and appeared to be the only application that properly implemented strong cryptography. We're pleased that ElcomSoft found Strip to be a solid implementation, and that it was noted as the most secure App during the presentation.  

It's important to note, however, that the detailed cracking analysis found in their white paper provides an excellent demonstration of the need to use a secure master password. Given the enormous power of today's CPU and GPUs it is possible to attempt an attack on a weak passphrase, even though key derivation protects against rainbow tables and slows down brute force searches. ElcomSoft's estimations show that using a powerful GPU it would be possible to try every combination numeric passwords in a short period of time. 

Keeping that in mind, Strip's security really comes down to the security of your passphrase. Use a long alphanumeric passphrase with a combination of upper case, lowercase, digits, and metacharacters. For comparison, the calculations presented in the ElcomSoft paper yield that an 8 character random ASCII password for Strip and SQLCipher would take an estimated 1,315 years to crack.

If you're interested in reading more about the types of attacks and security issues with these sorts of application's please check out the excellent source presentation and whitepaper. Likewise, if you're interested in moving to a mobile password manager with a higher level of security than the rest, you should take a look at Strip.

Who’s Resetting Passwords?

Permalink - Posted on 2012-03-15 15:55

Monitoring a large Active Directory and Windows environment with Zetetic Combine can turn up some interesting things... in this case we took a look at a Combine beta program participant's administrative password reset activity over the last few weeks.

It's a colorful chart, and a long one! Over 50 distinct support and administrative folks have been helping locked-out users around the globe. Of course, it's always good policy to make sure the people exercising these rights are doing so properly... all the more reason to implement good security log collection and analysis policies.

(The names have been obscured to protect the innocent, as well as the mostly-innocent.)

Forefront Identity Manager + Lotus Notes

Permalink - Posted on 2012-03-14 17:13

At Zetetic we do a lot of work for our clients with Microsoft's identity management stack: Active Directory, AD Federation Services, Forefront Identity Manager 2010, and its predecessors Identity Lifecycle Manager 2007 and Microsoft Identity Integration Server 2003.  FIM is a great tool, but--perhaps unsurprisingly--its connector to Lotus Notes has always come up a bit short because:

  • It can only talk to the Domino Names and Address Book with predefined fields and behaviors
  • It's limited to exactly one running Notes management agent (MA) at a time
  • It has a tendency to crash the FIM Synchronization Service, usually requiring a reboot, when the Notes API gets out of whack
  • Microsoft only officially supports a few legacy versions of the Notes client and server

(It's also impossible to prevent the standard Notes MA from complaining about replication-save conflicts or incomplete records, which then foul up the delta import process, but I digress...)

Having worked for years in the Notes and Domino development arena before switching full-time to C#, it seemed only natural to build a MA that bridges the gap between the many, many real-world business uses of Notes databases and FIM / ILM, while at the same time keeping the large, complex Notes client API out of the FIM server process.  

Our solution to this problem is a two-parter:

1. A backend Windows service that manages all native access to the Notes API, and exposes a facade of Notes sessions, databases, documents, and the Notes Certification Authority, via .NET 2 TCP Remoting, and,

2. An Extensible MA for FIM / ILM that communicates with the .NET Remoting service to implement FIM's import and export operations.

The result is a FIM agent that uses only .NET managed code, moving all the native Notes stuff into a separate process--or even better, a separate host.  Upgrading or moving FIM then no longer means dealing with the Notes client, or whether the 64-bit FIM process will have trouble with 32-bit Notes, or even trying to find the older editions of Notes that the FIM product supports.

We think this solution is an ideal fit for any FIM / ILM customer with Notes business databases or identity infrastructure in their environment because it greatly extends FIM's reach to read and update Notes databases, while also providing a serious boost in reliability.  It's tremendously useful for application and messaging migration, easy to set up, and we provide full support to get your FIM to Notes and Domino integration configured and running.

For more information: Zetetic Management Agent for IBM Lotus Notes and Domino

SQLCipher for Android 1.1 Released

Permalink - Posted on 2012-03-13 21:11

A new build of SQLCipher for Android is now available, binaries can be found here. With this latest release we've added support on the Android platform spanning versions 2.1 through 4.0.3. Due to our expanded support, a new ICU zip file entitled icudt46l.zip is being included which replaces the older icudt44l.zip. A tutorial covering application integration of SQLCipher for Android and building the source can be found here.

Point In Time Recovery From Backup using PostgreSQL Continuous Archving

Permalink - Posted on 2012-03-09 18:55

Last year, around this time we, published details of how we setup PostgresSQL backups using Continuous Archiving. This technique involves continuous WAL archives combined with a daily "baseline" backup script:

Backups are only half the picture, though; the ability to easily restore data is just as critical. Unfortunately, the recovery process, as documented, can be a bit complex. Here is an distilled, exact step-by-step procedure we use to recover from backup.


This assumes that hot-backups are enabled in postgres. Ensure the following are setup in postgresql.conf on the box where the backups are located

wal_level = hot_standby                 # minimal, archive, or hot_standby
archive_mode = on               # allows archiving to be done
archive_command = 'cp -n %p /backup/postgresql/%f'

Understanding the Backup Folder Structures

The PostgreSQL WAL-based backup approach is structured on a base backup, and then a set of transaction logs that can be applied on it.

Via the backup script, daily baselines are stored in the PostgreSQL backup folder, /backup/pg_backups, in folders like this:

drwxr-xr-x    2 106      113           4096 Aug 24 05:15 2011-08-23.09:00:01
drwxr-xr-x    2 106      113           4096 Aug 25 05:16 2011-08-24.09:00:01
drwxr-xr-x    2 106      113           4096 Aug 26 05:16 2011-08-25.09:00:01
drwxr-xr-x    2 106      113           4096 Aug 27 05:16 2011-08-26.09:00:01
drwxr-xr-x    2 106      113           4096 Aug 27 05:19 2011-08-27.09:00:01

In this case, the folder is named after the current date and the base backup. For example, the folder named 2011-08-25.09:00:01 would contain the base backup from 9 AM UTC, along with the WAL log files archived between 2011-08-25.09:00:01 and 2011-08-26.09:00:01. Thus, to restore to any point in that time you should use the files from that backup folder:

  1. base.tar.bz2 - full backup of the postgresql data folder (i.e. /var/lib/postgresql/9.x/main)
  2. pit-wal.tar.bz2 - point in time logs captured for transactions active while the base snapshot was being taken
  3. full-wal.tar.bz2 - the archive of all transaction logs present between the base backup and the following day's base backup

In the case of the current date, the folder corresponding to today's date will contain the base backup (base.tar.bz2) and the point in time logs pit-wal.tar.bz2. However, the full-wal.tar.bz2 file will not be present because the day's logs have not been archived yet. Instead, the current day's archive logs are stored in the archive logs directory, /backup/postgresql.

There are two options for data restoration:

  1. restore up to the last backup point in the current date
  2. restore to a previous day's backups

The process between these two is basically the same, the only difference is whether the WAL logs are extracted from the full-wal.tar.bz2 or taken from /backup/postgresql

Step 1. Copy data backup

Copy all the files from the appropriate backup folder to your home directory. The following assumes you have the archive files in the home directory of ~postgres (substitute as necessary).

In order to perform the restore, we'll create a temporary directory in which to stage the files.

cd ~postgres
mkdir restore
cd restore

Step 2. Extract base data and PIT logs

tar xjf ~postgres/base.tar.bz2
tar xjf ~postgres/pit-wal.tar.bz2
cd backup/postgresql

Step 3. Extract WAL data

  • If you are restoring from a previous day
    tar xjf ~postgres/full-wal.tar.bz2
  • If you are restoring from the current day
    cp /path/to/today/backup/postgresql/* .

Step 4. Shutdown Postgres

# shutdown postgres
sudo su -
service postgresql stop

Step 4. Restore main data directory

Start by moving into the base version directory. Move the existing main folder out of the way, then move the restored base back into place

cd /var/lib/postgresql/9.x/
mv main main.bak
mv ~postgres/restore/var/lib/postgresql/9.x/main main
cd main

Step 5. Create a recovery.conf

Now that the base backup is restored, you must to tell PostgreSQL how to apply the recovery procedure. First, create file called recovery.conf in the data directory, /var/lib/postgresql/9.x/main/recovery.conf. The contents should minimally include the following line, adjusted to the location of the WAL files.

restore_command = 'cp /home/postgres/restore/backup/postgresql/%f %p'

If you only want to apply transactions up to a specific point in time, for instance to recover to the middle of a specific day, add the recovery_target_time (note the time stamp will be relative to UTC):

recovery_target_time = '2011-08-27 04:00:00.0'

Step 6. Start PostgreSQL

service postgresql start

When PostgreSQL has finished restoring the files the recovery.conf file will be renamed to recovery.done.

Note: Information and additional details from:


SQLCipher in The Busy Coder’s Guide to Advanced Android Development

Permalink - Posted on 2012-03-06 21:10

The latest version of the Busy Coder's Guide to Advanced Android Development, published by CommonsWare, has recently been released. Chapter 21, Advanced Databases, is dedicated to database techniques like encryption. SQLCipher for Android is featured prominently along with a tutorial and discussion of proper integration techniques.

If you've been looking for a good book on advanced Android development topics that includes SQLCipher database encryption you should definitely check it out!

PRAGMA cipher_default_use_hmac = OFF;

Permalink - Posted on 2012-03-01 15:59

We needed a new PRAGMA! These things happen.

With the release of SQLCipher 2.0, a PRAGMA was added (cipher_use_hmac) which disabled the new per-page HMAC protection feature before opening a database, so that a developer wishing to run SQLCipher 2.0 against a 1.x database could do so. This was important to us because we wanted to provide an easy way for developers to migrate to the new database format. Generally speaking, you'd want to do something like this:

  1. Open the legacy database, set your key
  2. Call PRAGMA cipher_use_hmac = OFF; before opening the legacy database
  3. ATTACH a new, empty database, which will be encrypted by default and have HMAC on by default
  4. Copy your database into the attached database using sqlcipher_export()

That scenario looks about like this on the command line:

$> ./sqlite3 my-legacy-encrypted.db
sqlite> PRAGMA key = 's3cr37';
sqlite> PRAGMA cipher_use_hmac = OFF;
sqlite> ATTACH DATABASE 'new-sqlcipher2.db' AS newdb;
sqlite> SELECT sqlcipher_export('newdb');
sqlite> DETACH DATABASE newdb;

But there are other scenarios, ones in which we really needed to be able to ATTACH one legacy database to another (e.g. data replication). Even though we'd have called PRAGMA cipher_use_hmac = OFF; when opening the first database, the ATTACH operation assumed the new default format, and would report back "database is encrypted or is not a database."

We didn't wish to modify the ATTACH command, and we didn't want to change the behavior of cipher_use_hmac, as the latter's behavior is necessary for developers who wish to migrate and upgrade their databases. Instead, Stephen came up with a new PRAGMA, cipher_default_use_hmac, which is a globally applied setting in SQLCipher, allowing you to turn HMAC protection on and off before you open or ATTACH another encrypted database, so you only need to bother with one setting in your app. Here's an example (where custom_data_replicator() is a made-up function):

$> ./sqlite3 my-legacy-encrypted.db
sqlite> PRAGMA cipher_default_use_hmac = OFF;
sqlite> PRAGMA key = 's3cr37';
sqlite> ATTACH DATABASE 'remote.db' AS remote;
sqlite> SELECT custom_data_replicator('remote');
sqlite> DETACH DATABASE remote;

Pretty dang handy and available now on the master branch—stay tuned to the mailing list for details on new tags and release numbers. You can see the changes here along with updated unit tests.

Meanwhile, I've made some mods to SQLCipherManager to support this specific scenario. Setting the property useHMACPageProtection causes the new global PRAGMA to be called before a database is opened, rather than the older cipher_use_hmac. This allows you to attach 1.x or 2.x databases at will, by changing the setting when you need to, like so:

self.dbManager = [SQLCipherManager sharedManager];
[self.dbManager setUseHMACPageProtection:NO];
@try {
  [self.dbManager execute:
    [NSString stringWithFormat: @"ATTACH DATABASE '%@' AS remote;", [replicaURL path]];
  [self.dbManager beginTransaction];
  [self.dbManager execute:@"SELECT custom_data_replicator('remote');"];
  [self.dbManager commitTransaction];
  [self.dbManager execute:@"DETACH DATABASE remote;"];
@catch (NSException *exception) {
  // SQLCipher's execute: command now provides handy exceptions!
  // For traditional error handling, use execute:error: instead.
  NSLog(@"Command failed: %@", [exception reason]);

Strip for Android Coming Soon

Permalink - Posted on 2012-03-01 14:36

One of the most frequent requests we receive for Strip is support for Android. Android is one of the largest mobile platforms next to iOS. To support this, we first needed to port SQLCipher onto the Android platform. SQLCipher is our open source extension to SQLite that allows for transparent 256-bit AES encryption of database files. We began last year working in conjunction with The Guardian Project on this process. This has required bundling a custom build of the ICU project to allow portability across Android versions 2.1 through 4.0.3 (Ice Cream Sandwich). You can read more on integrating SQLCipher for Android here. With this out of the way, we've been focusing on the application development work and are nearing completion for an initial delivery.

Unlike the iOS platform, where users upgrade to the lastest iOS release quickly, the Android platform is more fragmented due to manufacturers playing a role in the update distribution process - more about this here. That said, we have been working to target Android versions 2.1 and up for Strip on Android - targeting the majority of users. We have also tried to maintain a consistent user experience between the iOS application and Android where it makes sense. An example of where the iOS and Android platforms differ is in their drag and drop support. iOS provides a native drag and drop interaction within their UITableView, requiring you to set an editing mode and handle a few events. On Android however, support was added in 3.0 for drag and drop, prior to that you are left with the implementation details. If you want to be notified when we release Strip for Android, sign up here. We are very excited about adding support for the Android platform and hope you are as well. We will leave you with a screenshot of the upcoming Strip for Android. Thanks!

Strip for Android

Intro to iPad, iPhone, &amp; iOS Application Development at Cowerks

Permalink - Posted on 2012-02-27 23:07

Bret Morgan of Cowerks, a good friend of Zetetic, is organizing a cooperative learning program in late April designed to give participants a crash course in iPad/iPhone development.

The approach is unique; instead of a traditional "teacher leads, students learn" class model, participants will work together as a cooperative development group. Following the first half of the Stanford University CS193P iPhoneApplication Development curriculum, the goal is to cover a wide range of iOS topics in just 8 weeks of sessions:

  • Walkthrough of iOS 5
  • Objective-C
  • Views
  • Autorotation, Protocols, & Gestures
  • View Controllers
  • UIToolbar and iPad Apps
  • Controller Lifecycle & Image/Scroll/WebViews
  • Table Views

With the course materials and group as a guide, attendees will work both collaboratively and on their own time to learn Objective-C and the relevant SDKs.

It's a really neat concept, so if you're in the NJ area and you've been waiting for a reason to learn iOS development, this could be a great opportunity. Classes start on April 23rd, and registration is open now with early-bird discounts at http://cowerks-ios.eventbrite.com.

SQLCipher 2.0 Released

Permalink - Posted on 2012-01-30 19:52

SQLCipher started out as a small "proof of concept" project to encrypt databases for one of our iPhone apps. It has grown over the past three years to become one of the most widely deployed encrypted database libraries. Today, SQLCipher has been integrated on numerous platforms including iOS, Mac OSX, Ruby, Python, Windows, ADO.NET, Java, and, with the help of the team at the Guardian Project, Android.
Today, we are pleased to announce the release of SQLCipher version 2.0. This release incorporates much of the feedback we've received since the start of the project. Most notably, SQLCipher 2.0 enables tamper resistent databases, performance improvements via custom database page sizes, and easier conversion between database formats. The detailed list of new features and security enhancements follows:
  • Per page HMAC -  Every database page now includes a message authentication code (MAC) so that individual pages are non-malleable. This change prevents potential attackers who have write access to a database file from making subtle changes to an encrypted page to introduce errors or attempt attacks.
  • Custom Page Sizes - This new version introduces a new pragma, cipher_page_size, that can be used to adjust the page size for the encrypted database. This is useful for applications where a larger page size is desirable to increase performance. 
  • Memory Locking - SQLCipher will lock heap memory used for its internal contexts and key storage, advising the OS that the memory should not be swapped out.
  • Pragma Improvements - Separate pragma settings can now be applied to attached databases to support different configurations (i.e. to attach a database with a different key or cipher settings).
  • Export - Introduction of a sqlcipher_export convenience function that mirrors the main database schema and data to an attached database. In conjunction with the previous pragma improvements, this allows migrations between encrypted / non-encrypted databases, and adjustments to various settings.
  • Code Reorganization - SQLCipher has been refactored to separate the SQLite codec hooks from the encryption implementation. This makes the codebase easier to understand, audit and extend.  
  • Updated version of SQLite - Based on a newer stable upstream SQLite release, 3.7.9 
  • Expanded test fixtures - The SQLCipher test suite has almost doubled in size as we've added coverage for even more common use cases and new features. 

Like past releases, SQLCipher 2.0 is open source software, distributed under a liberal BSD-style license. We also have binary releases available for sale and licensing on Windows Platforms.

Over the course of the next few weeks we'll be posting more information and details on the new features. We hope you'll find SQLCipher 2.0 is even more secure and full-featured than its predecessor, while preserving the same performance characteristics and no-configuration application implementation of the original. Please check out the new version on GitHub and let us know what you think.


SQLCipher 2.0 Final Released

Permalink - Posted on 2012-01-30 00:00

Big news today, Stephen just announced the final release of SQLCipher 2.0! That’s our new(ish) blog for folks who want to subscribe to a news feed specific to the SQLCipher project. Check out the long list of improvements and stay tuned for more updates this week regarding the new features.

Another bit of SQLCipher news you may have missed, if you don’t follow the mailing list: we’ve created an SQLCipher “organization” on Github, and moved the main repo and various associated, supporting projects under it. Find it here on Github!

Codebook 1.6.1 Released

Permalink - Posted on 2012-01-12 00:00

Codebook 1.6.1 is now available in the iTunes App Store, providing one of the biggest feature upgrades the app has seen to date. Many of these new features were on our customers' wish-lists for some time, and they make the app much nicer to use. Read on to find out what’s changed!

What’s New

  • In-app prefs are now accessible from Note view toolbar
  • Alpha-numeric sorting option for notes
  • Search inside a note and jump directly to text
  • Manual sorting option for notes
  • AutoCorrect for note editing now available
  • Preference to clear pasteboard on exit
  • Share note via email as password-protected PDF
  • Adjustable font face and size for notes
  • Updated password reset screen
  • Auto-upgrade database schema on Dropbox when possible
  • iOS 3 is no longer supported

Bug Fixes

  • Cancel button on dropbox login controller did not work in iOS 5
  • Deleting a note in search view caused crash
  • Dropbox sync failed on database version mis-match, reported password mis-match
  • Editing in landscape mode was a little busted
  • Error messages during sync were cryptic

Strip 1.6.3 Released

Permalink - Posted on 2012-01-06 00:00

As of Jan 4th, Strip 1.6.3 (for iOS) is available in the iTunes App Store. This is our best release of Strip to date, providing a slew of major and minor bug-fixes over the previous rev, and a number of new improvements and features. All customers are strongly encouraged to upgrade, this should be a smooth one.

What’s New

This may seem like a minor thing, but the password reset screen got a lot of needed love, as did the shake-to-generate password generator. The latter no longer requires you to shake the device to generate a password, but the accelerometer is still being used for entropy, so we encourage you to wave your iPhone around in public like a maniac before settling on a random password.

There’s also a couple of new preferences available in Settings: defaulting the login keyboard to the numeric keypad (we still discourage this, but it’s been on some of your wish-lists for a long time), and ensuring the pasteboard is cleared of copied data when you exit Strip.

What’s Been Fixed

Editing text for notes in landscape mode has been fixed, and we’ve made it easier to view longer field values on the entry screen by shrinking longer text a bit to fit. We also fixed a nasty but hard-to-track-down bug involving memory warnings and the login screen, which could cause the screen to go blank, and data loss could occur in obscure cases as a result.

Sync operations on the whole should be smoother, and error messages far more informative. In addition, we fixed a couple of nuisance issues you could run into when syncing with Dropbox. Strip now properly reports whether the remote database has a different password (or a different database version—it will automatically update an older database schema before replicating). When a Dropbox operation errors out due to such a condition, Strip will remove the lock-file it places in your Dropbox so you don’t get an additional error on your next sync.


Thanks are due to our beta testers! Thanks very much for taking a chance on the newest version of Strip before we were sure it was ready for public distribution.

System Maintenance Sun Dec 11, 9pm EST

Permalink - Posted on 2011-12-09 00:00

This Sunday night, December 11th at 9pm EDT, Tempo and our other web systems will be temporarily unavailable while we perform critical system updates to ensure the stability of our services. This includes the Tempo API, the purchase site for Strip for Windows, the Connect website, our support site for Codebook, and zetetic.net, hosting this blog.

Down time could last up to 2 hours, but we do not expect this to be the case. If you need to get in touch with us for any reason, please don’t hesitate.

SQLCipher for Android Released

Permalink - Posted on 2011-11-30 15:21

We are happy to announce that version 1.0 of SQLCipher for Android has been released. With this latest release, a collaborative effort between The Guardian Project and Zetetic, much work has gone into stabilization of the library across various Android versions. For those unfamiliar, SQLCipher for Android allows a drop-in replacement of the standard SQLite database used on Android to encrypt application databases.

Now that SQLCipher is supporting Android with this latest release, we have written up a tutorial covering both the integration of SQCipher for Android into an Android application as well as the steps required to build SQLCipher for Android from source. The latest binaries are available here. In an era where mobile security continues to be a threat, protecting your data becomes ever more important.

System Maintenance Tues Nov 29, 19pm EST

Permalink - Posted on 2011-11-28 00:00

This Tuesday night, November 29st at 9pm EDT, Tempo and our other web systems will be temporarily unavailable while we perform critical system updates to ensure the stability of our services. This includes the Tempo API, the purchase site for Strip for Windows, the Connect website, our support site for Codebook, and zetetic.net, hosting this blog.

Down time could last up to 2 hours, but we do not expect this to be the case. If you need to get in touch with us for any reason, please don’t hesitate.

Strip 1.2 for Windows Released

Permalink - Posted on 2011-11-28 00:00

Last week we had a quiet release that we forgot to mention here on the blog, an important update to Strip for Windows. This version includes our Dropbox Sync feature, making it possible to sync your Strip data via Dropbox to iOS, OS X, and Windows.

Full change-log:

  • New Feature – Synchronize Strip desktop with Dropbox!
  • New Feature – New application toolbar for quick access to application functions
  • New Feature – Support field reordering via drag-n-drop move handle
  • Improvement – Improved integrity check command finds and fixes improper field indexes
  • Improvement – Double click non-url fields to switch entry into edit mode
  • Improvement – Proper centering and alignment of modal dialogs
  • Bug Fix – Allow export of data sets containing empty field values
  • Bug Fix – Installer now shows proper program name instead of random string

If you have any questions or feedback, please get in touch.

Strip for iOS 1.6.1 Login Bug on iOS 5

Permalink - Posted on 2011-11-02 00:00

We released Strip 1.6.1 to the iTunes App Store and then pulled it from the store a few hours later yesterday due to confirmed reports of a bug preventing our customers on iOS 5 from accessing their data after successfully signing into the application. It’s that bug scenario you always fear as a developer with the App Store—something that you simply must fix right away, but can’t due to the app review process. We have already submitted a fix to Apple as version 1.6.2 and requested expedited review due to the circumstances.

We pulled the update to make that sure no one else gets bitten, and as a result Strip is currently not showing up in the iTunes App Store. There’s unfortunately no way for us to rollback a version update once it’s on your device.

We know this is a horrible inconvenience, but our recommended option is to wait for the forthcoming App Store update because it is the safest and lowest-impact fix. However, if this is not an option there are two other potential courses of action:

  1. Sign up for our TestFlight beta service. If you become a beta tester for Strip we can send you a new version before it hits the app store. However, this process involves a sign-up and registration of your device. You can sign up and register devices here: http://tflig.ht/nxGEhq
  2. Restore from backup using iTunes. As long as you haven’t synced your device since the update was installed, you should be able to restore from backup. Unfortunately this would erase any data from Strip and other applications that was not in the last backup. If you are think you might need to do this please don’t sync your phone with iTunes, as it could overwrite your last backup. This should be a last resort due to the potential for data loss.

We’re really very sorry about the problems this has caused – we are doing our best to get this fixed as soon as possible.

Migrating Strip Data To A New Device

Permalink - Posted on 2011-10-17 00:00

Since the availability of the iPhone 4S and iOS 5, many of our customers are upgrading to new iPhones (in particular, it would seem, the 3Gs users!) and are running into trouble because they often find that after the upgrade and after iTunes supposedly copies their data, data from their old device is not there, including Strip data. Stephen Lombardo, chief here at Zetetic, has put together the following upgrade advice for our customers. -Billy Gray

The easiest and most reliable way to migrate data from one device to another is to use one of Strip’s sync and backup features. Here are the backup and restore options:

Option 1: Desktop backup / restore

Strip has two desktop application that support syncing. The first, Strip Desktop, is a full editing environment with a backup facility. The second, Strip Sync, is a free utility you can install on your computer that just supports backup and restore. Both are available for download from getstrip.com.

In either case, you’ll want to start by installing one of the programs and syncing your old device with your computer. You can do this by running the desktop program, then switching to the Sync tab on the device, locating the computer to sync with, and running the basic sync operation (do not use Restore or Overwrite for this).

Once you have a solid backup of your data on your computer, the restore process to the new phone should be quite easy:

  1. Download Strip onto your new device. Run the program the first time and be sure to use the same password you used on your old phone and for Strip / Strip Sync on the desktop.
  2. Run strip / strip sync on the desktop and log in with your password.
  3. Back on your phone move to the sync tab.
  4. Choose computer and find your desktop in the list
  5. For Sync Operation type chose “Restore from Desktop”, with the the icon that shows the arrow pointing from the computer to the phone (This will overwrite the local database on the iPhone with a copy from the computer)
  6. Tap Sync and agree with the warning that says you’ll overwrite your device data from the desktop
  7. Once it’s compete you’ll have a complete copy of your Strip data on your new phone

Option 2: Dropbox backup / restore

The latest version of Strip in the App Store supports backup and sync with Dropbox. If you are a Dropbox user, or don’t mind signing up, you can perform the backup and restore with it’s cloud data service. JUst make sure you are running the latest version of Strip on both your devices. Then, on your old device, initiate a backup to Dropbox on the Sync tab.

Once that is complete, you can restore it to your new device.

  1. Run Strip on your new Device, and be sure to use the same password you used on your old phone
  2. After logging in on your new device, move to the sync tab.
  3. Change the Mode to Dropbox and link to your account.
  4. For Sync Operation type chose “Restore from Desktop”, with the the icon that shows the arrow pointing from the computer to the phone (This will overwrite the local database on the iPhone with a copy from the computer)
  5. Tap Sync and agree with the warning that says you’ll overwrite your device data from the desktop

Option 3: iTunes backup / restore

If you really don’t want to use option 1 or 2, then it should still possible to use iTunes to restore your last backup from your old device onto the new device. I want to mention that this option is not recommended, because some users have reported data loss during iTunes sync and restore.

  1. Make sure your iPhone is not connected to your computer
  2. Open iTunes, go into Preferences –> Devices and make sure that “Prevent iPods and iPhones from syncing automatically” is checked off.
  3. Now connect your iPhone to your computer.
  4. Open up iTunes and in the devices list on the left side panel of iTunes, right-click or control-click your device.
  5. Select ‘Restore from Backup…’ If you are offered the option to choose a backup, you’ll want to choose the newest one.
  6. After the restore, log in and test the restore
  7. If the restore worked, uncheck “Prevent iPods and iPhones from syncing automatically”

Please let us know how you fare with the conversion in the comments or send us an email.

Strip for iOS 1.6.0, Strip for OS X 1.2.0 Released

Permalink - Posted on 2011-10-10 00:00

Today is a big day for us, as we’re releasing two application updates for Strip, introducing our support for Dropbox as a sync and replication target.

Strip for OS X 1.2.0

Strip for OS X got a lot of bug fixes and minor adjustments to go along with the new Dropbox sync feature. Here’s the change list:

  • Dropbox Sync integration (menu: Sync –> Sync with Dropbox)
  • Integrity Check added for recovering orphaned records (menu: File –> Integrity Check…)
  • Fix: After deleting selected category or entry, display not updated correctly
  • Fix: Sorting disabled on Customize Labels panel
  • Fix: Fields of varying height drawn over each other, obscuring data
  • Add drag-and-drop field re-ordering on an entry
  • Add copy-and-paste for entries! (useful for templating entries)
  • Drag-and-drop entries into another category
  • Ready for OS X Lion
  • Last Sync label not populated on Get Info / Database Information panel
  • Add Replica GUID and Replica CSN to Database Information
  • Add “Export as Strip CSV” option to Export so users can also export to plain CSV if needed
  • Fix crashes in Export due to empty field values
  • Fix crash on Import

Get the latest version of Strip for OS X from the Mac App Store.

Strip for iOS 1.6.0

Changes in this version:

  • Dropbox Sync integration
  • More adjustments for better landscape-orientation support (login screen rotates!)
  • Ends support for iOS 3.1.3, requires iOS 4.0 or greater
  • Minor memory leak in database connection manager eliminated

Note that with Strip for iOS 1.6.0 we are requiring our customers to have iOS 4.0 or greater installed on their devices. We realize this will be painful for a small number of some of our customers, but it’s important that we prepare the Strip platform to adopt new technologies in iOS 4 and iOS 5 while shedding the weight of deprecated APIs. Being that iPhone 3G devices and later support iOS 4, and that these all appear to run more efficiently with iOS 4, this new platform requirement shouldn’t keep many from upgrading, and will allow us to develop Strip more quickly in the future. We have big changes planned for the future, and we expect we’ll be requiring iOS 5 once we get around to releasing Strip 2.0.

Get the latest version of Strip for iOS from the iTunes App Store.

Strip for Windows 1.2.0: Coming Soon!

Strip for Windows 1.2.0, which will provide support for Dropbox sync as well, is in the works and on the way. Stay tuned for updates!

How To Sync Strip Data Across Multiple Devices

Permalink - Posted on 2011-10-10 00:00

A thing that is confusing some new customers of Strip is that replicating your data is not something that iTunes will accomplish when you sync your device. You can’t simply sync two iPhones with Strip to the same copy of iTunes in order to get the data on the two exchanged. Instead you have to avail yourself of sync features we’ve built into the apps, and they can be used in several scenarios, which we’ll discuss below.


When we originally published Strip for iOS in 2008 (then it was iPhoneOS), it was stand-alone software which presented two pressing problems. The only option for backing up your data was to use the iTunes backup feature while keeping your fingers crossed, and there was no way to share or replicate your Strip database with another device (e.g. have your passwords on both your iPhone and your iPod Touch or iPad). We needed to solve these problems before we’d have the chance to build a full desktop port for Mac and Windows, so we created the free utility Strip Sync as our backup and replication solution. In the time that’s passed we’ve finished our ports of Strip for Windows and OS X, and they will eventually replace Strip Sync, which will be discontinued. Strip for Windows and OS X handles data replication in exactly the same way as Strip Sync, so we will only refer to Strip in the rest of this article.

Please note: copies of Strip that you wish to keep in sync must share the same password.

Desktop WiFi

Desktop WiFi sync is controlled by the mobile devices connecting to the desktop. All you should need to do on the desktop side is log in to Strip and leave the app running, it will advertise the sync service on your local WiFi network and await connections. With Strip running on your desktop, you initiate sync by launching Strip on your iOS device, selecting your computer on the sync screen, and tapping a button to start the operation.

These are the basic steps:

  • Launch Strip on your desktop and login, leave it running
  • Launch Strip for iOS on your iPhone / iPod Touch / iPad
  • Tap on the sync tab
  • Make sure Operation is set to Sync (not Overwrite or Restore)
  • Make sure mode is set to Desktop WiFi
  • Tap the Computer setting
  • Select your desktop from the list of computers
  • Tap the Start Sync button

When you sync, you are not simply creating a backup (although the effect with the initial sync is similar to a backup), you are creating and maintaining a replica of your data. All changes on your iPhone are sent to the desktop, and all changes known to the desktop are passed to the iPhone. You can then initiate the same process from another iOS device (e.g. iPad) and the process is repeated—changes from both the desktop and your iPhone are passed to the iPad, and changes from the iPad are sent back to the desktop.

The network connection itself is a simple, unencrypted TCP connection. The encrypted database files are exchanged over this connection after successful completion of HMAC authentication.

It’s important to use the basic, default sync operation, which exchanges all changes on each end of the sync. Overwrite and Restore operations are available, but they should be used rarely, only for restoring lost or corrupted copies of Strip. When a device is over-written, any changes local to that device are lost.

Our sync service is a network-based one, it assumes the user has a WiFi network, and that both the mobile device(s) and the desktop computer are on that same network and can communicate freely. While this works for the large majority of our customers, it is unfortunately not always the case with a lot of home networking setups. There exists such a plethora of networking devices and configurations that it’s impossible for us to recommend settings that will always work. If you end up having trouble, do get in touch with us and we’ll do our best to help you adjust things as necessary. Meanwhile, we’re working on providing new means of sync to do an end-run around home networking, such as the Dropbox Sync covered below.

Dropbox Sync

Starting with Strip for OS X 1.2.0 and Strip for iOS 1.6.0, support for sync via Dropbox is available. On the first sync to Dropbox, Strip creates an encrypted replica of your data and stores it in your Dropbox account. No encrypted data is stored in plain-text or decrypted in your Dropbox account. On every subsequent attempt to sync, Strip downloads a copy of the encrypted replica, exchanges all changes between the replica and your local database, and then replaces the copy out on Dropbox with the updated replica.

These are the basic steps to sync with Dropbox in Strip for iOS:

  • Launch Strip for iOS on your iPhone / iPod Touch / iPad
  • Tap on the sync tab
  • Set the Operation row to “Sync”, Not Overwrite or Restore!
  • Set the Mode row to “Dropbox”
  • Tap on the Account row to sign in to your Dropbox account
  • Tap the Start Sync button

Similar to WiFi sync, the replica on Dropbox serves as an intermediary between your devices, including the desktop. In direct contrast to our WiFi/Network sync above, you don’t need Strip on your desktop to keep your iOS devices in sync. In addition, if you are thwarted by home networking troubles, you’ll find Dropbox sync a breeze. This is because almost all modern routers and firewalls allow your computer to initiate unfettered connections to remote machines on the Internet over HTTPS.

Syncing with Dropbox for Strip for OS X is quite easy:

  • Launch Strip on your Mac and log in
  • Go to the Sync menu and select “Sync with Dropbox” (Shift+Command+D)

Note: Sync with Dropbox requires that your various instances of Strip share the same password. Strip uses HTTPS to communicate with Dropbox over the Dropbox API, it does not make any unencrypted connections to Dropbox.

Codebook 1.5.4 Released

Permalink - Posted on 2011-10-10 00:00

Today we are releasing a maintenance update for Codebook, version 1.5.4. There are no feature updates, it provides fixes for crashes related to syncing with Dropbox, particularly after a user resets her password and attempts to sync with the remote replica.

Note: Version 1.5.4 will be the last version of Codebook to support iOS 3, unless any bad bugs turn up between now and the release of Codebook 1.6.0.

With Codebook for iOS 1.6.0 we will be requiring our customers to have iOS 4.0 or greater installed on their devices. We realize this will be painful for a small number of some of our customers, but it’s important that we prepare Codebook to adopt new technologies in iOS 4 and iOS 5 while shedding the weight of deprecated APIs. Being that iPhone 3G devices and later support iOS 4, and that these all appear to run more efficiently with iOS 4, this new platform requirement shouldn’t keep many from upgrading, and will allow us to add features to Codebook more quickly in the future. We have big changes planned for the future, and we expect we’ll be requiring iOS 5 once we get around to releasing Codebook 2.0.

System Maintenance Wed Sep 21, 10pm EDT

Permalink - Posted on 2011-09-20 00:00

This Wednesday night, September 21st at 10pm EDT, Tempo and our other web systems will be temporarily unavailable while we perform critical system updates to ensure the stability of our services. This includes the Tempo API, the purchase site for Strip for Windows, the Connect website, our support site for Codebook, and zetetic.net, hosting this blog.

Down time could last up to an hour, but we do not expect this to be the case. If you need to get in touch with us for any reason, please don’t hesitate.

Passion for the Finer Details

Permalink - Posted on 2011-09-12 00:00

Wow, you can’t ask for a better review than this one below by our customer Chris Ostmo in the Mac App Store, reviewing Strip for OS X. We don’t normally highlight reviews, but this one is exceptional, especially the contrast he draws between Strip and our competition. We’re a stubborn shop—we do things at our own pace, we try not to be everything to everyone right out of the gate, and that means we’re not a perfect fit for everyone. Thanks, Chris!

If you care about the security of your information, this [is] THE password manager to get. Period.I was a die-hard user of STRIP for Palm, but had been more or less forced to settle for other options in the transition to Windows mobile, and then iOS. I had not switched back to STRIP until very recently due to the lack of a Mac Desktop application. I probably wouldn't have switched back if it weren't for the fact that the competition -- although prettier to look at -- is riddled with bugs and various annoyances. Besides that, the other companies seem to be very arrogant and give off an attitude that tells me that they view their customers as a nuisance. SplashID and 1Password are the solutions that I gave a serious run at being my password manager of choice -- having purchased and used each on my desktop and iOS devices for many months. If there is any negative in switching to STRIP, it's that it isn't quite as pretty as the others. Putting that aside, Zetetic writes killer software. What they write, it is obvious that they write well, and their passion for the finer details of what it takes to have the ultimate in function is apparent in their writing about the details of the technology that their programs use in their company literature and blogs.Case in point: The "Shake-N-Make" password generator in [STRIP for] iOS uses your device accelerometer to add environmental variables for entropy to the random number generator when passwords are generated. In short, if you want anything that approaches real randomness from a computing device, this is it.If your primary concern is eye candy, this may not be the one for you. If you want great software written by a company that has an expressed passion for having the most secure and functional password manager, look no further -- STRIP is for you.

To the very many of you who’ve taken the time to leave us ratings and reviews for Strip in the iTunes and Mac App Stores, we really appreciate it. It means a lot to us, as the reviews not only help us to see how well (or not) the apps are doing, but they also help to increase the number of people who are willing to give Strip a shot and that helps to further fund development of Strip for Windows, OS X, and iOS.

For those of you who made it this far down the post, a bit of insider info: we’ve begun development of the Android port of Strip in earnest! We’ve no more info about it at this point in time, but we’re working on it.

Asbury Agile

Permalink - Posted on 2011-09-07 00:00

Some exciting news! Our colleague Mr. Bret Morgan, a talented developer, entrepreneur, and co-founder of Cowerks and BandsOnABudget.com has been hard at work trying to foster a vibrant tech and developer community on the New Jersey shore, and is now working on Asbury Agile, a one-day, single-track conference in Asbury Park, NJ “for makers and doers in the web industry.”

Featuring user interface experts, tech investors, start-up captains, experienced web gurus, it’s chock full of people who know how to start a business on the web. The kind of people you want to meet: folks who have real-world experience building software platforms. We’re quite excited to hear what they have to say, so Zetetic will be attending.

We’re sponsoring the event, and we’re offering free copies of Strip for iOS and OS X to attendees, as well as 3 free months use of our time-tracking web app, Tempo. Other sponsors include Forrst and A Book Apart. Rosenfeld Media and A Book Apart will be raffling off books on the day of the conference, and offering a 20% discount on their titles at the conf.

On a personal note, I grew up in suburbs outside of the City of Asbury Park, and back then it was the only place on the shore to go to see some punk rock. My friends and I would get into trouble breaking into the old decaying amusement palaces on the boardwalk to take photographs of the Summer sun streaming through a broken roof onto indoor vegetation. The former beach resort city had been plagued since the seventies by a depressed economy and violence, but has since made a remarkable turn-around. Fifteen years later Asbury Park is in many ways unrecognizable, with a vibrant and safe downtown, a growing community of successful entrepreneurs and artists, and hip spots to grab a beer and some greasy food with good tunes on the Hi-Fi (I highly recommend Bond St. Bar). I’m very excited to see Asbury Agile happening, it would have been unthinkable when I was fifteen playing terrible punk-metal at the Stone Pony.

We hope you’ll join us, and say hello at the conference! We’d love to talk business or tech and make some new friends.

Zetetic.Events Shell

Permalink - Posted on 2011-07-29 00:00

We’ve released some free code for LDAP and Active Directory hackers in the past, Zetetic.Ldap, but now we’ve got something for the Windows and AD sysadmins out there: Zetetic.Events Shell.

The Zetetic.Events Shell is a free, fast, and efficient tool to extract Event Log data for Active Directory and Windows computers (Server 2008, Vista, Windows 7, or newer), allowing you to find out where and when important things happened.

Sounds simple, but it’s a really dynamic instrument that’s particularly handy for security auditing, e.g. when you need to know who has changed a particular security group and when. Conceived and implemented by our identity guru Steve Kradel, we’ve found Zetetic.Events Shell to be pretty handy in the identity work we do for our clients and we think you will, too. You can download it here and see a more complete example of how it works.

Let us know what you think, if you find any bugs, or have feature requests. We’re providing the Zetetic.Events Shell at no charge in the hopes that it will be useful to the community, and as a preview of our industrial-strength, realtime auditing package, coming in late Q3 2011. Key features of the full Zetetic.Events Pro package will include:

  • Near real-time streaming of event data
  • Agent-less, durable event monitoring of dozens to hundreds of hosts
  • Pre-built, customizable capture templates for various server roles (domain controllers, file servers, web application servers)
  • Deep inspection of audit trails; view by user activity or by targets of that activity
  • Automatic topology discovery
  • Event ID library and assistant
  • Web-based management and reporting

You can join the mailing list on the download form for Zetetic.Events Shell and we’ll let you know when the Pro version becomes available.

Strip for Windows, OS X Version 1.1

Permalink - Posted on 2011-07-28 00:00

Today we’re excited to announce the first important incremental update to our desktop applications Strip for Windows and Strip for OS X. This update brings some important new features to each and helps to bring them a little closer together in terms of feature parity.

Strip for Windows 1.1

  1. Copy and paste entries (great for templating)
  2. Integrity check to identify orphaned entries dating back to Strip for iPhone beta testing
  3. Double-click URL and email fields to launch appropriate browser or application

The copy-and-paste feature already exists in Strip for OS X. We’ll be adding it to Strip for iOS very soon.

Strip for OS X 1.1

  1. Search across all entries and fields
  2. Double-click URL and email fields to launch appropriate browser or application
  3. Clean-up of internal code to help try and resolve a crash bug
  4. New key-bindings for adding and removing fields, and CMD+F for search

The search feature already exists in Strip for Windows.

How to Update

Version 1.1 is out now on the Mac App Store and our own Windows store for Strip. Customers who already have Strip installed on their Mac can get the update through the Mac App Store. Customers with Strip installed on their Windows PC can simply run the program and it should offer to install the latest update for you automatically.

Update 7/29:

It would appear that File –> Export in Strip for OS X 1.1.0 has a bit of a bug we missed—it never actually runs, and the sheet dialog is never dismissed as a result. This is a one-liner, so we’ve already tested a fix and submitted it to Apple for review, and we’ve asked for expedited review so we can get this bug-fix out quickly. Look for 1.1.1 to appear in the Mac App Store soon.

STRIP Data Import Guide

Permalink - Posted on 2011-07-27 00:00

This Document is Out-of-Date

For the latest information and help with Codebook's Import feature visit this page.

Information about Export is also available.

We had an even earlier document here on our blog about CSV importing, but it’s also out of date.


Exporting STRIP databases from Palm OS

If you are using STRIP on Palm OS and wish to export your data to CSV for safe-keeping or for moving to another system, we have a special utility just for you: Palm STRIP Export Utility. It works on Windows and OS X (including Lion) by opening up the backup of your STRIP data files stored by Palm Desktop. Make sure you Hotsync first!

The files produced by this utility should be ready for import into current versions of STRIP for the desktop. If you run into any issues importing these files, please get in touch.

Background Information

When importing and exporting data with STRIP, it is very helpful to have a general understanding of how STRIPstores and models your data. Here is a quick run down:

Entries are the basic records. Each has a name, an icon file, a Category, and a list of associated fields, shown right on an Entry record. For instance, you might create an Entry named “Bank Account”, and create a Field for the account number, another Field for the routing number, and perhaps a third Field for your PIN.

In summary: Categories –> Entries –> Fields

A Category may have any number of Entries, and an Entry may have any number of Fields.

Each Field has a Label (sometimes we call this the “Type”, but we’ve been making an effort to be more consistent with our terminology). The Label identifies the data stored in the Field (e.g. “Password”, “Website”, “Email”), and also defines behaviors in STRIP for your convenience. For example, when you tap on a Field labeled Website in STRIP for iOS, the application will offer to launch the URL in your web browser.

Labels have a Mode that define behaviors for the label. For instance, the “Website” Label in a default install of STRIP has the mode “url”. When you tap on a Field in STRIP that has this mode, Strip will attempt to launch the value in the Field as a URL on your system. You might consider creating a label SSH for launching your favorite SSH client with your credentials in the field, e.g. sftp://user:password@hostname:22. When you create a label, the default type is “field”, which has no special behaviors. Any registered protocol handler on your system should be a valid URL scheme.

Importing data

STRIP for Windows and STRIP for OS X allow you to import data via CSV format (learn what this is here). As might be expected, each line in the file (with the exception of the header row) represents an Entry in STRIP. However, for STRIP to successfully parse your file, there are a few requirements that must be met:

  • The file must be a valid CSV file. Properly escaped data is supported.
  • The file must be encoded with Unicode (UTF-8).
  • A header row identifying all columns must be present.
  • One column must be named “Entry”, and cannot be empty for each row of data.
  • One column must be named “Category”, and cannot be empty for each row of data.

Creating new Entries

By default, STRIP on the desktop will treat every line in your CSV file as a new Entry record and create it accordingly (even if you give multiple lines the same name in the Entry field), unless the EntryID column is detected, and contains data. More on that later.

N.B. Importing the same file multiple times will result in those records being created anew each time, something that trips up a lot of users. If you wish to reset your database, see our FAQ item

In your CSV file’s header row, ensure that there is a column named Entry, and a column named Category. When STRIP imports your CSV file and inspects the Category column for a record, it tries to find a matching Category with that name that already exists in your database. This lookup is case-sensitive. If a Category with that name does not exist, one is created for you.

All other columns are treated as Fields, so that each remaining column in the header row is matched up to a Label in your database. With a default install of STRIP, you’ll find that Labels like Password and Website already exist. If no existing Label is found that matches the name of your column, STRIP will create a new one for you.

If you need to create a record that has multiple fields with the same label, simply cram each values into the same column, and separate them with the pipe character, |. For example, say you have a record that needs three emails fields—in a column labeled ‘Email’, you could include three email addresses by separating them like so:


If for some reason the pipe character is not intended to be a separator but is valid data, you can escape it by putting a backslash in front of it, like so:


Updating existing Entries

This feature is only supported for import on STRIP for OS X, it is not available on Strip for Windows.

When importing data into STRIP for OS X, you can add a special column to your CSV file named “EntryID”. If this column is empty for a particular row, it is simply ignored and a new Entry will be created from the row. If this column contains the GUID of an existing Entry record in your Strip database, Strip looks up the Entry matching this ID and replaces its name, Category, and Fields using the data in the rest of the row.

All versions of STRIP display the GUID for each Entry record. If you wish to export your data to a CSV field to bulk update in a spreadsheet editor like Excel, use the Export feature. The file contains the EntryID column populated for you. You can then re-import the file after making your changes, and it will cause all the listed records to be updated.

An example CSV

Here’s an example CSV file that you might use as a template for importing data. As you can see on line 2, newlines (line-breaks) are allowed in field data as long as the field is properly escaped with double-quotes.

Credit Card,Financial,3759 876613 21001,,"exp:12/12
Insurance Policy,Financial,3759 876613 21001,,secret: name of your first pet? spot,secret,1-800-123-4567,4,,mscott,http://myinsurance.com
jordie laforge,trekkers,,,,,,,nextgeneration|deep space nine,,
kirk,trekkers,,,,,,,star trek,,
patrick stewart,trekkers,,,,,,,star trek|next\|generation|voyager,,
Shopping Website,Personal,,mscott@mailinator.com,,secret,,,,,http://paypal.com

Our import and CSV processing is based on the scanning technique and EBNF outlined by Matt Gallagher to fully support properly escaped CSV data.

If one were to extend that EBNF definition to take into account our use of | to separate multiple field values, we think it would look like this:

file = [header lineSeparator] record {lineSeparator record}
header = name {separator name}
record = field {separator field}
name = field
field = escaped | nonEscaped
escaped = doubleQuote {innerField | separator | lineSeparator | twoDoubleQuotes} doubleQuote
nonEscaped = innerField
doubleQuote = '"'
twoDoubleQuotes = '""'
separator = ','
lineSeparator = ('\r' | '\n') {'\r' | '\n'}
innerField = textData { innerFieldSeparator | textData }
innerFieldSeparator = '|'
textData = {characters up to the next double quote character, un-escaped innerFieldseparator, separator string, or lineSeparator}

What happens when there's an error?

STRIP imports your data in a transaction. If anything goes wrong during the data import, the entire transaction is rolled back and your STRIP database is restored to its original state, from before the import operation.

If you’re missing data on a row (say the Category or Entry column is blank), STRIP will endeavor to tell you the line number so you can easily fix it.

Encoding Errors | My file is not in Unicode (UTF-8)

Unicode was a brave effort to create a single character set that included every reasonable writing system on the planet and some make-believe ones like Klingon, too. ~Joel Spolsky

Not all text files are alike. These days, most text files, and most websites, are encoded in what’s called UTF-8. In fact, when you type text into a form in a modern web-browser, you are typing in UTF-8 (unless you’ve done something to change that behavior). For this reason, when STRIP reads your CSV file, it expects it be encoded in UTF-8.

You don’t need to know what that is or means, really. But if you have a file from another system, say a CSV file from another password manager product, and you run into an encoding error during import, there’s an easy fix: just change the encoding!

It’s a simpler operation than you might think, and most text editors support it: Simply open up your CSV file in your favorite text editor, go to the Save As dialog, and look for an “Encoding” drop down, and select Unicode (UTF-8). You can even do this in Excel.

Resetting STRIP | When imports go wrong

This data import thing can be tricky. If it didn’t work the way you wanted it to and you want to try again, you have options.

If you are using STRIP for Windows, or Strip for OS X, your best best is to simply delete all the data added in the interface, and adjust your CSV file for another shot at it. If you don’t, you’ll start to end up with duplicates. If you would instead rather delete the data file and reset the application, you can find it in the following locations:

Windows %APPDATA%\Zetetic LLC\Strip\strip.db
OS X /Users/username/Library/Containers/net.zetetic.Strip.mac/Data/Library/Application Support/Strip/default.strip

On OS X, the Library folder is hidden, but you can navigate to the parent folder in the Finder by selecting Go -> "Go to Folder..." (Shift+Cmd+G), and entering the following into the location field:

~/Library/Containers/net.zetetic.Strip.mac/Data/Library/Application Support/Strip

For Windows, simply paste that location into the location bar in Windows Explorer. After trahsing the database file, start Strip up again, and you’ll be asked to set a new password so it can create an empty database for you.


Strip for Windows, Strip for OS X Released

Permalink - Posted on 2011-07-13 00:00

This morning we are proud to announce the immediate availability of Strip for Windows, and Strip for OS X, our two newest data security apps. The programs provide a data editor on each platform for your Strip database, a capability that our loyal customers have been asking for since we first released Strip for iOS (née iPhoneOS) in 2008.

Strip for OS X is available exclusively from the Mac App Store, and for our Windows customers we set up our own purchasing portal at getstrip.com, where you can also get a good look at both programs, and Strip for iOS. They were all designed to look and feel like native apps, with a simple and familiar interface, and we think you’ll find them a pleasure to use.

Strip Sync for OS X and Windows will continue to be available for free at getstrip.com, although we do eventually plan to discontinue it as we move forward.

To help mark this release, we’re offering Strip for iOS at a temporarily discounted price—we’ve lowered it from $9.99 to $4.99 in the iTunes App Store.

This has been a long time coming, thanks for waiting! We look forward to your bug reports and feature requests. As always, support@zetetic.net.

Now then, it’s time to get hacking, we’ve got some big things planned for this Fall.

Problem with Strip for OS X Preview Release

Permalink - Posted on 2011-06-17 00:00

Earlier this week we soft-launched a preview release of Strip for OS X in the Mac App Store, and we’ve just pulled it from the store because we found a serious bug that could cause data loss for our customers. Only a handful of people noticed the app and bought a copy, if you’re one of those folks, here’s what you need to know:

Editing the name or icon of a category can cause the inadvertent loss of field data attached to entries on that category. We’ve got a fix, but we’ll have to test it thoroughly and then run it through Apple’s review team. In the meantime you can avoid the problem pretty easily, just don’t use Strip for OS X to edit your categories at the moment. Our apologies if anyone got bit—so far no one’s reported any issues to us. If you did manage to get a copy of Strip for OS X before we pulled it and you’ve found any bugs or issues, please get in touch.

Everyone else waiting on Strip for OS X and Windows to be available: please sit tight, we’re almost there and we’ll announce a proper release date soon.

Tempo Maintenance: June 7th, 9pm EDT

Permalink - Posted on 2011-06-06 00:00

Our time-tracking service Tempo will be undergoing some brief maintenance on Tuesday night at 9pm EDT. There may be a brief outage while the services are restarted.

Strip 1.5.4 Released

Permalink - Posted on 2011-06-03 00:00

We just released an update to Strip to fix a bit of a nuisance bug that had cropped up in the last version. We had enabled this setting for the application (UIRequiresPersistentWiFi) that activates the device’s WiFi connection on application launch, and keeps it open, rather than closing it after 30 minutes. We had done this in the hopes that it might solve some intermittent connection problems some folks had experienced trying to connect with Strip Sync on their local WiFi network. Anyway, there was a bit of a downside we didn’t see coming—every time you launched Strip and a WiFi connection was not available, you’d get this really jarring popup alert from the system, complaining about the absence of a WiFi connection. Very annoying in Airplane mode! It’s off now, sorry for the trouble.

What’s Up with Tempo

Permalink - Posted on 2011-06-02 00:00

Last week we experienced some problems with Tempo that were a bit of a nuisance for some of our customers. We needed to switch to a new charting library as the old one wasn’t holding up, but we ran into some issues with the first launch of those update. Our apologies that we didn’t catch them before making those updates live! We worked quickly to have it resolved by the next day, and things have been peachy since. If you happen to have a lot of people and/or projects in your Tempo account, you’ll notice the charts are quite a bit more useful now than they have been. If you run into any issues with the charts, please let us know.

There’s another update coming this Monday night to help out accounts that have a lot of projects and users, each page now has a search field allowing you to quickly pull up who or what you’re looking for. We’re currently working on more ideas for making Tempo more efficient and easy to use, and we’d love your feedback. Feel free to drop us a note in the comments here or get in touch via email.

Preparing Strip to Ship

Permalink - Posted on 2011-06-02 00:00

It’s been a little bit since we provided an update on Strip for Mac OS X and Windows and some folks have been asking, “what’s up?” We are submitting the 1.0 version of Strip to the Mac App Store, a universal binary, 32/64 bit. Keep your fingers crossed for approval and not rejection! This is one of the reasons why we don’t have a release date set yet, we need to get approval before we can realistically set one. It may turn out that changes will be required before we can publish it. Strip for Mac OS X requires you to be running Mac OS X 10.6 Snow Leopard or later (it is untested on Lion developer seeds).

We’re going all in with this Mac App Store for Strip, we won’t be distributing the app outside the Mac App Store. On the Windows side, we’re still working on our own purchasing system. There is no official Microsoft app store service for selling Windows software yet (would someone please light a fire under Uncle Fester’s derriere?), so we’ve had to do some work to set up our own purchasing and authorization system. Nothing too complex, but it’s work.

We’re also working on a major update to the product site for Strip, as the way it is currently set up isn’t quite inadequate for providing information on what are ostensibly two more products. Our merchant account provider for the Windows side isn’t cool with us launching the product without a supporting site, so we can’t just push it off until later.

All things considered, looks like we’re a couple of weeks out, as we’re juggling a couple of other things, too. Thanks for waiting on us!

By the way, if you have been thinking about buying Strip for iOS but have been leery of paying $9.99 just to try it out, we’re running a sale at the moment. For the time being, Strip for iOS is now available for $4.99 in the iTunes App Store.

Tempo Maintenance: May 25th, 9pm EDT

Permalink - Posted on 2011-05-24 00:00

Our time-tracking service Tempo will be undergoing some brief maintenance on Wednesday night at 9pm EDT. We don’t expect it to result in any noticeable downtime, although you might experience a blip. There’s a real gem in this update, we’ll begin using a new charting library that should greatly improve the display of charts on the reporting page. In particular, users who were reporting on a very high number of projects and/or users should find it quite a bit more useful.

Guardian Project Introduces SQLCipher for Android

Permalink - Posted on 2011-05-11 12:38

I believe it was a couple of years ago that I first met Nate Freitas at No↔Space co-working here in Brooklyn (née The Change You Want To See). He was working on ideas to help enable and protect communications amongst fellow activists, and I took an instant liking to him—this was a trouble maker! I mentioned our SQLCipher project to him, it was still pretty new in 2008, and he was immediately interested in being able to use it in Android applications. Since then he’s gone on to help found the Guardian Project, which aims to arm and protect mobile devices against unwanted surveillance and intrusion. Recently, he got back in touch with some big news:

After some major breakthroughs during last week’s development sprint, we’re extremely excited to announce SQLCipher for Android, Developer Preview r1.

SQLCipher is already on mobile devices on other platforms, but this is the first time it’s been made easily accessible for an Android developer, bringing compatibility with the native SQLite interfaces provided by Android. I’d say that probably makes it even easier to work with on Android than on iOS, as it closely integrates cursors with views (in Cocoa-land, you can’t just plug SQLCipher into Core Data, you have to role your own data management classes). Our teammate Erik was able to easily drop it into a sample Android project and get it working in no time.

In an environment where mobile data privacy is increasingly in the headlines, this project will make it easier than ever for mobile developers to properly secure their local application data, and in turn better protect the privacy of their users. The data stored by Android apps protected by this type of encryption will be less vulnerable to access by malicious apps, protected in case of device loss or theft, and highly resistant to mobile data forensics tools that are increasingly used to mass copy a mobile device during routine traffic stops.

Big ups to Hans-Christian Lee of Guardian who did brilliant work achieving this high level of integration with the Android platform. Please check out the Guardian Project and their apps, especially if you own an Android device. If you’re a hacker, give the developer preview a shot, and consider helping them hack on some seriously cool software.

SQLCipher for Android Developer Preview r1 Released

Permalink - Posted on 2011-05-11 00:00

I believe it was a couple of years ago that I first met Nate Freitas at No↔Space co-working here in Brooklyn (née The Change You Want To See). He was working on ideas to help enable and protect communications amongst fellow activists, and I took an instant liking to him—this was a trouble maker! I mentioned our SQLCipher project to him, it was still pretty new in 2008, and he was immediately interested in being able to use it in Android applications. Since then he’s gone on to help found the Guardian Project, which aims to arm and protect mobile devices against unwanted surveillance and intrusion. Recently, he got back in touch with some big news:

After some major breakthroughs during last week’s development sprint, we’re extremely excited to announce SQLCipher for Android, Developer Preview r1.

SQLCipher is already on mobile devices on other platforms, but this is the first time it’s been made easily accessible for an Android developer, bringing compatibility with the native SQLite interfaces provided by Android. I’d say that probably makes it even easier to work with on Android than on iOS, as it closely integrates cursors with views (in Cocoa-land, you can’t just plug SQLCipher into Core Data, you have to role your own data management classes). Our teammate Erik was able to easily drop it into a sample Android project and get it working in no time.

In an environment where mobile data privacy is increasingly in the headlines, this project will make it easier than ever for mobile developers to properly secure their local application data, and in turn better protect the privacy of their users. The data stored by Android apps protected by this type of encryption will be less vulnerable to access by malicious apps, protected in case of device loss or theft, and highly resistant to mobile data forensics tools that are increasingly used to mass copy a mobile device during routine traffic stops.

Big ups to Hans-Christian Lee of Guardian who did brilliant work achieving this high level of integration with the Android platform. Please check out the Guardian Project and their apps, especially if you own an Android device. If you’re a hacker, give the developer preview a shot, and consider helping them hack on some seriously cool software.

SQLCipher Performance and SQLCipherSpeed

Permalink - Posted on 2011-05-08 02:42

Recently, we had a query on the SQLCipher Users’ mailing list inquiring about the performance of a LIKE query, where the user was wondering if SQLCipher’s encryption engine was responsible for poor performance he was seeing in his code. “It depends,” is the cheapest and most accurate answer we could give without seeing his query and the EXPLAIN plan generated by SQLite (no index, for instance, could lead to a full table scan, thus requiring every page to be decrypted). What we do know is that performance of SQLCipher compared to SQLite is really pretty good, and certainly good enough for our needs as application developers.

If you’ve been wondering what kind of performance hit you can expect using SQLCipher as compared to vanilla-SQLite, we’ve published a new tool to help you get an idea. In the end,EXPLAIN and EXPLAIN QUERY PLAN cannot be replaced, but for a quick side-by-side reference to see that we’ve done a half-decent job, check out Stephen’s SQLCipherSpeed. It’s an iPhone OS project that rips through the various SQLite speed tests. I ran it on my crunky iPhone 3G and the results were about what I expected, and pretty interesting:

In this next one, note that there is no performance impact for 2500 selects on an index.

You’re highly encourage to check out the code yourself, and to fork it. It would be really cool if someone added an action button to the results screen to email the data off-device. More tests wouldn’t hurt either.

Maintenance - May 3rd, 2011 10pm EST

Permalink - Posted on 2011-04-27 00:00

We will be having maintenance for the various sites Zetetic runs includingTempo on May 3rd, 2011 at 10pm PST toperform system upgrades. The maintenance window should last no more than 1hour.

We will be adding a few new features to Tempo, and a new plan, so stay tuned!

Thank you for your patience.

Strip 1.5.2 Released

Permalink - Posted on 2011-04-18 00:00

Apple has informed us that Strip 1.5.2 has been approved, so we’re releasing it this morning, it should be available in the iTunes App Store by the time this post goes live. As previously communicated, this release removes the In-App upgrading service and reverts Strip to a paid-only application. All existing customers should upgrade, it’s free. Please let us know if you see any issues.

Opening CSV Export Files From Strip Sync

Permalink - Posted on 2011-04-13 00:00

Updated: 6/6/2012 This blog post is out of date, and the software referenced in it, Strip Sync, has been discontinued in favor of Strip for Windows and Strip for OS X. For more information on our data export format, please see this newer blog post.

Strip Sync is a free tool we distribute for customers of our password manager, Strip. It’s a kind of hold-over until we’ve got a proper desktop port of Strip that provides some basic but necessary capabilities, in particular the ability to bulk import your data (say, from another program or source), and to export your data (so you can print a hard copy to store in a safe, or so you can move off Strip someday).

The import and export files are CSV files. That is, plain-text files structured in a particular way, that can be opened in a spreadsheet programs like Excel. A good many people out there are familiar with spreadsheet programs, but Excel has some issues when it comes to opening a CSV file and displaying the data correctly:

  • UTF-8 is not supported when opening a CSV, ASCII is assumed, so international characters turn into garbage.
  • Leading zeros on numbers like PINs and postal codes are lopped off.

Our international customers, being quite fond of their umlauts, have written us a few times about the first problem, one that MSFT does not appear poised to fix this century. The second issue can be a real nuisance if you have a column like “Zip Code”. Excel always assumes such data is a Number (even if it’s wrapped in double-quotes), and if you format the column as Text after you’ve already opened it, the zeros have already been lopped off. Obviously, this isn’t a show-stopper, but it’s not appropriate for printing a hard copy of your secret keys for safe storage.

Looking for another work-around, I tried using Excel’s “Get External Data” wizard to import the text from a CSV, but it doesn’t respect line-breaks in quoted text fields, so even though you can mark your Zip Code column as text on the way in, the rest of your spreadsheet gets wildly munged by any line-breaks you might have in a note field.

This morning I fired up Open Office.org for the first time in a long while to see how it’s spreadsheet program Calc handles this, and it’s just the thing for our customers. Did I mention that it’s free? Here’s how it went down: I exported from Strip Sync, I right-clicked on the file, selected OpenOffice.org, tweaked some settings on the dialog panel that came up, and I was in business.


First, right-click (or control-click) on the export file, and instead of opening it with Excel, go with OpenOffice.org.

When the Text Import dialog pops up, take a look at the Separator Options: the only one you should check off is Comma. Make sure Text Delimiter is set to straight double-quote ().

Next take a close look at the Fields listing, and scroll over to any column that contains numeric data that you don’t want munged, e.g. PIN, or Zip Code, etc. Select the column header, and choose Text from the Column Type pop-up to ensure that leading zeros won’t be lopped off.

Then open it up, you’re all set! You get to keep those leading zeros.

From here you can manipulate and format the spreadsheet for printing however you like, or you can export it to a native Excel workbook format if you prefer to work in Excel. Excel does support UTF-8 characters, just not when opening a CSV file.

Message to Strip Customers Re: In-App Purchases

Permalink - Posted on 2011-04-07 00:00

Updated, below: Apr 18 10:00 AM

On March 1st, we released Strip 1.5.0, largely a pretty successful release with a low number of bugs, crashes, and some big improvements that were long over-due. However, in that same release, we started using Apple’s In-App Purchasing system, and it’s caused a lot of confusion and frustration for our current customers. That’s really the last thing we wanted to do, as our customers are particularly great, so this post is about what happened, what we’ve done so far to fix it, and what comes next.

The Issue At Hand

Thousands of people have already paid the full price for Strip, $9.99 USD. We wanted to make sure that when they upgraded, they weren’t charged again by the new In-App Purchasing system in Strip 1.5.0. To ensure this, the program looked for a previous install on first launch, and made sure not to ask the customer to pay for an upgrade, which worked—on the upgraded device.

It didn’t prevent users from being charged for the new version on new or replacement devices where the old version of Strip wasn’t already available on the device for detection by the new version. Thus, anyone upgrading to a new device, doing a restore, replacing a device, or buying a new device was faced with being charged a second time, because they no longer had the old version on the device in question and could only download the new version. To make it worse, there appears to be no way for us to remedy this with the App Store and the In-App Purchase system as provided by Apple.

To add to the confusion, purchases made once in the iTunes store don’t have to be made again on the same account, they are free, but the iTunes store still presents it as a purchase until you agree to pony up the cash. Only then does it inform you that you get the new download for free, so you’re always trying your luck. But the In-App Purchase for Strip is considered a different “Product” in the iTunes App Store, and buying the old version didn’t make the new version free on a new device. Many users in this situation confirmed the purchase when prompted, expecting it to be free thanks to their previous purchase experiences, and were charged anyway. To these folks, it looked like we’d performed a bait-and-switch (or just screwed up).

What We’ve Done So Far

Answering everyone’s email and getting to the bottom of the various problems wasn’t going to be enough, so we got to coding.

We published Strip 1.5.1 to the iTunes App Store on Monday, April 4th. It fixes a couple of bugs in 1.5.0 (thus the delay in getting it out), so we recommend you install it now. This version has a facility allowing us to remotely grant a user unlimited access to Strip on their device. When a customer gets in touch and it turns out she has or will be double-charged, we can put their UDID in a remote database and give her a couple of steps to perform in Strip to cause a remote HTTP request to check with a little web service we set up for authorizing instances of Strip.

Back to Paid Downloads

We will be publishing Strip 1.5.2 as soon as it’s approved by Apple (we’ve already submitted it for review to the App Store). It contains a one-line adjustment to disable the in-app upgrade completely, and we’re going back to what works: $9.99 to download, no more screwing around. Anybody who upgrades won’t be charged for the download.

We’re really grateful to our customers for being so patient with us while we worked through all the email and got back to everybody. If you are currently in a pickle yourself, get in touch, and we’ll pull you out of the brine. We’ll post a note here and to the mailing list once Strip 1.5.2 is available for download.

Update: Strip 1.5.2 is now available in the iTunes App Store, all customers are advised to install this update.

Demo-to-Paid with In-App Purchasing: STRIP’s Cautionary Tale

Permalink - Posted on 2011-04-07 00:00

Updated, below: Apr 8 9:22 AM

We first released our Password manager, Strip, to the iTunes App Store in May of 2009. It started life as a paid application priced at $9.99 USD to download. Unfortunately, this left early users with no way to test or evaluate the software before buying. Or course, the app was quite new to the store, didn’t have very many reviews, and users were reluctant to pay sight-unseen.

Like many application developers we decided to make a “Strip Lite” version that would provide an easy way to evaluate the software. This was basically the same application with a couple of build settings changed to introduce reasonable demo limits (10 entries, no WiFi Sync feature). Strip Lite allowed a potential customer to see if the software was indeed right for her before purchasing. At the time there was no other way to provide trial-ware, where the user has a certain period of time to review an app before paying for it.

Even so, there were some clear disadvantages to the Lite-app approach.

  • All of our stats, ratings, and reviews were walled off into two separate gardens in iTunes Connect, one for each app.
  • We had to develop a custom upgrade system so people could bring their data along to the paid version. Even though this worked, the process was a bit confusing and increased our support load.
  • We would often hear from people who were confused about the versions, upgrades, differences and prices between the two application versions—another increase in support cost.

Strip Lite really did help grow the visibility and popularity of Strip by a wide margin, but it wasn’t ideal.

Demo-to-Paid using In-App Purchasing / StoreKit

When Apple announced In-App Purchasing for free apps it was widely touted as the perfect way to provide demo-to-paid upgrades. Indeed, it seemed like the ideal solution to our problems: we could make Strip free to download (with the Lite limits in place), allow users to purchase the full version inside the application, and get rid of Strip Lite and it’s confusing upgrade process.

Before taking the plunge on our most popular applicatiom, we tried it out on Codebook first, a paid-only app that had a smaller user base. It led to a big increase in overall downloads and sales, and amazingly we received no complaints. This seemed to be the best approach for us and our customers, so we got to work on building it into Strip for release in version 1.5.0.

On March 1st, 2011 we released the new version of Strip to the app store. At first there were no problems. On the contrarary, the jump from paid to free resulted in a huge spike in downloads, placement in the top-ranking productivity tools lists, and even an uptick in conversions. Unfortunately, this didn’t last very long, and the troubles started shortly after.

Is It Really Free?

Free apps with In App Purchases can be confusing on two levels.

On the one hand, even though we had placed a prominent note on the app description saying that Strip was only free to use for up to 10 entries without paying for the upgrade, many people don’t carefully read the descriptions. This resulted in some customers feeling that the In-App Purchase was a “bait-and-switch” tactic, even though this was never our intent.

On the other hand, I can’t tell you how many emails we received that asked, “is it really free to install on another device?” With a paid application, people are accustomed to selecting apps they already own in iTunes for installation on a new device with no charge, getting all the functionality immediately. However, when customers buy an In-App Purchase for your app on one device, it does not automatically transfer to a new device. Even though they are entitled to that purchase for free the user is asked to confirm if she would like to buy “1 Strip Unlimited” (love that qty of 1) for $9.99, with no hint of “free for you”. Only after the customer agrees to pony up the additional $9.99 does iTunes inform her that it will be a free download and that she won’t be charged1.

Which version is this?

“Where’s the full version of Strip, I only see the Lite version available for the new upgrade!?”

When thousands of our existing customers saw that the only available upgrade for the new versions was free, they thought we’d eliminated Strip in favor of Strip Lite, along with their unlimited functions. This resulted in a big increase in support mail. This is a confusing thing to have to explain. We tried to head this off at the pass, by making this clear in our release announcements, but it didn’t help.

Don’t get us wrong, we love the opportunity to provide great support to our customers (if done right, these interactions are invaluable), but we really don’t like confusing them and wasting their time. We’d rather save that karma for when there are bugs—there will be bugs and you don’t want to use up good will!

But the next problem was a real Charlie-Foxtrot.


For users who’d already paid for the full version of Strip, we needed to make sure they weren’t charged again via In-App Purchase when they upgraded. Thus, when Strip 1.5.0 launched for the first time on your device, it would do some clever stuff to check for a previous install and grant you the unlimited upgrade by writing a receipt file onto the device in the application’s documents directory.

Unfortunately, that only works for one device. When a user gets a new device, the old version of Strip isn’t already on there, and only the new version where you have to pay in-app is available in the store. Since there is no old version on there already, it asks the user to pay again. This doesn’t just affect users who go and buy an iPad to go along with their iPhone, it affects people who need to get their devices replaced, or who upgrade and find iTunes just forgot to copy their apps and data over. Consider this lovely email from one irate customer who wiped his phone and couldn’t restore from backup:

"what the fuck iz wrong with you guys?? i bought the app 4months back. and now the app is askin me to pay another 10bucks for sum shitty upgrade. jus fix this issue asap."

This was an aberrational response, most of our customers are very good spellers (and rather polite), but it was a harbinger of serious trouble. At first, we had no way to help these folks get Strip without being charged a second time. We also had no way to tell the StoreKit API that the user should be granted the purchase for free when we did the grand-fathering check described above.

This problem was made worse by the confusion around the in app purchase screens. Now, when our customers downloaded the new version and then contacted us to ask, “Will I be charged again?” we had to go through a complicated process to determine what version the user previously had, when he or she made the purchase, what state the device was in (is this a restore?) and whether or not he or she would be charged before we could say, “go ahead, it’s gonna be alright.” Many customers just went ahead with the purchase, thinking they wouldn’t be charged per usual iTunes store policies (expecting the little “don’t worry it’s free” modal dialog to come up) only to find out otherwise.

The kicker here is that there’s no way for us to offer refunds in the iTunes Store, still, after all this time. Not cool at all, and not how we like to do business. The only thing we could do was to offer a $10 gift card to cover the re-buy, but since iTunes had already taken their cut, we covered 30% of the refund straight out of our own pocket. Even worse, we could only do that for our customers in the US.

A Temporary Hack

We published Strip 1.5.1 to the iTunes App Store on Monday, April 4th. It fixes a couple of bugs in 1.5.0 (thus the delay in getting it out), so we recommend everyone upgrade now. This version has a facility allowing us to remotely grant a user unlimited access to Strip on their device. If a customer gets in touch and it turns out she has or will be double-charged, we can put their UDID in a remote database and give her a couple of steps to perform in Strip to check with an authorization web service.

At least this allows us to help our customers out in the short term, but it still requires a lengthy support process full of confusion and often beginning with frustration for the user, so we’re not stopping here.

Back to Paid Downloads

We will be publishing Strip 1.5.2, which disables in-app purchasing, as soon as it’s approved by Apple. We’re going back to doing what works: $9.99 to download, no more screwing around. Anybody who upgrades won’t be charged for the upgrade a second time.

We won’t be using the In-App Purchasing API for this purpose again. In-app purchases clearly work well for icon packs, new levels in video games, and paid content downloads. They might even be appropriate for demo-to-paid apps that start out free, if you can live with forcing your users to “re-buy” every time the install on a new device (where they must confirm a new purchase before iTunes offers it for free). But for an app like ours there is just no easy and clean way to take care of the problems described here without incurring significant support overheard and/or creating a complex StoreKit companion to track purchases and authorizations.

We’re really grateful to our customers for being so patient with us while we worked through all the email and got back to everybody. If you are currently in a pickle yourself, get in touch, and we’ll pull you out of the brine. We’ll post a note here and to the mailing list once Strip 1.5.2 is available for download.

[1] Suggestion for Apple: The StoreKit makes no effort to check before hand if the user is already entitled to the purchase, but it could do so quite easily, rather than requiring us developers to set up our own system. It could simply be part of displaying the price: just make it zero if the user already bought the requested product ID. Better yet, create an API method we can call to check. Don’t make us set up a companion system to register our customers, that’s the whole point of the iTunes App Store.

Update: As mentioned by Mark J below in the comments, the StoreKit API gives the developer a way to restore a user’s previous in-app purchases without forcing anyone to try their luck, with the SKPaymentQueue method - (void)restoreCompletedTransactions.

Tempo Maintenance, Apr 7 2011 10pm EST

Permalink - Posted on 2011-04-05 00:00

We will be having maintenance for the various sites Zetetic runs includingTempo on April 7 to perform system upgrades.The maintenance window should last no more than 1 hour.

Thank you for your patience.

Cartographer: Site Maps with No Strings Attached

Permalink - Posted on 2011-03-29 00:00

Site maps are one of the few things you can do to a website that don’t veertowards the “snake oil” side of SEO. Generally with these things, having directsupport from the Search Engine vendors is a straight arrow. In the process ofmaking our sites more accessible to customers, we noticed a void of thesewonderful little files.

The sitemap specification is so simpleit hurts. You have a list of URLs. They have a few properties. This isn’tparticularly surprising; Google, the inventor of the specification, is prettyskilled at applying KISS philosophy when it comes to web technology.

The number of sitemap tools onrubygems.org didn’tsurprise me either. After all, this is a very useful tool for people involvedin the web, and like it or not, a great deal of the energy thrown at ruby isfor web development.

That said, the ruby community loves its static site generators:theyreallylikethem.Needless to say, I was genuinely surprised when I came to the realization thatnot a single one of these sitemap systems supported them.

Enter Cartographer, which is astandalone system for generating sitemaps. In particular, it has three mainfunctions:

  • Import an existing sitemap into an internal structure to represent it
  • Find, with optional filtering, all the items in a given path and add them to to the sitemap.
  • Generate the sitemap XML.

It brings along with it a few bonuses:

  • Not attached to rails, rack, or anything other than Nokogiri, HAML, and Ruby.
  • Easy to manipulate, no need to feel locked into a framework.
  • Designed for static trees.

And a few disadvantages:

  • Does not know about your routing, rewrite rules, or any other URL manipulation.
  • Is not an “end to end”, pluggable tool. You need to invest some effort.

Cartographer makes heavy use of the ‘Find’ library that comes with Ruby, and assuch leaks its functionality via the add_tree call. For example,we use staticmatic and do the sitemap generation in an at_exit hook (so it’sthe last thing that runs, without getting into the nitty-gritty of rubyinternals.)

This Find leak is critical to the functionality of Cartographer and yields whatI believe to be very effective and succinct methods for dynamically adjustingwhat will be automatically included in your sitemap. For example, from theSTRIP Password Manager’s staticmatic generator:

You can see in the add_tree block we case over thepath with several regexes applied. Returning nil will callFind.prune which says, “Please do not look down this treefurther”. Cartographer will also refuse to include that tree into the sitemap.

So, here, we actually prune all non-html assets, and a couple of files whichunfortunately make it into our repos from time to time. We don’t want to indexour Search Engine instructions either. Also, for index.html files we prefer theparent path with a trailing slash, e.g., /demo/index.html werewrite to /demo/. If none of these criteria match, we simplyreturn what we got and it is added to the URL list verbatim.

The result looks something like this (trimmed for brevity):

Documentation for Cartographer ishere, and the code is ongithub. Please feel free to fork andadd suggestions, patches, or issues!

Site Maintenance: Mar 7 2011 10pm EST

Permalink - Posted on 2011-03-02 00:00

We will be having maintenance for the various sites Zetetic runs includingTempo on March 7 to perform system upgrades.The maintenance window should last no more than 1 hour.

Thank you for your patience.

Strip 1.5.0 Now Available from iTunes Store

Permalink - Posted on 2011-03-01 00:00

Strip 1.5.0 has been released and is available now from the iTunes Store as a free update. We think this is the best release of STRIP yet. It contains myriad small fixes to enhance the user experience and correct application behavior and a few more impressive updates:

  • Support for staying unlocked on multi-tasking devices
  • Support for landscape-orientation for easier data entry
  • Updated graphics for Retina displays
  • Updated SQLCipher to version 1.1.8

The various other updates:

  • In-app upgrade to unlimited (no more STRIP Lite)
  • Current customers who bought STRIP before 1.5 are grandfathered
  • Field behavior changes fixed to take effect immediately
  • Database info screen now includes Ditto replica info
  • Password Generator sets controls to last-use settings
  • Last-use settings are stored encrypted in SQLCipher
  • Fixed display of lower distenders in fields values
  • Field labels are no longer lower-cased on display
  • Fixed default icon display for newly imported entries and categories

As you can see from the second listing above, we’ve made a change to how we allow people to try STRIP for free before making a purchase. Nothing has really changed for our existing customers, who are grandfathered to ensure the app is not limited in anyway.

Strip Sync update required

This version of Strip, 1.5.0, is incompatible with earlier releases of Strip Sync. As of today, an update is available for both Strip Sync for Mac OS X and Strip Sync for Windows. If you already have Strip Sync installed, simply fire up the program and it should offer to update and relaunch. If not, or if you’d like to install the software directly yourself, you can download the updated version below:

As always, if you have any questions or run into any issues, please get in touch.

PostgreSQL on EBS: Moving to AWS Part 3

Permalink - Posted on 2011-02-01 00:00

Databases and EBS: What you need to know.

Just a few things that you should know about EBS.

EBS is slow

All your data travels over a network before it reaches a disk, or data from thedisk reaches your instance. This means that writes and reads can be slow orintermittent at times.

Further compounding the issue, your SAN is shared with hundreds (thousands?) ofother users! While these machines are some high powered “big iron”, it stillmeans you’re going to have I/O contention and a number of other issues.

Even further, your disk access is metered! This means all those operations aretickling tiny little counters. This isn’t a lot in reality, but it all adds up!

On the bright side, EC2 instances have a lot of RAM. Let’s play to the field!

PostgreSQL Configuration and Use

This might sound a little preachy and redundant, but here goes:


No database should go without being properly indexed, from head to toe, witheverything you query upon and the vast majority of the combinations you use inyour queries. Yes, write performance will suffer, but we’re about to renderthat much less troublesome by sending the writes to RAM as frequently aspossible.

Less time spent searching tables = less disk access = greater performance.

Build queries to be sent over the network

If you’re doing anything with an ORM, you’re probably guilty of this at leastonce or twice: building your queries to be sent to the app to be handled later.You know those kooky DBA types that say “do everything in the database”, well,they’re on to something here.

Well, ‘lo and behold you do something like this:

When something like this:

Would have not only likely saved you a lot of computational cycles, but quite abit of network traffic is reduced, and continues to pay off as your tables growin size. This happens a lot in the rails community, unfortunately.

(Yes, I’m aware this example is a bit contrived. You could easily prepare thatquery with find() or ARel’s composition methods.)

The skinny: the less you do in the database the more you’re spending on networkresources and time to deliver your result. The database is probably working Ntimes as hard, too, to deliver your responses.

Even if it takes the “pretty” out of your code, do it in the database.

Shared Buffer Cache

Shared Buffer Cache is the meat and potatoes of PostgreSQL tuning. Increasingthis value will greatly decrease the frequency at which your data is flushed todisk. An EC2 Large Instance will happily accomodate a 4GB PostgreSQLinstallation which would be more than enough for lots of reasonably traffickedapplications.

Why is this important? The less time it spends writing to disk, or the lessfrequently it writes to disk, can mean a lot for your application’sperformance!

Database backups on the cloud

We have a few options for backing things up. As usual with redundancy, the bestoption is to… be redundant. (See what I did there?) Using a strategy thatallows us the best of both worlds.

EBS snapshots

You’ve already seen our snapshot script:

Which iterates over your volumes and maintains the last 5 backups.Here is a detailed account of the script’s function.

We use the script, amongst other things, to back up our database partitions,which are composed of the database master, the transaction log, and the backupsof the WAL.

WAL archiving

Write Ahead Logging and Continuous Archiving for Point in Time Recoveryis a pretty sticky topic and you would do yourself well to read that whole document.

Instead of repeating it here verbatim, I’ll tell you what our backup script does:

This script manages the archiving of three tarballs:

  • base.tar.bz2, the base database system
  • full-wal.tar.bz2, the whole WAL for the last day.
  • pit-wal.tar.bz2, the point in time portion of the WAL.

The major difference between ‘full-wal’ and ‘pit-wal’ is that at the time thefirst backup is taken (the night of the backup), the data may not be fullycommitted to disk. Therefore, we write as much as we can to the ‘pit-wal’ filefor the purposes of crashes that day. The ‘full-wal’, as you might suspect, isthe fully written representation and is actually written out a day after thebackup occurred.

In a recovery scenario, both of these tarballs would be merged with theexisting WAL files in order of ‘pit-wal’, then ‘full-wal’ would be unpacked.

The WAL directory itself has some data hidden in the filenames, let’s checkthat out:

2011-02-01 09:05 000000030000000300000026
2011-02-01 09:05 000000030000000300000026.000076B8.backup
2011-02-01 10:12 000000030000000300000027
2011-02-01 11:30 000000030000000300000028
2011-02-01 12:57 000000030000000300000029
2011-02-01 14:10 00000003000000030000002A
2011-02-01 14:58 00000003000000030000002B
2011-02-01 15:30 00000003000000030000002C

The filenames themselves hold two important pieces of information:

  • The first 8 characters of the filename are the recovery version. As we’re good little children and test our backups, this is at version 3.
  • The last 8 characters of the filename are ordered, you can see this by comparing the times and the filenames themselves.
  • If there is an extension, that is a demarcation point where pg_start_backup()/pg_stop_backup() was invoked. This is what we use to create the ‘full-wal’ tarball.

As for the backup structure? Well, here’s a sneak peek:

2011-01-28 09:05 2011-01-27.09:00:01/
2011-01-29 09:05 2011-01-28.09:00:01/
2011-01-30 09:05 2011-01-29.09:00:01/
2011-01-31 09:05 2011-01-30.09:00:01/
2011-02-01 09:05 2011-01-31.09:00:01/
2011-02-01 09:07 2011-02-01.09:00:01/

The $today and $yesterday calls just generate these filenames. At the endof the script, we see this idiom:

cd $backup_dir
ls -1d * | sort -rn | tail -n +15 | xargs rm -vr

Which is a way of saying, “show us the last 15 dirs and delete the rest”. Thiskeeps our filesystem size low and we rsync these files nightly.

The sed usage here is a little tricky but not anything incomprehensible. Basically,

breakpoint=`ls *.backup | sort -r | head -n1 | sed -e 's/\..*$//'

Finds the latest backup file. Now,

arline=`ls | sort | sed -ne "/^$breakpoint$/ =" `
archive=`ls | sort | head -n $arline`

Uses that as a demarcation point to determine the archive files. Those filesare archived and removed and result in full-wal. The rest leftover result inpit-wal.

Happy Hacking!

Let’s talk about EBS, baby: Moving to AWS Part 2

Permalink - Posted on 2011-01-31 00:00

EBS — or the Amazon Elastic Block Store — is the way you get persistence on most EC2 instances. Let's talk about what EBS is good for, what it's not good for, and why it matters to the EC2 consumer.

About EBS

EBS is basically a volume system with dynamic attachment. You go into the EC2 system, select an EBS "volume", and attach it to an instance. There are additional ways, such as EBS rooting, to use EBS volumes.

EBS is implemented at Amazon via a Storage Area Network (SAN) that is dynamically attached to your instances. Each EBS "volume" you attach is a portion of the disks that make up the SAN; a portion that can and will be allocated sparsely.

This has performance drawbacks. EBS can be very slow and unresponsive at points (there are no availability guarantees on EC2 for any of its products), so it's important that your EBS-related task can handle intermittent outages even if very small. For the most part, things that need read performance or will block on writes will suffer. There are ways you can mitigate it, such as "striping" volumes, but in practice this is very troublesome.

What's the difference between EBS root and the instance store?

EBS rooting is where the device that your root-level filesystem lives on is an EBS volume. This is different because instance stores are ethereal, and will disappear after the machine is stopped. Therefore, it is wise to use EBS rooted machines for machines you want to last.

What's the difference between an EBS volume and a traditional physical disk?

In particular, the major (other than the provisioning, of course) issue is that EBS volumes will not necessarily be available at boot time, so you must mitigate that for any non-root volumes.

How does Zetetic use EBS?

We use it for two roles:

  • Database Servers (with a high ram setting)
  • Support machines (monitoring, repositories, wiki, ticket tracker, etc)

We'll talk about the database management in the next article; our support machines are very simple in execution but require a lot of configuration, so automating them is a bit of a bear.

Why not run everything as EBS root?

You could do that, but EBS is billed on a per-transaction (writes and reads) basis, and then there is the performance issue. EBS-rooted volumes additionally have a reboot penalty which (at the time of writing) is a dollar. That can get expensive quick! It's probably best to stick to EBS rooting where configuration management is hard and leave the rest to instance stores.

Hopefully this article has been a decent overview of EBS; next time we will cover PostgreSQL management in the cloud!

Introducing Codebook 1.5.1

Permalink - Posted on 2011-01-27 00:00

On January 22 we released Codebook 1.5.1 to the iTunes App Store. This is the best version of Codebook yet, with many bug fixes, interface enhancements, and a really cool new feature: Sync with Dropbox. Read on to find out what’s new in our secure notebook app.

Sync with Dropbox

Codebook 1.5 has a new Sync tab that provides a means for you to upload and sync your data with an encrypted replica stored in your Dropbox account. Simply enter your Dropbox account information and start a sync, and when it’s all done you’ll see that you’ve got a new folder named “Codebook” in your Dropbox account, containing your encrypted database file.

This resolves a number of long-standing feature requests from our users. No longer do you need to rely on the unreliable iTunes to keep a backup of your most important data. Not only that, but with an encrypted copy up on Dropbox, you have an incredibly easy means of restoring your data if it is somehow lost. Sync often!

But we didn’t just stop there. Thanks to our Ditto replication technology, the Sync feature allows you to share your data across multiple devices. If you use Codebook on your iPhone and an iPad, you can use the sync feature to replicate your data across both of them (or any other iOS devices you’re rocking). Just run Sync and Codebook will take care of the rest.

Note: The Sync feature is only available to users who purchase the Unlimited Upgrade inside Codebook. More detailed information about how Sync works is available on our Codebook FAQ.

Edit Screen Updated

This update to Codebook is all about details. If you remember what the edit screen looked like in Codebook 1.4 or 1.3, you’ll find this screen has seen some serious improvements, mostly to the effect of putting things where they ought to be and making it look and feel better. For instance, the background no longer squishes and resizes when the keyboard is revealed and hidden!

The new toolbar at the bottom of the screen provides a new trash-icon button to delete the current note—that’s an FAQ item we can remove. Power users figured out the swipe-to-delete thing on the list view screen, but it was still a nuisance to have to pop back to the previous screen to delete the current note — you’d have to then locate the note, which was be a real nuisance. And if you weren’t hip to swipe-to-delete, it just looked like you couldn’t delete a note in Codebook.

Also on the toolbar is a relocated forward-icon for that reveals a modal menu of Sharing Options (currently just the ability to e-mail the document somewhere, unencrypted, mind you). This just seems like a much better way of making the e-mail feature available without the user accidentally kicking it off (thereby dumping plain-text data into the Mail app and potentially mailing it by mistake). More handy little buttons will probably appear in this toolbar going forward.

And then there’s the add-icon, the big + button on the right side of the navigation bar. If you need to tap in a few notes, one after the next, now you can! It was getting really annoying to have to go back to the main list view just to create a new note.

Finally, we’ve started using the tear-off-page style animation to transition the view when you hit Add or Delete on the edit screen. Being able to seamlessly transition the views like this (whether you use animation or not) is what allows us to provide these two capabilities on the edit screen without forcing the user to go back to the list view first.

Graphics for Retina Display

We finally got all the icons and background graphics updated to support the hi-res display of the iPhone 4, and it’s such a huge improvement to the app. You’ve got to see it to understand the value here, but I’ll say that if you regularly use Codebook on an iPhone 4 it will be literally relieving to your eyes to interact with this new version. To be quite honest, does anyone like using apps on the iPhone 4 that don’t support Retina Display? I sure don’t.

Rotation and Landscape Orientation

If you prefer to work in landscape mode, you’re really going to love this release of Codebook. All screens (except for the login and dropbox link screens) support landscape orientation. Codebook 1.4.7 supported landscape-orientation for note editing, but it needed some love (like stretching the text view to the expanded view to make more of the current note visible while editing!) Codebook 1.5 brings a ton of tweaks to the rotation behavior, and makes landscape orientation available on the Sync and Settings screens, too.


Version 1.5.0 had a mean little bug on the edit screen—if you switched to another application while editing, certain things happened to inaccurately re-draw the screen upon returning to Codebook that garbled the text and moved it off screen. No data was actually harmed, but it freaked people out and was obviously insanely annoying. We actually pulled the app from iTunes before more than a handful of people could install that one.

Codebook 1.4.7 suffered from a bug where the list view of notes would suddenly disappear, due to a bug in the code. The data was still there, but the app had to be restarted to work around the problem. The 1.5 series of Codebook fixes this issue.

gem-testers: Great QA Justice in a Gem

Permalink - Posted on 2011-01-19 00:00

If you're my age (I had a MC Hammer cassette tape in elementary school) and a rubyist, chances are you've done a dash of Perl in your time. Whatever the reason may be, we are now rubyists, and writing our web applications, database interaction and daemons in Ruby.

When it comes to Perl vs. Ruby, two things immediately stand out heavily weighted as superior in Perl's court:

  • Documentation
  • Quality Assurance

Today, I'm focusing on the latter. In fact, it has been my full-time focus for the last two months outside of work, and a healthy chunk of the last two years.

"Anything your QA infrastructure can do, mine can do better" - anonymous, possibly fictional Perl programmer

And they're right. Compared to the swath of tools available to the eager Perl tester, Ruby's testing facilities look weak in comparison. Granted, compared to the programming spectrum as a whole, Ruby's not so bad. Perl, however, has an amazingly great testing credo in which several things happen even if you don't care:

  1. When you install a module from CPAN, it is tested before it can be installed.
  2. Day in day out, results from testing are reported to a site where they can be reviewed by library authors. This is SERIOUS BUSINESS.
  3. Good Perl programmers simply do not use libraries that aren't tested or documented. This is fact.

Note that I am not saying use Perl; here. Perl is a fine system, but we're attracted to Ruby for a reason, right? Instead, let's make Ruby better. We need testing on a variety of environments to fix bugs in our gems. Gem authors frequently do not have the resources that, say, the whole freakin' internet has.

Gem Testers and it's companion gem, rubygems-test are an attempt to provide these things. The gem testers system is pretty crude at this point, but should be a good start. Here's what it does when you run gem test rubygems-test:

  • Runs 'rake test' for the provided gem.
  • Captures the output of the system and records any exit status.
  • Reports this to the Gem Testers Website
  • Returns a happy little URL you can give to people when you write that angry trouble ticket about their gem.

Additionally, gem users are unfortunately more and more frequently finding themselves confronted with gems that are inadequately suited to their needs. This isn't necessarily because they are bad; maybe they haven't been maintained, or simply don't work on their preferred platform. Gem Testers is not just for gem authors; users can quickly work with the results to adequately vet the stability of a particular gem (or even a particular version). Evaluating libraries can be one of the more important things you do when starting a new application or library feature.

Josiah Kiehl and I have made a herculean effort with the help of people on the rubygems and various ruby platform teams to support a wide range of ruby platforms. All of these rubies run rubygems-test on Windows, Mac, and other POSIX systems:

  • MRI 1.8
  • MRI 1.9
  • Rubinius 1.2
  • JRuby 1.5 and 1.6beta
  • Windows versions include both Luis Lavena's RubyInstaller and the 'garbagecollect' Visual C builds.
You're out of excuses

rubygems-test is easy to integrate, most likely supports your preferred platform, and gives you testing that you simply don't have time or resources to produce on your own. Heck, even gem building systems like Hoe and Ore are adding support for it. Why not take the plunge? I dare you to!

Want to contribute?

The entire project is open source, down to the Capfile. You can help us! rubygems-test and gem-testers have all the fixings for you to help!

Doing it right: Moving to AWS Part 1

Permalink - Posted on 2011-01-18 00:00

Greetings folks, I'm Erik Hollensbe, recent Zetetic recruit. One of my first tasks here has been to move Tempo and this site, and our marketing sites for products like Strip and Connect to AWS, specifically EC2.

Why EC2?

I'm going to presume you've heard the standard-fare cloud rhetoric; so I'm going to just skip that part and go straight into the meat:

EC2 has a remarkable commandline-driven API:

Anything you can do in the web interface (and then some) is represented in unix philsophy — "do one thing and do it well" — java or ruby-based utilities. For example we have a script that takes nightly snapshots of our in-use EBS volumes and then prunes everything but the last 5 of these:

You can see here we are able (for the most part) to cleanly parse and manage each individual step of the process from start to finish, having an easily accessible point anywhere in the script to break it, and check whether the moving parts are functioning in the way we suspect.

For example, ec2-describe-volumes yields output like this:

VOLUME vol-5ab82932 15 snap-ad6f2234 us-east-1d in-use 2010-12-14T17:07:21+0000
ATTACHMENT vol-5ab82932 i-f0370bed /dev/sda1 attached 2010-12-14T17:07:24+0000
TAG volume vol-5ab82932 Name somebox-root

(That's one line)

End-over-end enumerating all your volumes, which can be pulled apart with classic unix dissection utilities like sort, awk, and perl. You can see with the information being supplied to the script above, how the hard work is done for us, leaving us to extract the pieces we care about, culminating in a relatively boilerplate-free experience.

There's 101 tools at a quick count of my ec2-api-tools directory — filtering duplicates for Windows and Legacy systems — and that's not even counting the ec2-ami-tools which are used to build custom systems (more on that later).

EC2 was built by network engineers for network engineers

One of the most useful features of EC2 is its networking stack. EC2 machines are behind a NAT (10/8 spanning all DCs) and assigned external IPs dynamically. One can change the external routable IPs using the "Elastic IP" system. These IP addresses can be attached and detached from systems about as liberally as you attach a thumb drive to machines, giving you maximum flexibility. No more waiting for pesky TTLs to expire or having to change 20 /etc/hosts files or scripts.

EC2 also supports "security groups", which are basically network roles. Roles can be used in firewall rules to create logical partitioning between machines in your network.

For example, you can have a set of machines in the 'webserver' class and another set of machines in the 'database' class that only accept connections on port 5432 (the standard postgresql port) from 'webservers'. This means no matter how many 'webservers' you create, or how many times they change IP addresses, your firewall rules still keep out the hax0rs and let webservers talk to your databases. These rules are port/protocol dependent and the "security group" takes the place of CIDR notation for in/out.

Get as detailed or simple as you want

AMIs, EBS and instance stores, what you do with EC2 is up to you. If you want a classic (oy, calling it classic is a bit much, but hey) VPS, you can run with one of the pre-rolled EBS rooted instances. If you want a shiny new cloud system, you can run with instance stores which, when terminated, disappear forever. You can even roll your own kernels and initrd's to customize your system with the AMI toolkit. We will dive deeper into these in upcoming articles.

"Ok Erik, my brain's getting tired. What can I expect for next time?"

This is going to be a minimum 4-part series (including this one) which will at least cover:

  1. EBS management both on and off the root device — here
  2. PostgreSQL on the cloud - management and backup tips — here
  3. Deploying Web Applications for volatile systems

Thanks for reading! I will be happy to field any comments below. -Erik

Tempo Maintenance 1/17/2011 9pm EST

Permalink - Posted on 2011-01-14 00:00


Tempo will be recieving system updates and a new deployment on this upcoming Monday, January 17 at 9pm EST. The entire process should last less than an hour.

If you have any questions or concerns, please get in touch with us.

System Maintenance, Dec 19th, 9PM EST

Permalink - Posted on 2010-12-13 00:00

This Sunday the 19th of December, we’ll be conducting a significant bit of infrastructure and system maintenance to support our various websites and our time-tracking service Tempo, which will accordingly affect your ability to access these sites, temporarily.

We’ve scheduled the downtime for 9pm to 12am EST in order to minimize impact on the business day. We’re also doing this mid-month to avoid disrupting our customers’ end-of-month (and end-of-year) billing and reporting.

If you have any questions or concerns, please get in touch with us.

Updating Page Sentry for APEX 4.0 Upgrade

Permalink - Posted on 2010-12-10 00:00

We’ve been using Oracle’s Application Express 3.0.x on a client site for about three years now, possibly more. Last week we did the upgrade to Application Express 4.0.2 on a development host, and for the most part it was seamless and our apps worked great. In addition, the new Application Express engine is snappier, easier to work with, and really quite fantastic.

However, we did run into some small troubles that became quite vexing. We use APEX in a single-sign-on environment (Oracle Access Manager is involved), so instead of using APEX’s built-in authentication schemes, we use a custom one we call oamPageSentry, based off of the many examples out there on doing just that (there’s even a kind of unofficial white-paper from Joel Kallman, one of Oracle’s APEX hackers, on creating a “page sentry” authentication scheme in PL/SQL for OAM over here on his blog).

For the sake of brevity, if you’d like to peak at our original page sentry function at the time of the upgrade, in it’s resplendent, mod_plsql glory, check out this gist.

Anyway, the strange behavior we noticed had to do with links used to forward users already authenticated in our SSO environment into a specification application and page in APEX, setting certain required page items in the reports using values passed in through the APEX URL request format. After the upgrade, we saw was that the user was getting a redirect that squashed the Page Item parameters by sending the user to a new session every time, without the original query string preserved.

This seems due not to anything wrong with the original page sentry code (ours or Oracle’s, which were identical in most aspects), but with some slight changes in behavior in APEX to avoid session manipulation, although it was quite tricky to narrow it down.

The primary problem seems to be that when the user visits a session-id-zero link, APEX 4.0 redirects the user to a new version of the URL with a new session ID every time, even if the user already has a session. We found this quite accidentally; we created a simple test app using built-in authentication to narrow things down, and we decided on a lark to include the display of the &APP_SESSION. variable. In other words, for a URL like this:


We’d expect to end up at something like:


And on every subsequent request, we should keep landing at that same link with the same session ID (the value 3343328572473537 in the example above). However, that’s not what was happening, we were getting a new session ID every time. Even more curiously, the value being displayed from APP_SESSION never changed, it was always left at the value of the first session ID we were given in that browser session.

Another problem that was happening was that page items we passed over the original session-id-zero link were indeed retained in the redirect URL, but were not used to set the values in session, despite session protection being off. We think this is because APEX won’t properly manipulate the session from url parameters unless the session IDs agree, and in this case, they wouldn’t.

Now, this was all without the page sentry authentication turned on, so we finally had a culprit — this particular behavior would cause the page sentry function to behave somewhat incorrectly. In our page sentry, which attempts to emulate what APEX normally does, for users that already have a cookie, it just registers the existent session and attempts to forward you to the page you originally requested. Except the session IDs no longer match (because a new session has been generated by APEX thanks to session ID zero), so the URL the user is sent to is for a new session, but the parameters/page item values have been stored in the original session and ignored in the new one.

At this point we decided to adapt the more recent page sentry function listed in Joel Kallman’s blog post as our starting point for getting this working correctly, since his seemed more comprehensive and careful of edge-case scenarios. It looks like this:

create or replace function PASSPORT.oamPageSentry ( p_apex_user in varchar2 default 'APEX_PUBLIC_USER' )
return boolean
l_cgi_var_name varchar2(100) := 'REMOTE_USER';
l_authenticated_username varchar2(256) := upper(owa_util.get_cgi_env(l_cgi_var_name));
l_current_sid number;
-- check to ensure that we are running as the correct database user
if user != upper(p_apex_user) then
return false;
end if;

if l_authenticated_username is null then
return false;
end if;

l_current_sid := apex_custom_auth.get_session_id_from_cookie;
if apex_custom_auth.is_session_valid then
apex_application.g_instance := l_current_sid;
if l_authenticated_username = apex_custom_auth.get_username then
return true;
else -- username mismatch. unset the session cookie and redirect back here to take other branch
apex_application.g_unrecoverable_error := true; -- tell apex engine to quit
return false;
end if;

else -- application session cookie not valid; we need a new apex session
apex_application.g_unrecoverable_error := true; -- tell apex engine to quit
if owa_util.get_cgi_env('REQUEST_METHOD') = 'GET' then
wwv_flow_custom_auth.remember_deep_link(p_url => 'f?'|| wwv_flow_utilities.url_decode2(owa_util.get_cgi_env('QUERY_STRING')));
end if;
-- -- register session in APEX sessions table,set cookie,redirect back
p_uname => l_authenticated_username,
p_session_id => nv('APP_SESSION'),
p_app_page => apex_application.g_flow_id||':'||nvl(apex_application.g_flow_step_id,0));
return false;
end if;
end oamPageSentry;

The first thing we needed to do with the above listing is put in a check for the session ID mis-match caused by linking the user to a page with session zero. If we have the “current”, or originally created session ID in the user’s cookie, we can check to see whether or not it matches what is in the QUERY_STRING, and if they don’t match, redirect the user to the very same URL but with the “current” session ID:

l_current_sid := apex_custom_auth.get_session_id_from_cookie;
l_url := wwv_flow_utilities.url_decode2(owa_util.get_cgi_env('QUERY_STRING'));

-- split on zero or more non-colon characters
l_url_sid := REGEXP_SUBSTR(l_url, '[^:]*', 1, 5);

-- does the current sid match the sid in the url?
if owa_util.get_cgi_env('REQUEST_METHOD') = 'GET' AND l_current_sid <> TO_NUMBER(l_url_sid) then
-- nope, so let's go to the correct url, with the current sid
wwv_flow.debug('oldurl: ' || l_url);
l_url := REGEXP_REPLACE(l_url, '^(p=.+?:.+?):*\d*(.*)$', '\1:' || l_current_sid || '\2');
wwv_flow.debug('newurl: ' || l_url);
owa_util.redirect_url('f?'|| l_url);
return false;
end if;

Now, if the user comes in on session 0 from a link, and they already have a session, but have been redirected to a new/different session ID, page sentry fixes it and redirects the user to the appropriate URL.

However, there are other problematic edge cases. Most Stephen took care of with the clever regex matching used above to identify the session ID if present in the QUERY_STRING, but the real bugger was post_login. In previous versions of APEX, we believe that the remember_deep_link call would cause any subsequent call to post_login to redirect to the user to the target URL. This doesnt appear to be the case in APEX 4.0.

To account for this, we updated the call to pass the target page in to the post_login call directly. We found that post_login will blindly append the session ID to the end of p_app_page parameter string when it redirects, and we can clean that up with the another cleanup-redirect at the beginning of our page sentry function:

-- the post_login call at the end of this function will blindly append the session ID to the URL, even if it is
-- a deep link. Detect this condition, strip the duplicate session identifier, and redirect.
if REGEXP_SUBSTR(l_url, '^.*:' || l_current_sid || ':.+:' || l_current_sid || '$') IS NOT NULL then
l_url := REGEXP_REPLACE(l_url, ':' || l_current_sid || '$', '');
wwv_flow.debug('oamPageSentry: identified duplicate session id on URL, stripping and redirecting to ' || l_url);
owa_util.redirect_url('f?'|| l_url);
return false;
end if;

This set of fixes has gotten us through, straightening out all the redirecting and link remembering that needs to be done when our users come in to link in our pages with params they need and session ID 0.


You can grab the full PL/SQL for our implementation of this page sentry function at this gist.

Codebook 1.4.1 Released in App Store

Permalink - Posted on 2010-12-02 00:00

As previously noted, we pulled Codebook 1.4.0 from the App Store due to a start-up bug, and rushed to get a fix prepared. The update has been released, Codebook 1.4.1 is now available in the App Store, and all users of Codebook should update as soon as possible. Visit the App Store now to get the update.

If you had installed Codebook 1.4.0, or any other recent update and could no longer start Codebook on your device, this update will restore your access to your data. As we mentioned before, we had done quite extensive testing on Codebook before releasing the last update, but we didn’t do it on enough disparate iOS devices to detect this bug, and will be doing far more extensive testing on all future updates.


Well, obviously, we fixed the start-up bug.

But the biggest change since Codebook 1.3 is that Codebook 1.4 provides the oft-requested support for multi-tasking: on devices that are running iOS 4 and support multi-tasking, you can now set a timer, allowing Codebook to stay temporarily unlocked while you switch applications. Makes the app a lot more convenient to use on the Subway, I’ll tell you that.

I’ve also ditched the recycled-paper background displayed on the note view/edit screen in favor of a more subtle paper texture that’s far more pleasant.

Coming Soon in Codebook 1.5

Work on Codebook 1.5 was completed recently, and we’re now testing it as mentioned above for any surprises. It includes a ton of usability improvements and a fantastic new feature: Dropbox Sync.

The note view/edit screen also got a lot of love, too:

If the differences aren’t readily apparent: the top-right navigation bar button is no longer the action button kicking up an email compose view. This + button allows you to quickly add a new note — the current note is torn off the view (a la Apple’s MobileNotes) to reveal a fresh page.

The toolbar is a long-overdue addition. Now you can delete what you’re looking at without having to pop back to the list view, or you can hit the Action/Share button. The share button, by the way, no longer just throws up a compose view. Instead it presents a modal sheet providing you the option of sharing the current note as an email. This pause in the process allows us to add more options later and will help cut down on some accidental mailing of notes.

Finally, while you can’t tell from the screenshot here, the animation of presenting the keyboard and re-sizing the text view for editing is greatly improved. It’s no longer jerky, but nice and smooth, and the background doesn’t appear to get squished or stretched, it just remains static, providing a much nicer editing experience.

This is all probably a couple weeks out from appearing in the Store. Hopefully, by Christmas.

Thanks for using Codebook!

STRIP: Not Cheap And Nasty

Permalink - Posted on 2010-12-01 00:00

SY, a fan of our password manager STRIP for iOS sent us one of the funnier complements we’ve ever gotten:

Overall I love the app, the interface is clean and simple but doesn’t look cheap and nasty like XXXX and others.

Thanks, SY!

Codebook Startup Bug in 1.4.0

Permalink - Posted on 2010-11-17 00:00

Updated, Update II, below

Thanks to direct reports from our customers, and some crash logs we’ve received via iTunes Connect, it appears that the new version of Codebook that we published in the App Store (version 1.4.0) had a start-up bug in certain circumstances, on certain iOS versions and hardware. Basically, the app was crashing immediately on iOS 3, and crashing on some instances of iOS 4 during the application start-up sequence. We’ve since pulled Codebook from the store to prevent anyone else from downloading this update.

No one’s data is lost, but anybody who’s run into this problem will find their data inaccessible, simply because they can’t start the application. To that regard, we are hustling to deliver a fix through the App Store (we’ve already got the bugs solved, and thoroughly tested). We realize that if you’re a serious user of Codebook, you depend on being able to access your data, and we’re on it.

For all future releases of Codebook, we’ll be testing on more devices, iOS 3 and 4, to make sure this doesn’t bite us again. I should note that we had done extensive testing of Codebook, but it was limited to iOS 4 on an iPhone 4, and iOS 4 on an iPhone 3G. Clearly, we need to be testing this on the iPod Touch, on iOS 3, etc, and that’s what we’ll be doing from now on.

We do have some good news: Codebook 1.5 is already undergoing testing and should be ready for release soon. The main reason for the version bump, aside from a ton of user interface and usability improvements, is the new feature: Sync with Dropbox!

Thanks again for your patience and feedback.

Update, Nov 23rd, Codebook 1.4.1, which fixes the issues outlined here, was submitted to Apple on Sunday (Nov 21) with a request for expedited approval due to the situation at hand. We’re waiting to hear back, hopefully it will be approved and posted to the App Store within the week.

Update II, Dec 2nd, Codebook 1.4.1 is now available from the iTunes App Store. All users of Codebook should upgrade as soon as possible. Release notes (and sneak peaks).

Strip Desktop and the Future of Strip

Permalink - Posted on 2010-10-29 00:00

Updated: 6/6/2012 Strip for Windows and Strip for OS X are now for sale.

It’s about time we came out and said it: we are in fact working on Strip Desktop. Long requested by fans of our popular private data management app for iOS (and previously for Palm OS), Strip Desktop will provide a means for users to manage their Strip data on their desktop computer, in addition to the features we’ve already made available in Strip Sync.

As you can hopefully tell from the screen clip above (click to enlarge), we are working hard to maintain the same simple and elegant style used in Strip for iOS, by borrowing some of our design choices from Apple’s Address Book. We expect this interface to change and mature quite a bit over the next few months, but this is a reasonable approximation of our intended product. You can’t tell from that lone screenshot, but all the basic features of the data editor in Strip for Mac OS X are complete at this point.

Strip Desktop is a bit of a misnomer, as it actually describes two distinct, native applications: Strip for Windows, and Strip for Mac OS X. We’ve been making great progress recently on the Mac version, but we’ve fallen a bit behind on the Windows version and expect to pick up the slack soon. We are considering publishing Strip for Mac OS X in the new Mac App Store recently announced by Apple, and expect to have it ready for release by the time the Mac App Store opens for business, whether or not we decide to go that route (Apple estimates this will be around Jan 26th, 2011, so that’s our target).

Online Backup & Strip

We’ve reconsidered our previous stance on providing an online-backup feature. We’ve found that supporting Sync over local WiFi networks is particularly difficult. With so many different types of home networking hardware out there — with all the infinite variations of network configurations, combinations, pitfalls, and firewalls — it’s no wonder Apple does sync over the Dock cable. It’s time for us to find ways to make this easier, too.

We’re not getting rid of Sync over WiFi, but we are going to begin experimenting with an online backup & sync feature for Codebook, and if all goes well, we’ll port it back to Strip. The basic gist of the feature is that a copy of your encrypted db will be placed in your Dropbox account. When it’s time to sync, any one of your copies of Strip can download the master copy in your Dropbox, and sync against it locally. Your unencrypted data will never be stored on Dropbox, and your password/key will never be sent over the wire. This feature will have the happy side-effect of providing you with the same multi-device replication you get now with Strip Sync.

Discontinuing Strip Sync

Relatedly, we have one maintenance update in the pipe for Strip Sync, and we plan to discontinue development of the application once Strip Desktop is released. Once we have Strip Desktop and the Online Backup feature in place, there won’t be a need for the software anymore — whether or not you choose to use Strip Desktop. The forthcoming maintenance update of Strip Sync will coincide with the release of Strip 1.5 for iOS, a rather handy set of small productivity enhancements and bug fixes. Users who upgrade to Strip 1.5 will need the latest version of Strip Sync, as well. We’ll publish a notice to the mailing list as soon as this next release is ready.


We really appreciate the requests you’ve been sending in for an Android port of Strip! At the moment we need to focus on the desktop applications. Once we’ve brought them to market, we will take another look at building a port for Android.

How to Structure Applications for Mac OS X?

Permalink - Posted on 2010-10-28 00:00

There’s a really telling thread active on the cocoa-unbound mailing list right now, regarding the difficulty in grasping how to structure applications in Mac OS X, especially as compared to its sibling iOS, and the materials that are available, a subject with which I’ve become quite familiar as I hack on STRIP for Mac OS X:

When I create a new Rails application or Ruby Gem, there’s a clear, predefined application structure. Its obvious what things go where. It’s the same structure every time,

When I first created new iPhone projects, picking a “Navigation-based app” or such like gave you all the structure you’d really need for that type of app. You could see exactly where the VCs lived, how they hooked up to NIBs and how they talked to each other. I don’t need the templates now, but they were very instructive in the beginning.

I’m missing the same thing for Mac applications.

Exactly. List users are starting to add their suggestions for reference material and tutorials, some good resources there. But really, we could use some better, more comprehensive materials from The Source for Mac OS X. The WWDC video sessions are invaluable, the small app examples are great, the API documentation is fantastic, but we devs really could use some beefier, more complex, real-world reference materials.

Update: It’s not really a how-to document, but I did get a lot out of Matt Gallagher’s article, The design of every Mac application.

Getting Bottom Bar Buttons to Follow an NSSplitView Pane (Code, wonky)

Permalink - Posted on 2010-10-27 00:00

In working on Strip for Mac OS X, I came across a scenario in which I wanted to get the bottom bar buttons on an NSWindow to follow the left-margin of panes about them in an NSSplitView with which they are associated. That sounds like a mouth full, so I’ll use a picture to illustrate, it’s an idea I’m looking to borrow from Apple’s Address Book application (click image to embiggen):

What I’m trying to suggest with the annotations I’ve made on the image is that the [+] button under that middle pane (highlighted in green) will move as the left margin of the pane is moved, either by the user, or by the window being resized—which cascades down to the subview being resized, since the split view is basically the entirety of the window’s contents.

In any event, I wasn’t sure how to hack this out and didn’t see any examples out there, so I put one together. There might be a better, faster way of handling this, perhaps by responding to NSView notifications about a change in frame, but here I just used an NSSplitViewDelegate method that fires every time subviews are resized (thus, every time the margins of the panes might have been adjusted by a resize or a divider moving). Sample project is here on Github, but this is the meat of it, in the NSSplitView’s delegate:

// gets call after the NSSplitView is resized OR after the divider(s) are moved
- (void)splitViewDidResizeSubviews:(NSNotification *)aNotification
[self repositionBottomBarButtons];

- (void)repositionBottomBarButtons
// we don't actually have to do anything for the left-most button and the left pane
// because we've got it pegged in IB to maintain it's position in relation to the
// window's bottom and left bounds

// first tell the superview that it will need to redraw the frame we'll be moving
NSRect oldFrame = [rightButton frame];
[[rightButton superview] setNeedsDisplayInRect:oldFrame];

NSPoint newOrigin = rightView.frame.origin;

NSRect newFrame = NSMakeRect(newOrigin.x, oldFrame.origin.y, oldFrame.size.width, oldFrame.size.height);
[rightButton setFrame:newFrame];
[rightButton setNeedsDisplay:YES];

And there we go, button now follows the pane’s margin, moves nice and smooth.

Announcing Zetetic Connect

Permalink - Posted on 2010-10-08 00:00

Today I'm very excited to announce Zetetic Connect, a fast, super-flexible way to get information out of (and into) LDAP directories and relational databases databases for the web, iPhone, BlackBerry, and Android.

Connect grew from a need to publish Active Directory data to the web; so many businesses and schools rely on directory systems, but there just aren't a lot of mature applications that help people take full advantage of those directories or to spot and correct missing data. Connect does that and, going two steps farther, hosts an extremely robust, high-performance engine that can unify multiple directories and data stores behind the scenes, and allows users from any of those directories to sign in.

For example, if part of your company uses Microsoft Exchange, another division uses Lotus Domino, and you've just acquired a third group that uses Zimbra for messaging, Zetetic Connect can quickly create an online phonebook merging all three. Just launch Connect, search for "Smith", and you'll get the contact and organizational details for all the Smiths across all systems, live. The same powerful simplicity applies to contacts, groups and distribution lists, sites and locations, and virtually any other data in your directories. (Of course, you can choose what to include or exclude from each.) Users can easily maintain their own data, such as phone and mobile numbers, according to rules you define.

Interested? »

We're currently running a small number of commercial evaluations for interested customers, including system deployment by Zetetic's LDAP-meisters. Contact us now if you'd like a demonstration and evaluation of the system.

Your mobile users will be impressed by Connect's user interface, which is tailored especially for the iPhone, BlackBerry, and Android, and has the look and feel of a native application. (See: screenshots.) Connect is internationalization-friendly too, so your users get Connect in their native languages, top-to-bottom.

Behind the scenes, we've leveraged many years of directory experience to build an extremely robust framework that actively monitors your directory servers' performance and availability, so users won't notice if individual servers go out of service. Connect also does some pretty serious and smart caching and threading, and features a wealth of special optimizations for Active Directory. That said, it works great with any LDAP server, SSL on or off, and any schema.

You can even use the Zetetic Connect core as a pure-LDAP, federation-capable membership and role provider for any ASP.NET application, a topic upon which I'll touch in a future blog post.

Some Updates to Tempo 10/2010

Permalink - Posted on 2010-10-07 00:00

Last night we pushed some minor updates to Tempo, and I want to take a quick moment here to tell you what they were.

Excel XLS Exports (and new listing)

We’ve been fielding the UTF-8/Excel complaint about our CSV exports for a loooong time, and now the nightmare is over. We’ve implemented a new conversion filter that dumps the current report into a native .xls Excel spreadsheet. We also re-labeled the exports to make it a bit easier to find the one you want.

The UTF-8 problem was never an issue with our CSV exports, by the way. Microsoft Excel has always had a bug importing CSV files (one they will apparently never, ever fix), and it treats the characters in your file as ASCII data no matter what. So it goes. Now you’ve got the good stuff.

Bug fixed: Bad Figures in Exports!

At some point we added pagination to our reports’ data sets. This caused a bug in our Time by People and Time by Projects reports. The Total row in each was correct, but the reported hours for each project or person was incorrect in some cases — limited to the total for the currently paginated set. All fixed now, our apologies.

Improved Print Preview

The print preview on the Reports screen was getting a little bit heinous, this should improve things for the time being.

Invoice Memo

When our billing system bills tempo accounts, it sends a receipt, or invoice, by email to the account owner documenting the charges. One of our German companies recently asked if they could include custom information on this document in order to be “in compliance with German law.” We have no idea what it takes to be in compliance with German law, but we did provide a way for them to do it in this release.

If you are logged in as the account owner, or an account manager, go to the Account screen and you’ll see a new field, Invoice Memo, in which you can put anything you like and it will appear under Memo: on your billing receipt.

That’s it for this round of minor adjustments. More are planned for the near future, based on our customers’ feedback, bug reports, and our desire to make Tempo easier to use and more intuitive. As always, if you have ideas, complaints, or suggestions, get in touch

Tempo / Zetetic Server Maintenance, Oct 6, 11pm EDT

Permalink - Posted on 2010-10-05 00:00

We’re planning to do some preventative server maintenance tomorrow night to ensure the reliability of our systems and the security of our customers’ data. At 11pm EDT on Oct 6, our various websites will become inaccessible and remain that way until 11:30pm. This affects our time-tracking system Tempo, as well as zetetic.net, getstrip.com, and getcodebook.com.

To find out exactly when this will happen in your time zone, click here. If you have any concerns about this, please get in touch!

Update: we’re back in action. Thanks for your patience.

Advisory: Safe-guard STRIP Data When Migrating to a New iPhone or Upgrading iOS

Permalink - Posted on 2010-10-01 00:00

It has come to our attention that there is a potential for inadvertent loss of data in STRIP for customers who have purchased a new iPhone to replace an existing one. This may also affect other iOS devices such as iPod Touch and iPad.

When setting up a new iPhone in iTunes, iTunes offers to restore the data from your old device on to the new one. It would seem that in some cases the process appears to have been completed successfully, but the user later discovers that while Contacts and data from other default applications is transferred successfully, STRIP and other downloaded applications are missing their data. Some users have found (including us personally) that doing a second “Restore from Backup…” operation completes the migration successfully.

However, some users don’t notice the failed migration right away, and have at times discarded the old device (thus losing access to its copy of Strip’s data), or have synced their iPhone with iTunes since the initial Restore, which has the effect, in some cases, of wiping out the old backups maintained by iTunes. In that unlikely situation, it becomes nearly impossible to recover the user’s data.

Avoiding the Problem Before You Make the Switch

If you are planning to migrate to a new device or upgrade your iOS operating system, you’ll want to do the following before you make the switch. We’ll go through the various steps below.

  • Disable automatic syncing in iTunes
  • Turn off encrypted back up (temporarily)
  • Take a fresh backup in iTunes, explicitly
  • Use Strip Sync to take an independent backup of your data

As always, we are here if you run into trouble, please get in touch.

Disable automatic syncing in iTunes

Make sure your iPhone is disconnected from your computer. Open up iTunes, go to Preferences → Devices, and make sure the checkbox “Prevent iPods, iPhones, and iPads from syncing automatically” is checked.

Turn off encrypted backup (temporarily)

Connect your iPhone (or iPad or iPod Touch) to your computer with the USB cable that came with your device. If iTunes is not running, start it. Once the device appears in the left-hand side of the iTunes window, click on it to bring up the Summary screen. Scroll down to Options, and make sure that “Encrypt iPhone backup” is not checked.

Take a fresh backup in iTunes, explicitly

Every time you sync, iTunes will take a fresh backup, but it doesn’t necessarily keep that backup around for later. Doing it explicitly will keep the backup around for later in case we need to do a Restore.

In iTunes, with your phone still connected, right click on your phone’s icon and name in the left-side view of iTunes. In the menu that comes up, select “Back Up” to initiate a fresh, unencrypted back up.

The process may take a few minutes to complete.

If you had turned off encrypted backup in the previous step, you can now turn it back on.

Use Strip Sync to take an independent backup of your data

To ensure that you can have an independent backup outside of iTunes, we’ve published a free companion utility for Mac OS X and Windows called Strip Sync. It is important that you download and configure Strip Sync on your desktop. Once installed you’ll be able to sync your data off your iPhone and into Strip Sync over WiFi.

You can download Strip Sync for free over here: http://getstrip.com/strip-sync

Be sure to follow the setup instructions for your operating system:

Strip Sync works over WiFi on your home or office. If you have problems syncing the most likely cause is a firewall or network issue, and a good first step is to ensure your workstation firewall is disabled or at least allowing incoming connections. Do get in touch with us if you need help.

Tempo / Zetetic Server Maintenance Tonight, Sept 22, 11pm EDT

Permalink - Posted on 2010-09-22 00:00

We’re planning to do some preventative server maintenance tonight to ensure the reliability of our systems and the security of our customers’ data. At 11pm EDT on Sept 22, our various websites will become inaccessible for a short period of time (should only be 10 or 15 minutes, max). This affects our time-tracking system Tempo, as well as zetetic.net, getstrip.com, and getcodebook.com.

To find out exactly when this will happen in your time zone, click here. If you have any concerns about this, please get in touch!

Codebook Updated in the App Store

Permalink - Posted on 2010-09-14 00:00

There’s an updated version of Codebook in the App Store, v1.3.0, which fixes a bit of a nuisance bug with regard to timestamps.

Tempo Maintenance Tonight, Sept 1st 11PM EDT

Permalink - Posted on 2010-09-01 00:00

For customers of our time-tracking system, Tempo, the web interface will be temporarily unavailable starting at 11PM EDT tonight, Wednesday September 1st.

Just a couple of small fixes, service should only be offline for a few minutes while we make sure nothing’s amiss. Reporting time entries via Twitter and Email will continue to function without interruption.

On the Subject of Online Backup for Strip

Permalink - Posted on 2010-08-16 00:00

We’ve received a few requests recently to provide an online or cloud-based backup/sync solution for our password manager Strip, in particular as to whether we plan to add an integration with Dropbox, so we figured now is a good time to provide a statement with regards to what direction we’re going.

We do not have plans to provide an integration with Dropbox for Strip at this time. While we agree an online backup would a really cool and useful feature, we’re uncomfortable with tying a core part of the product to another service that might change without consultation. That’s not to say anything at all about the utility or stability of Dropbox (it’s a really useful service done very well), but decisions made at Dropbox will always be out of our control.

Any online backup would require that the database file be stored remotely in an unknown location, with unknown security risks. That scenario makes us and many of our customers nervous, so we are reluctant to move in this direction without serious planning and risk evaluation.

We’ll continue to investigate the possibility of an online backup for Strip, but in the mean time, Strip can be backed up to the desktop with Strip Sync, providing multi-device replication. Our implementation requires authentication, and the files are always encrypted and secured on your local computers.

Strip 1.4.8 Released

Permalink - Posted on 2010-07-13 00:00

A new update to Strip, our password manager for the iPhone, has been approved by the Apple iTunes App Store, version 1.4.8. This is mostly a bug-fix release for version 1.4.7, and makes the changes list below. While this is a minor update, all users are strongly recommended to backup their data and update to the latest version to ensure compatibility with future versions of Strip.

  • Fixes crash on auto-save of Note during fast-app switching on iOS 4.
  • Autosave is now enabled when editing Notes with a hardware keyboard.
  • Displays GUID of data entities to facilitate sync support requests and debugging.
  • Corrects icon display on import.
  • Fixes a couple of NIB-related crashes introduced by iOS4.
  • Corrects a typo in one of the dialog prompts.

More updates are on the way, but they’re still a few weeks out, so make sure you get the latest and greatest. [ Get it on iTunes ]

Announcing Strip Sync for Mac OS X and Windows

Permalink - Posted on 2010-07-01 00:00

Updated: 6/6/2012 This blog post is out of date, and the software referenced in it, Strip Sync, has been discontinued in favor of Strip for Windows and Strip for OS X.

As many of our customers have already noticed, we’ve made Strip Sync for Mac OS X and Windows generally available. It serves as a free a companion utility to Strip 1.4 for iOS, the first version of Strip to support our new Sync feature. More accurately, Strip supports multi-device replication, allowing you to safely replicate your data across any number of devices1. Strip is the first password manager we know of with this kind of awesome and lightning fast sync system.

No longer will our dear customers be relying on and subsequently let down by iTunes for backups and data recovery. Every time you sync your device with Strip Sync, a backup copy of the local database on your desktop is taken for you. You can revert to any of your backups at any time, and the sync service also provides authoritative data restore.

Strip Sync also provides CVS import and export. This allows you to export your database to a spreadsheet that you could print and store in a safe. It also allows you to bulk load new entries, and in the case of the Mac OS X version, you can do bulk updates as well (e.g. export the existing database to spreadsheet, make edits, and import the same sheet).

Now that more folks are seeing what Strip Sync is – or rather, that it’s not a full desktop port of Strip, thus the qualified name – we’ve been getting questions about a full desktop port. We’re working on it! It’s next on the list, Strip Sync had to come first. You can expect minor updates to Strip Sync in the next few weeks as we make some minor improvements (and add bulk-updating to the Windows version).

I should add that there a ton of other improvements to Strip itself in the 1.4 upgrade (free for those who’ve purchased Strip already), including improvements to the display of data, the ability to work with stored data quickly (copying, launching, etc), and better performance to boot.

With regard to iOS 4, things are looking pretty good so far. We have no plans at the moment to take advantage of new features in the SDK just yet, as our primary concern is stability and compatibility. We do have upcoming improvements planned for the 1.4 version of Strip and if any bugs pop up we should be able to address them in forthcoming updates.

1 When we have a chance, we’re going to post an article about how this works and the technology behind it. Ditto, the replication library, will be made available as open-source software, as was done with our encryption engine SQLCipher, in order to facilitate peer-review and to encourage future innovations from other developers.

Github Auto-Generates QR Codes for Android Apps

Permalink - Posted on 2010-06-23 00:00

Imagine how cool it would be if we had this for the iPhone? Says Github:

For all you Android developers out there, we now will automatically detect when you upload an Android package (.apk) file and will give you a QR code page link on your download page list…. Now you can scan that with your Android phone to automatically download and install that package.

As a hacker, that makes me straight-up jealous. I ordered my iPhone 4, but I’m not going to lie, I sweat this stuff.

Alexis Rondeau tells me that you need to configure the Market app to allow this behavior explicitly. I’ll take it.

Tempo Update: release Macross replaces Voltron

Permalink - Posted on 2010-06-21 00:00

Last night we delivered an update to Tempo, our time-tracking service, called Macross. The previous release version had been named Voltron internally. The reason for naming them, beyond internal version control and tracking, is that we want to start providing some more communication going forward about what’s on the road map for Tempo, and having names for the releases makes it a bit easier.

In any event, Tempo release Macross went into production last night. It brings a number of badly needed performance improvements and runs off the latest and greatest stable version of Rails (2.3.8) AND gets us off Ruby 1.8.6 (now we’re on 1.8.7). In particular, users with very high numbers of projects and users will be happy to know that the management screens are way faster thanks to implementing some over-due pagination. There’s still a lot more optimization we’re planning to do, and we’re starting to consider changes we might make to the UI on the Projects and Team screens to make them more useful, in particular for our larger account holders. If you’ve got your own ideas, please get in touch and tell us what you’d like to see.

Another important update in last night’s release was switching our Twitter API interaction over to OAuth from HTTP Basic Authentication, due to their upcoming switch-over on June 23rd now-postponed conversion to OAuth. Whenever they do make the switch, Tempo will continue to scoop up your time entries via direct messages to @keeptempo.

Macross, named after the TV show Macross and the SDF-1, is mainly a stepping stone, to move us off some really old tech and to better position us for further infrastructure upgrades and service and UI improvements. This is now the current version of Tempo.

The next release, Macross Plus, is currently shaping up. The biggest thing I want to tackle there is moving Tempo to Rails 3; we anticipate that this will deliver some really great performance gains, as well as make on-going development far easier. We still need to firm up the list of other improvements and features that will be in Macross Plus – it will likely remain in flux, so it’s not a contract, but I will post it soon.

Strip Sync Beta Update: Almost There

Permalink - Posted on 2010-06-18 00:00

Updated: 6/6/2012 This blog post is out of date, and the software referenced in it, Strip Sync, has been discontinued in favor of Strip for Windows and Strip for OS X.

Update: Fixed bad link to the beta sign up.

As many of our customers have noticed, Strip Sync is still in beta (you can sign up here). We have a few finishing touches to work out and a final set of builds to run through the beta before we declare it official. Y.T. has to update the documentation, as well. We are planning to do a public release early next week.

I’ve just pushed an update to Strip Sync for Mac OS X (0.2.2), that we hope is a good if not final release candidate for that version. An update to Strip Sync for Windows is on the way to resolve many of the data import issues that were discovered in the last build (turns out that an MSFT data adapter was behaving somewhat badly, and we’ve got a fix on the way). This next update of the applications also provides a minor bug fix for multi-device replication.

Both the Mac OS X and Windows versions of Strip Sync automatically check for signed updates, so you should only need to run the software and you’ll be asked if you’d like to download the latest and greatest.

Inconsolata - Excellent Coding Font

Permalink - Posted on 2010-06-17 00:00

Recently I visited Mohit Muthanna’s blog 0xFE for the first time (a great nerd tech read, subscribed!) and came across this post about his new favorite font for programming, Raph Levien’s Inconsolata:

It’s super, super snazzy. Switched both TextMate and XCode over to it as my default, it’s quite pleasant. I’m not exactly a typography connoisseur, and while I’ve looked at other mono-space fonts before as an alternative to my usual default of Monaco, this is the first I was ever tempted to really switch.

Also, it’s free. Apparently, variants of the font are breeding rapidly, although I’m not feeling any of them in particular. Also, I don’t need straight-quotes, I think the quotes look just fantastic:

Many thanks to Raph for making this available! Check out the aforementioned home page, this Google engineer is quite an interesting character!

Hampton’s Ruby Survey 2010

Permalink - Posted on 2010-06-14 00:00

The 2008 and 2009 results are listed, too. If you code in Ruby, you should fill it out and have a look at the previous stats!

Among the expected results are that Rails appears to be pulling more users away from Merb, due probably to Rails 3 being the merger of the two frameworks. Also, readership of the pickaxe is down, but only a little.

Meanwhile, I continue to be surprised by how few people use Haml! I just assumed that because it was so easy and that I personally found it such an important tool, that everyone else would, too. Well, shows me!

Perhaps the auto-completing short-cuts that many folks use for HTML and ERB make this a non-issue. But I can’t stand to write ERB anymore. Grumble, grumble.

Custom URL Shortener for Google Analytics using Rack

Permalink - Posted on 2010-06-14 00:00


A Rack-based URL Shortener for Link Tracking

If you’re like us and you like to send out a newsletter once in a while about one of your new products – in particular if you’re running promotional ad campaigns and your own marketing efforts – you’ve probably tried tacking on Google’s various utm_.* variables to the URLs you are sending people. These are really handy in that Google’s analytics code looks for these when users visit your website, allowing you to start tracking which of your ads, promos, and newsletters is performing well, and which are bombing.

The only problem with this is that you end up trying to put links like this into emails, and they’re long enough to be problematic on display, in particular in plain-text emails:

Write a blog post about Strip telling us what you like and
what you don't like, and we'll hook you up with a candy-
bar! Click here to learn more: (not an actual link)


We’ve all seen emails where that URL gets garbled and cut into two lines.

What we used to do for this was to employ a URL shortener like bit.ly or tinyurl.com, resulting in links like http://bit.ly/abc123. This solves the problem of munging, but brings on two new problems: your links are dependent on bit.ly always being available and working correctly, and they’re not always easy to “fix” once they’re out there. In particular if you decide to change up the various UTM variables you’re sending to Google Analytics. PITA.

Suffice it to say, many sites are choosing to implement their own URL shorteners to ensure their carefully crafted links don’t rot, and we decided that we’d do ours as a tiny Rack application with a YAML file:

# Rack-up config
require 'rubygems'
require 'rack/zetetic/rack-campaign'
run Rack::Zetetic::Campaign.new('/path/to/your/campaigns.yml')

To install:

gem install rack-campaign

Here we list our campaigns out in YAML:

url: http://dev.zetetic.net/blog/2010/06/11/introducing-rack-campaign
campaign: rack-campaign
source: blog
medium: internets
content: example link

url: http://getstrip.com
campaign: rack-campaign
source: blog
medium: internets
term: strip rocks!
content: example link

At the top level of our Nginx config, we define an upstream directive for Unicorn, which will host our Rack application over a unix socket (mwahahaha):

# define upstream for campaign routing
upstream campaigns {
server unix:/www/campaigns/tmp/sockets/unicorn.sock;

Then, in each of our Nginx vhosts, we add a location directive for /c, telling the server to forward all such requests to the unicorn process:

location /c {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_max_temp_file_size 0;

# forward everything else to the mongrel cluster
if (!-f $request_filename) {
proxy_pass http://campaigns;

Now, we can pass out the link you may have seen on Twitter:


When you visit it, you get redirected to:


Isn’t that neat!?

This needs to perform very well, so we did a little testing with Apache’s ab testing tool and found it runs as fast as a normal nginx rewrite. Here’s what a basic rewrite looks like (/software rewrites to /code):

$ ab -n 500 -c 10 /software
Non-2xx responses: 500
Total transferred: 191000 bytes
HTML transferred: 92500 bytes
Requests per second: 4626.33 [#/sec] (mean)
Time per request: 2.162 [ms] (mean)
Time per request: 0.216 [ms] (mean, across all concurrent requests)
Transfer rate: 1721.00 [Kbytes/sec] received
Percentage of the requests served within a certain time (ms)
50% 2
66% 2
75% 2
80% 2
90% 2
95% 2
98% 2
99% 2
100% 2 (longest request)

And here’s how rack-campaign is performing:

$ ab -n 500 -c 10 /c/blog-rack-campaign
Non-2xx responses: 500
Total transferred: 167500 bytes
HTML transferred: 7000 bytes
Requests per second: 2749.78 [#/sec] (mean)
Time per request: 3.637 [ms] (mean)
Time per request: 0.364 [ms] (mean, across all concurrent requests)
Transfer rate: 896.43 [Kbytes/sec] received
Percentage of the requests served within a certain time (ms)
50% 2
66% 2
75% 3
80% 3
90% 4
95% 4
98% 13
99% 14
100% 39 (longest request)

Obviously, there’s some differences but so far, it looks like rack-campaign is doing well enough here. I’m sure it could be faster, and I’m sure that over time a YAML file could become a cumbersome manner of storage, but for now it’s good ’nuff. Feel free to fork it and use a SQLite database (which in this case would likely be very fast).


gem install rack-campaign

Z-Site Refresh, Moving Off Radiant

Permalink - Posted on 2010-06-04 00:00

A thing of minor note: we’ve updated the main zetetic.net website. Aside from giving a few of our pages a long-needed refresh, we’ve decided that we really wanted to get all this content out of the database and onto the filesystem.

For a long time, we’ve been using the Radiant CMS to run both the website and the blog. It’s had it’s ups and downs. Radiant is pretty cool, a Rails-based application that has a lot of brilliant tricks for building out a website with a lot of shared content and cross-marketing. However, for us it’s always been a tad volatile and clunky. For instance, it’s easy to accidentally double-submit on a new post to the blog which then creates a page with no parent_id and that makes your whole site impossible to access.

Major version upgrades have been a real nightmare, especially when it comes to getting plugins updated. Plugins are what make Radiant so dynamic, but they tend to be very brittle, and are complex to upgrade with a major update of Radiant. Simple things like tagging or comments really ought to be part of the core system.

Then there’s the memory usage, or rather Ruby’s memory allocator and garbage collector (which could be considered a form of entropy). We don’t see the need to incur and manage this overhead just to provide static HTML content and images.

Finally, we wanted to be able to build out our pages in HAML, manage them over time with Git, and we’ve found that the Ruby gem staticmatic is just the thing for this. It provides a Rails-like project structure, partials, layout capabilities, etc. I even managed to hack in an automatically generated sitemap.xml.

At this point our website is almost entirely static content, with a little jQuery here and there where needed, and the blog itself is still on Radiant, soon to be moved over to another engine. When we have some spare cycles I’ll try to post some of the tips and tricks we employed to make it happen, but it’s nothing that any competent Ruby programmer can’t handle.

As an aside, the staticmatic gem is maintained by Stephen Bartholomew, and he’s doing a great job of actively maintaining the project. The mailing list is pretty active and helpful, and there seems to be a good community of people using it. That tends to give a tool a longer shelf-life and makes us even more confident in our decision to make the switch.

The Side-loading Argument for iPhone OS

Permalink - Posted on 2010-06-04 00:00

The argument about the iPhone OS being too “closed”, or that Apple is controlling what you do with it too tightly, is still being pretty hotly debated, and I’m loathe to wade into it because most of what could be said has been said, usually with a lot of invective that’s unhelpful. For the most part, while I find it annoying, I try to keep in mind that nobody is forcing anyone to buy iPhones. Take it or leave it.

Yesterday, John Gruber brought up this interesting proposition by Jason Snell in which the latter proposes that allowing the “side-loading” of native apps would end the debate, and end the claims of critics that iPhone OS is too “closed.” I don’t agree with him that this will be the direct consequence, but I think it is worth considering. Happily, Gruber has pulled the money quotes for us:

I don’t think the company needs to stop controlling what apps get in the App Store. All Apple needs to do is add a new feature, buried several menu items down in the Settings app, that mirrors the one found on Android devices: an option that lets you install Apps from “unknown sources.” If a user tried to turn this option on, they’d get a scary warning about how these sources couldn’t be trusted, and that they may lead to instability, crashes, loss of data, you name it. Scary stuff.

Most users will never find that setting. Many who do will be loath to turn it on. But by putting it there, Apple immediately shuts up every single claim that the iPhone isn’t open.

Obviously, I like this idea, but I don’t think it “immediately shuts up every single claim that the iPhone isn’t open.” Gruber responds:

Personally, I’d welcome such a move, but I don’t think it would have the effect Snell envisions. Snell’s argument is that Apple should do this to nip the argument that the iPhone is too closed. But if Apple did exactly what Snell argues, critics would still harp on the closed App Store. iPhone critics have seldom let facts get in their way.

Maybe John’s right about critics of the App Store, at least some of them. But I think there’s another angle of influence to consider here, a better reason to do this, that will help achieve the goal of calming critics who might scare away potential customers, telling them that the device is “too closed.” Consider Gruber’s further argument later on in his post:

If there are people who think the iPad can’t read PDFs or play music and videos that aren’t purchased from the iTunes Store, then surely there would be people who’d think you can only install apps from the App Store even if sideloading were a supported option, as per Snell’s suggestion.

This is more likely than not the result of the tech-head discussion spilling over to blogs that normal people read and daily conversation in a kind of painful telephone game. It’s almost like watching political campaign spin and slogans propagating.

I’d like to offer a bit of dissent here. Perhaps I’m not the kind of critic John is writing about, since I’m already an iPhone developer, but this would certainly make me very happy and alleviate most of my concerns (in particular the very high risk of investing months of “opportunity cost” on an application that could be rather capriciously rejected from the App Store). Also, and more importantly I think, I’m one of those people who gets asked by friends, “should I buy an iPhone? I heard those things are really closed, that you can’t do what you want with them.” My answer to those folks would suddenly be radically different*.

Then there’s all my sysadmin friends buying Droids instead of iPhones. I think they’d have a radically different view of all this, too. Being able to load what they want is specifically the concern they have. In my circle of tech heads, we don’t care that the App Store is closed, we care that we are prevented from loading what we want onto the device. We’d still happily sell software on the App Store (I think few would choose to go it alone) and buy software on the App Store. And we’d be more inclined to develop software for the device itself. In fact, you’d probably have an explosion of freeware, further entrenching iPhone OS.

I think a lot of tech folks – who are not normal folks, but who end up being a product’s pro-bono (or de facto?) evangelists to the normal folks – do see the prohibition against side-loading native apps as being really heinous. They’re like howling monkeys on the issue! And they are very much the people coloring the discussion, starting this telephone game of “the iphone is locked down,” resulting in normal people thinking that they can’t read PDFs or load their own music. Maybe I’m wrong, but I think these are dots appropriately connected.

I think all this other stuff about the App Store itself being too closed is just window dressing for that issue. I don’t think Apple needs to do this to convince people to buy the iPhone or the iPad – so far it would seem they clearly don’t – so I don’t expect to see it happen.

An aside: I don’t think it can reasonably be said that the prevention of side-loading native apps is solely to protect the user experience, as it’s also been exercised by Apple in ways that have nothing to do with protecting the user experience (rejecting Google Voice, punting that 4Chan image scraper or whatever it was, etc). Furthermore, it obviously gives them a monopoly on revenue for the whole market place. The App Store is very convenient, but it’s very much the only game in town by force.

Allowing the side-loading of native apps really would change the discussion quite a bit, and does cut the rug out from under the whole “what iPhone doesn’t, Droid does (unless Verizon doesn’t want you to)” ridiculousness.

* Usually my answer is, “yeah, they’re great, I love it. No, you can’t load whatever you want onto it, but it’s still really awesome, despite regularly dropping all my calls.” And that right there is probably why Apple won’t change the policy. Still, “Yes, buy it, yes, you can do whatever you want with it, it’s really awesome, despite regularly dropping all my calls,” is a much better endorsement.

Strip 1.4 Coming Soon / Git Pr0n

Permalink - Posted on 2010-06-03 00:00

We’re a hair’s breath away from releasing the latest and greatest version of Strip, our password manager and data vault for iPhone OS. Just a few tweaks to make, then we’re on to App Store submission. Strip Sync is also available for general beta, just pop on over to the contact form and drop us a note if you’d like to participate.

We recently merged the development branch into master and tagged the release. I love looking at these stats:

113 files changed, 6956 insertions(+), 4447 deletions(-)

More prep work to do, we’ll keep you posted on our progress. Beta testers – the feedback has been great, please keep it coming!

One last thing to note: the Ad Hoc development and app signing quagmire that Apple has developed to control how we handle beta testing has been a huge hindrance to many of our beta testers. We’re sorry about the complexity, there’s not much we can do about it, but we seem to have most folks getting along alright.

AT&amp;T Mobile Banking App for iPhone

Permalink - Posted on 2010-06-01 00:00

Because I’m totally comfortable with allowing the phone company with the most contempt for its customers to access my bank account information:

I can’t wait to stop paying these jokers their “subsidy” once the contract ends and my monthly bill doesn’t go down. Need to be able to make phone calls, plain and simple. Why are they even bothering to spend R&D money on this junk? Perhaps they recognized that if they couldn’t force this stuff on their subscribers, they can at least make it available through the App Store. Still doesn’t make any sense.

It’s been suggested by Marco Arment and others that one of the reasons the iPhone isn’t available on Verizon yet is because Apple doesn’t go for allowing the carriers to dictate anything about the device, and Verizon is pretty much #1 at doing just that. I’m curious of any of my VZW-Droid-owning friends can elaborate on whether this is currently the case for them? Are there apps on there you don’t want and can’t delete?

Re: Apps that work together – on iPad

Permalink - Posted on 2010-05-27 00:00

Brent Simmons lays out the case for setting up a sort of gentlemen’s agreement between iPhone OS developers, or at least an agreement in behavior for the apps – in order to facilitate inter-app communication. The title of his article refers to iPad, but the concept applies well to all iPhone OS apps, and he asks if his solution is sensible or silly:

But we don’t have an easy way to get back to the calling app. Imagine a hypothetical case like this:

  1. You’re in Twitterrific, looking at a web page, and there’s a link to a feed. You want to subscribe to that feed.
  2. So you choose a “Subscribe in NetNewsWire” command. It opens NetNewsWire and subscribes to the feed.
  3. Now that you’ve done that, you want to get back to your place in Twitterrific. You want it to be exactly as if it never quit.

We can do #1 and #2. It’s #3 that’s tricky.

So I have an idea. It just came to me, so I don’t know if it’s good or bad — but it’s worth posting, at least.

What if the calling app added, as a parameter to the URL, a URL to call when the task is completed?

Seems pretty sensible to me. It would be fantastic for Strip. I’ve been looking for ways to make our password manager more easily accessible from other apps so that it’s easy to take that very round-trip he describes into Strip and back out to another app to either store some data in Strip and go back, or to retrieve some data from Strip to use. It’s pretty easy now, but it could be better, it could just work.

I think Bret’s idea is a really good one, and provides for a lot of flexibility going forward. However, there’s still no way an app could “discover” what other apps are available and what services they provide under this scenario, and that’s really clutch for this sort of thing, for providing a button like “Fire a flame thrower in NetNewsWire” and knowing that it will in fact launch NetNewsWire and run some fictional “Fire a flame thrower” command.

Maybe apps should broadcast their services over Bonjour to the localhost? Right there we already have a very solid model for advertising and discovering “services,” although it doesn’t quite lend itself to application switching. And on iPhone OS 3 and lower, no application that isn’t running could advertise a service in the background.

In iPhone OS 4, that will no longer be the case, it would seem. Perhaps one could just run a bonjour advertisement for a service in the background in an NSOperationQueue? What an awful kludge that would be. I don’t understand why this isn’t a basic feature of iPhone OS 3 already.

New Website for Strip

Permalink - Posted on 2010-05-26 00:00

We’ve put a little bit of extra elbow grease into our web presence over the last couple of weeks, and as part of that effort, we launched a new website just for Strip last night: getstrip.com.

That gorgeous design is the work of Mr. Johnny Bilotta.

We expect this will serve customers of Strip quite a lot better than the old sub-page on zetetic.net, it makes it a lot easier to find information about the program itself, and there’s a ton of documentation on there. We’ve redirected/rewritten all old links to the new site, let us know if you see any broken ones. And let us know what you think!

Thanks to Johnny, Bret Morgan of DBL Systems who helped me hack out all the wiring, and the rest of the Zetetic Team (Don Quander, Steve Kradel, SJ-Lo) for doing such a great job and providing great feedback.

One of the nifty things about this site is that we decided to forgo any kind of webapp or content management system, and instead built a completely static site using HAML, SASS and staticmatic. We thought it worked out so well that we’re doing the same for zetetic.net at the moment, and moving off of Radiant. We had a good run with Radiant, but upgrades have been extremely painful and it’s really easy to break the site. We like kicking it in a text editor and using Git to manage our static content, much nicer than having it all in a database. As for the blog itself, we’re building ourselves a fresh Rails 3 app to hone our chops for upcoming upgrades.

Building SQLCipher with QT

Permalink - Posted on 2010-05-26 00:00

Russian developer Igor Bogomolov put together a fantastic tutorial for building SQLCipher with QT in Russian, and it translates really quite well into English via Google Translate. That’s really quite remarkable.

Thanks again, Igor!

Updated: openssl-xcode and billymeltdown-choctop

Permalink - Posted on 2010-05-20 00:00

Stephen has updated the openssl-xcode project to support building OpenSSL 1.0.0. We’re not entirely sure why, but the make process was attempting to use x86 assembler on non-x86 architectures (ppc, armv6, etc), so we updated the build script in the Xcode project to do the right thing by setting certain flags based on architectures. Works like a charm, now.

This was tested with Xcode 3.2 and OpenSSL 1.1.0 only, results may vary with different versions of either. You can grab the latest by pulling from the master branch.

I’ve updated our fork of the fantastic choctop Ruby gem, which we use to automate release builds for Mac OS X apps. The recent change adds a “codesign_identity” accessor. Set this to the name of your code signing identity and the gem will sign the target app bundle right before it builds the DMG. My fork can be found and forked here on Github, but to install you can pull it from Gemcutter, the name of the gem is billymeltdown-choctop, e.g.:

gem install billymeltdown-choctop

Then you can require it in your Rakefile like so:

gem 'billymeltdown-choctop'
require "choctop"

Example Rakefile:

ChocTop.new do |s|
s.build_opts = '-sdk macosx10.5'
s.codesign_identity = 'Zetetic LLC'
s.remote_dir = '/www/zetetic.net/current/public/files/strip-sync'
s.base_url = "http://www.zetetic.net/files/strip-sync"
s.build_products = "/Users/wgray/Documents/Sources/xcode-build/Release"
s.transport = :rsync
s.rsync_args = '-vazxS --delete -e "/usr/bin/ssh -p 11122" '
# ...

My fork has been modified from the original in numerous small ways because I had to get it working on OS X 10.5, and then 10.6. Caveat emptor.

Pretty Page Title in Rails 3

Permalink - Posted on 2010-05-18 00:00

Ryan Bates has an incredible video tutorial series called Railscasts. They’re really fantastic, and the recent ones focusing on Rails 3 development are invaluable to someone like me who’s playing catch-up, having been in iPhone SDK land for what seems like the last six months.

In any event, he posted this nice trick a while back, called Pretty Page Title. You can watch the railscast for all the details, but the basics of it are a means to set a default bit of content in your layout, and override it from a particular page view. The most obvious example is the HTML title element, but we also need it for things like page description, keywords, other meta content. Here’s what the code looks like:

# application_helper.rb
def title(page_title)
content_for(:title) { page_title }

<!-- layouts/application.rhtml -->
<title>Shoppery - <%= yield(:title) || "The Place to Buy Stuff" %></title>

The crux of the trick is the || operator. If yield returns some value evaluating to false (such as nil), “The Place to Buy Stuff” becomes the content. This is important because it means in a particular view page file, you could over-ride this. Pretty handy for product pages or individual blog posts!

<!-- show.html.haml -->
- page_title(@article.title)
= render @article

This trick no longer works, because content_for returns a blank string when no content has been supplied. I’m not sure when it stopped returning nil, but that’s the case, and I suspect it’s a Rails 3 thing.

In the spirit of giving back (and because I needed it), I hacked up an alternative that’s working pretty nicely for us on a new project (replacing our blog in Radiant with a custom Rails 3 blog). The idea is to check content_for for any content in a helper method and return default content if it’s blank. Here it is as a Github gist, hopefully this loads nicely:

This works because content_for acts as a kind of accessor (both get and set) for the content you pass to it. No need for yield! Which is good, because if you try to call yield inside the helper method, you’ll be treated to the actual Ruby yield, which won’t look kindly on your symbol ;-)

Strip Sync beta Update / Strip v1.4

Permalink - Posted on 2010-05-08 00:00

Updated: 6/6/2012 This blog post is out of date, and the software referenced in it, Strip Sync, has been discontinued in favor of Strip for Windows and Strip for OS X.

The beta test is moving along pretty nicely. If you haven’t been sent any files or updates just yet, but you’ve already opted to participate, don’t worry, we’ll hook you up soon! At the moment we’ve got a loose target date of June 1st for general release, although we don’t really know exactly how long it will take for the newest version of Strip to appear in the App Store after we submit it.

The most recent update to Strip Sync is that we’re now supporting bulk updating of existing Entries during the CSV Import process. Simply use the Export feature to dump out a CSV of all your entries, and you’ll see a new column called “EntryID”. This contains what is basically a GUID for each entry, and if you include these rows in an import, the data in the row will cause the entry to be updated. Original CSV spec post has been updated to reflect this.

We’ve also made numerous improvements to the display, work-flow, responsiveness, and memory usage of Strip running on iPhone OS. Even if you don’t want the new Sync features, the improved layout of field labels and data values is so much better, and much easier to read. We’ve finally added a much easier to utilize Copy function for each field on display (no need to drop into edit mode anymore just to copy a password), and similarly for launching applications with a particular piece of data stored in Strip, and this really makes the program a lot easier to use for everyday look-ups.

For instance, you might want to log into your insurance website account. You open up the insurance entry, you see the password row, you just tap it, and a Copy menu comes up, allowing you to copy the password to the system’s “Pasteboard:”

From here, you just want to go to the website so you can use that password:

And if you’re a sysadmin, with perhaps Touch Term installed on your iPhone or iPad (or some other SSH terminal program), you can just use the ssh:// URL scheme (or any other URL scheme) to do your thing. Here’s a similar scenario, involving some system credentials:

Copy the password for use in the next program:

Now fire up an SSH application:

And the password textfield in this other app (not Strip) allows us to paste the secret password from our clipboard.

An ironic twist: something I did in the most recent beta build of Strip causes this to dial the Phone instead of launching the SSH app, will have a fixed build out early next week, I expect.

SQLCipher Performance and SQLCipherSpeed

Permalink - Posted on 2010-05-07 00:00

Recently, we had a query on the the SQLCipher Users’ mailing list inquiring about the performance of a LIKE query, where the user was wondering if SQLCipher’s encryption engine was responsible for poor performance he was seeing in his code. “It depends,” is the cheapest and most accurate answer we could give without seeing his query and the EXPLAIN plan generated by SQLite (no index, for instance, could lead to a full table scan, thus requiring every page to be decrypted). What we do know is that performance of SQLCipher compared to SQLite is really pretty good, and certainly good enough for our needs as application developers.

If you’ve been wondering what kind of performance hit you can expect using SQLCipher as compared to vanilla-SQLite, we’ve published a new tool to help you get an idea. In the end, EXPLAIN and EXPLAIN QUERY PLAN cannot be replaced, but for a quick side-by-side reference to see that we’ve done a half-decent job, check out Stephen’s SQLCipherSpeed. It’s an iPhone OS project that rips through the various SQLite speed tests. I ran it on my crunky iPhone 3G and the results were about what I expected, and pretty interesting:

In this next one, note that there is no performance impact for 2500 selects on an index.

You’re highly encourage to check out the code yourself, and to fork it. It would be really cool if someone added an action button to the results screen to email the data off-device. More tests wouldn’t hurt either.

Some Quick Notes from Virginia

Permalink - Posted on 2010-04-10 00:00

I’m still at the RubyNation conference, and it’s going really well. Fantastic conference, really, with a huge presence and backing from Engine Yard. Kudos to all involved, my brain is Chock full of Goodness. Dave Thomas’ keynote was excellent, and all the talks I’ve attended have been exceptional. I’ve also had the pleasure of making the acquaintance of many of the speakers and numerous Ruby and Rails Ur-hackers.

In any event, it’s the break just after lunch on day two and I’m giving my brain a code break. Sitting in the sunshine, just inside the lobby, I’m listening to my friends’ new and unreleased album, tapping out a review on my iPhone. Specifically, iPod app is on in the background and I’m tapping away in our new app Codebook, because I like to keep my stupider/unrefined writings really private, and it beats the pants off using Apple’s Notes app.

I think that’s a good measure of whether or not your software is any good! If you don’t use it, why should anybody else?

Active development continues unabated here at Team Z, for those keeping track. An update to Strip Sync for Mac beta will be pushed soon, allows for bulk loading/editing of existing entries via CSV. I think this is the last thing currently missing piece for this utility app.

I’m finding that certain network / sleep events are causing Strip Sync to dump core. Still working out what’s going on there.

Strip Sync for Windows is on the way! Sit tight, we’ll be in touch soon.

Back to the conference. Enjoy the beautiful weather this weekend, temperatures should be up tomorrow ;-)

How Strip Sync CSV Import Works (beta)

Permalink - Posted on 2010-03-25 00:00

Updated: 6/6/2012 This blog post is out of date, and the software referenced in it, Strip Sync, has been discontinued in favor of Strip for Windows and Strip for OS X. For more information on our data import format, please see this newer blog post.

As mentioned here previously, we’re on the cusp of starting the beta test of Strip Sync, our new desktop companion tool for Strip. Among the application’s features are CSV import and export. The intent of this article is to describe the format used on export and required on import. This format is subject to change, but it won’t be changing much. Any changes will be announced here on this blog and noted as updates at the end of this article.

The General Gist

Each row in the CSV corresponds to an Entry in your Strip database. There’s a field indicating what Category the Entry belongs in, the name of the Entry, and every other column is considered a Field. The import process creates a new Entry for each row in the CSV file after the header row. Note: Bulk updating is now supported on SSM, requires use of EntryID column. Bulk updating will be made available soon in Strip Sync for Windows (SSW).

This is what a sample import CSV might look like:

Credit Card,Financial,3759 876613 21001,,"exp:12/12
Insurance Policy,Financial,3759 876613 21001,,secret: name of your first pet? spot,secret,1-800-123-4567,4,,mscott,http://myinsurance.com
jordie laforge,trekkers,,,,,,,nextgeneration|deep space nine,,
kirk,trekkers,,,,,,,star trek,,
patrick stewart,trekkers,,,,,,,star trek|next\|generation|voyager,,
Shopping Website,Personal,,mscott@mailinator.com,,secret,,,,,http://paypal.com

Header Row Required

Just like the subtitle says, a header row is currently required to describe the data in the spreadsheet you’re importing for Strip.

Header Specification

  • One column must be named “Entry”, and this is case-insensitive.
  • One column must be named “Category”, and this is also case-insensitive.
  • The name of every other column (for now) is considered the name of a Field.
  • No columns should be named “Guid”… Guid is no longer a restricted name.
  • One column may be named “EntryID” on SSM, making the row an update to an existing record.

When Strip Sync reads the header row of your import file, it looks up each Field name in your database to see if there’s already a label/type associated with it. If not, a Field with this label is created for you in your database, with the default mode set to “text”, and you can simply change this setting to URL or whatever you like by editing your labels in Strip.

When a row contains an EntryID, Strip Sync looks up the Entry in your database and replaces it’s name, category, and fields using the data in the rest of the row.

Bulk Updating

To do bulk updates via CSV import, you need to get the unique identifiers for your entries! Simply use the export feature of Strip Sync to export a CSV file containing all records in your database, with their EntryIDs.

Row Processing

During import, after the header row has been read, Strip Sync begins cranking through all the other rows, creating new Entries using the data in each row (bulk update via CSV import is not supported yet, but we plan to support that soon). Here’s how it works:

  • Strip Sync looks at the Category field and does a case-sensitive lookup to find a matching Category in your database. If no match is found, a new Category with this name is created.
  • The Entry column is used as the name of the new Entry, as indicated above.
  • For each additional column in the row:
    • If the column is empty, it is ignored
    • If the column is not empty, a Field is created on the Entry, with a type/label corresponding to the column’s header name.
    • Field columns may contain multiple values, separated by the ‘pipe’ character, ‘|’. If multiple values are detected, multiple Fields will be created on the Entry, labeled according to the column’s header name.
    • If your Field needs to contain a pipe character as part of the Field value, you may escape it with a backslash character (i.e. ‘\|’).
  • If an Entry or Category column is blank, the entire import will be rolled back, and an error message will display detailing the problem and the line number where the problem was found.

Our import and CSV processing is based on the scanning technique and EBNF outlined by Matt Gallagher to fully support properly escaped CSV data.

If one were to extend that EBNF definition to take into account our use of | to separate multiple field values, we think it would look like this:

file = [header lineSeparator] record {lineSeparator record}
header = name {separator name}
record = field {separator field}
name = field
field = escaped | nonEscaped
escaped = doubleQuote {innerField | separator | lineSeparator | twoDoubleQuotes} doubleQuote
nonEscaped = innerField
doubleQuote = '"'
twoDoubleQuotes = '""'
separator = ','
lineSeparator = ('\r' | '\n') {'\r' | '\n'}
innerField = textData { innerFieldSeparator | textData }
innerFieldSeparator = '|'
textData = {characters up to the next double quote character, un-escaped innerFieldseparator, separator string, or lineSeparator}

Obviously, commentary and corrections are welcome (as well as bug reports).


Tempo Updates: Tagging, Status, UI tweaks

Permalink - Posted on 2010-03-24 00:00

Last night I pushed a couple of updates out to our Tempo time tracking service that were a touch over-due:

  • Tweaked date field on time entry to fix text-obscuring problem
  • Tweaked order receipt for providing copies of past invoices
  • Improved navigation and visibility for Team → Status
  • Fixed display margins in module boxes site-wide
  • Adds a “add new user” link in project team settings for convenience
  • Allows meta-characters in tags, no longer restricted to [A-z0-9-_]

The tags thing was getting annoying, I will admit. It’s pretty useful to be able to, for instance, begin certain tags with a * character to mark them as project defaults.

The Team Status thing was a visibility issue. I think most administrators and managers of Tempo accounts were unaware that in addition to the basic Team view (a simple list of your users), there’s a Status view indicating who is working on what:

Aaaaand it even has a handy mobile view that you could bookmark:

If you notice any bugs, or there’s anything bothering you about the system, please get in touch.

In Search of a Pragmatic Programmer

Permalink - Posted on 2010-03-23 00:00

We’ve been really busy here at Zetetic lately and we’re looking for a new teammate to help us develop and support client systems and our own products. As a small and flexible software development consultancy, we’re mostly interested in personal qualities, not resume buzzwords:

  1. Natural or Artificial intelligence (robots welcome)
  2. Intense desire to learn new things & hack on technology
  3. An unflappably positive attitude
  4. Plays well with others

A background in one or more of the following goes a long way too!

  • Strength in at least one Object Oriented Programming Language (C#, Ruby, Java, Obj-c). Anything except VB.
  • Desire to “switch things up” and work on multiple programming languages
  • Experience with databases, relational SQL, or otherwise (mongo, couch, etc)
  • Security Technology (i.e LDAP authentication, Single Sign-on, PKI)
  • Linux and general networking
  • 2-5 years of software development experience
  • Located in Philadelphia, NYC, or Central NJ to allow collaborative work with our current team members

In short, we mostly care that you’re smart, love to hack, and get things done.

If this sounds like you, or someone you know, please reach out and let us know: sjlombardo@zetetic.net.

Strip Sync Screens

Permalink - Posted on 2010-03-20 00:00

Updated: 6/6/2012 This blog post is out of date, and the software referenced in it, Strip Sync, has been discontinued in favor of Strip for Windows and Strip for OS X.

I have a couple small things to fix still, but we’re planning to start the beta for Strip Sync next week. We’ve been getting a lot of “where is it!?!” emails, so we thought it’d be a good idea to post some screens and show you that it’s not vaporware. I’m heading development on the Mac side, so I’ll show you screens from Mac OS X. You’ll get a look at the .NET version for Windows soon.

When you start up the Strip Sync application, it is locked, and requires you to enter your access password:

On first-time start-up, it will ask you to set a password for the local database replica. I should note that, at least for the time being, the password on your desktop database must match that of your iPhone database. Still gotta work out nicely paginated printing, and to be honest I’m not sure it’s necessary. Will probably be left out on initial release, as anybody can export to CSV and print that, and stick it in a safe.

Once you’re in, you’ll see the main utility window:

One of the key features here, Import, can be fired off pretty easily to import Strip CSV data (more on that in a later post, I have an EBNF that I need to clean up for programmers):

Then, you fire up the iPhone version, select the Sync tab, browse for your desktop on the local network, and begin the sync operation:

Those other buttons on the select switch indicate performing a restore from your desktop, and performing an authoritative override of what’s on the desktop. Once we’ve chosen the desktop we wish to sync with, we go for it (click to embiggen):

Here we can see that a new category called “trekkers” has been added:

And we can also see that the data import supports multiple values for field types on an entry:

The reason this worked is because they were delimited by a | character in the CSV data shown above. It can be escaped with a backspace. Like I said above, more on the import format later. Obviously, my Trek knowledge above is bogus, just needed some data.

Ruby Nation / Best Practices

Permalink - Posted on 2010-03-19 00:00

I’ll be attending this year’s Ruby Nation conference in Reston, VA April 9-10, and I’m quite looking forward to it. The list of speakers and talks is absolutely fantastic, and includes the excellent Nick Sieger, whom I had the pleasure of first meeting at Ruby Fringe in 2008. There are still a couple of open registration seats left if you haven’t signed up yet. If any of the Ruby heads out there want to meet up, I’ll be in town from the evening of April 8th to the morning of April 11th. You can find me on Twitter as @billymeltdown.

I’ve been spending a little time revisiting some of the core concepts and industry practices with Ruby, and recently Bret Morgan of DBL Systems pointed me in the direction of Gregory Brown’s newly published book, Ruby Best Practices. The first chapter alone is excellent, a kind of sermon for Test-Driven Development, and I highly recommend it.

Saying Goodbye to PingMe

Permalink - Posted on 2010-03-18 00:00

We have some sad news to deliver to users of the PingMe reminder service. Starting today, we will be blocking new registrations on PingMe, and we have decided to turn off the system permanently starting on April 23rd.

So long, and thanks for all the fish

We believe in working on projects that are sustainable. When we built PingMe, we had very high hopes for it. It was designed from the ground up as a system that was more dynamic and flexible than anything else out there.

We have maintained PingMe for free for as long as possible for all the people that have been depending on it. We love to get email from people who have found the service to be an enormous help in their lives, and it’s partly a sense of responsibility to them that has helped us to keep it up.

Unfortunately, it’s just not a sustainable service in the long-term for several reasons:

  1. PingMe requires continuous maintenance and constant vigilance against abuse by spammers, malicious users, and even inadvertent mistakes. Recently, direct and accidental system abuse cases have been on the rise, to the point that we have almost daily incidents to deal with.
  2. PingMe is a difficult system to support, because of various problems with external SMS gateway providers, cellphone carriers, and email systems. These issues are mostly out of our control, and make it difficult or impossible to troubleshoot and resolve even common problems.
  3. Despite the fact that PingMe is widely used and well liked, it hasn’t grown to the point where we can monetize it or effectively compete with other systems.
  4. We’re a small team, and maintaining PingMe has become an undue burden on other projects that we have brought to market

Switching to Another System

There are plenty of other reminder systems and task managers out there. Each has their own way of doing things. While we can’t recommend any particular system, we encourage you to try out a few and see what else you like.

In order to help you get your data out of PingMe, we’ve added an export feature so you download an Excel/CSV or XML-formatted export of your reminders. We’ve also posted a reference guide to the export data here on our blog.

What does this mean for Zetetic and your other products?

PingMe is the only system we are shutting down. Tempo Time Tracking, Strip Password Manager, Codebook Secure Notepad, etc, will be completely unaffected. We are doing very well as a company, continuing to grow, and approaching our 6th year in business. In fact, the most important reason we are turning off PingMe is so that we can continue to give proper focus to our other products and services.

Thank you

Finally, we want to say thanks to all of our PingMe users for trying the service, providing feedback along the way, and helping to spread the word. We really appreciate it and sincerely apologize for any inconvenience this may cause.

Exporting Reminders From PingMe

Permalink - Posted on 2010-03-18 00:00

Last night we made a small update to the PingMe reminder service to make it possible for you to export a listing of your reminders, should you decide you’d like to switch to another service. If you click on the Profile Tab, you will see an “Export” section at the top of the page:

The export options are straightforward, but I want to describe the CSV and XML formatted output and describe what exactly each of the fields describes, to help anybody looking to massage the data for another system.

CSV Output

CSV (comma separated value) output is suitable for opening in a Spreadsheet program like excel, but it can also be opened with any standard text reader. Field data will be correctly escaped when necessary according to the CSV spec (for instance, when a field contains a comma, line-break, or quote character). The data is UTF8-encoded (not ASCII), but if you try to open the file directly in Microsoft Excel, it may munge the UTF8 characters that extend beyond the ASCII set. Other spreadsheet programs should be able to handle this for you, and help you convert into an actual Excel workbook.

Here’s some example output, with a header row:

172,false,false,22-Jul-2008 17:34,22-Jul-2008 17:34,true,false,check check,22-Jul-2008 17:45,one-time,daily,false,Gmail,0,"",Billy

XML Output

This will produce an valid UTF8-encoded XML document. The root element is <pings type="array" />, and it contains, you guessed it, a list of pings as XML! Type-hinting attributes are turned on, but should be easy to ignore. This is what it generally looks like:

<pings type="array">
<created-at type="datetime">2008-07-22T17:34:04Z</created-at>
<id type="integer">172</id>
<is-active type="boolean">true</is-active>
<is-done type="boolean">false</is-done>
<is-recurring type="boolean">false</is-recurring>
<message>check check</message>
<require-confirmation type="boolean">false</require-confirmation>
<updated-at type="datetime">2008-07-22T17:34:10Z</updated-at>
<is-pestering type="boolean">false</is-pestering>
<pester-interval type="integer">0</pester-interval>
<start-date type="datetime">2008-07-22T17:45:00Z</start-date>

Export Field Guide

created_at – Creation timestamp. Excel format used in CSV output. All timestamps are in UTC.

id – The unique integer identifier of the ping. There are many others like it, this one is yours!

is_active – Boolean determining whether the ping is still “active” in the system. This is only really set to false by the system, not the end-user.

is_done – Whether the ping has been marked by the user as “done”. You can interpret is_active = false and is_done = true to mean the same thing.

is_pestering – Boolean indicating whether or not the reminder is supposed to bug you at a particular interval until you respond.

is_recurring – Determines whether the ping will be rescheduled after it sent at it’s start_date.

message – The contents of the reminder itself

pester-interval – The interval in seconds that a ping should be re-sent until a response is received from the user. Only valid if is_pestering == true.

recurring-frequency – The schedule to be used when is_recurring == true. Can be:

  • daily
  • weekly
  • monthly
  • yearly
  • biweekly
  • mon-fri
  • quarterly

require_confirmation – Boolean setting that, when true, makes the ping a kind of “to-do.” Normally, if a ping has been sent at it’s scheduled time, and it’s not up for rescheduling, it is marked as “done” by the system. However, if require_confirmation is set to true by the user, the ping will not be marked “done” until the user replies to confirm that the task has been completed. This causes the ping to stay on your homepage on PingMe, instead of being archived.

schedule_type – Convenience text describing what kind of ping this is: pestering, repeating, or one-time. Pings that are combined pester-repeat pings are simply marked as “pestering”, so you may wish to consult is_pestering and is_recurring directly.

start_date – The date at which the ping should be scheduled for delivery.

tag_s (tags in CSV output) – A comma-separated list of tags assigned to this ping.

targets_s (targets in CSV output) – A comma-separated list of the targets assigned to this ping (names only).

updated_at – Timestamp indicating when this ping was last modified, by the user or the system scheduler.

users_s (users in CSV output) – A comma-separated list of the users this ping was assigned to, listed by login name. This exists because pings can be shared with more than one user.

Codebook is in the App Store!

Permalink - Posted on 2010-03-17 00:00

Time for a little business, friends! We have a new application in the iTunes App Store, and we call it Codebook: A Secure iPhone Notebook for People with Secrets!

Download it now in the iTunes App Store for only $2.99.

My bias being what it is, I recommend that you replace your other notes apps with this elegantly simple notebook that keeps all your data private, and just gets out of the way. Codebook is perfect for attorneys, physicians, journalists — anybody who needs to keep their notes confidential.

Codebook is built on the same rock-solid encryption engine we use for STRIP, SQLCipher. It’s perfect for storing sensitive meeting notes, terrible poetry, anything you want to keep secret should you lose your iPhone or iPod Touch. ALL data stored in Codebook is stored using the robust and peer-reviewed 256-bit AES encryption implementation in OpenSSL.

I used to use Apple’s included Notes application a lot myself, but I’m getting less and less comfortable storing stuff in there. Here’s my use-case, since I’ve been using Codebook for a few months now:

I, for one, have a penchant for thinking up lots of bad “lyrics” for my band. I’ll be on the subway reading some radical article in Harper’s, and BOOM, I get this great idea! I fire up Codebook, tap in my password real quick, and tap out my idea. If I want to add it to a previous bit of my wondrous witticisms, they’re incredibly easy to find via the Search feature, or just by going back in time and scanning the titles.

It may not be totally evident in the screens here, but we opted to use the first line of each note as its title (an idea we got from John Gruber’s writings about the untitled document syndrome, and the Simplenote app), so you don’t have to think of one. It’s just there, it just works.

One last thing we made sure we included: Email forwarding of individual notes. You just might want to mail something out and we wanted to make that easy to do.

Stephen and I started work on this back in February of 2009, and have basically sat on it since while we put priority on Strip. Recently, I took some time to clean it up and get it ready for a proper release. Feels good to finally have it out there in the store. If you give Codebook a spin, let us know what you think!

Hold and Copy in UIKit

Permalink - Posted on 2010-02-24 00:00

This article has been cross-posted at MobileOrchard.com, our favorite place to get news and tips about iPhone/iPad development.

Recently, I wanted to implement an interface where a user holds down on a UIView class or subclass to reveal a copy menu. Basically, I didn’t want to have to present the user with a UITextField just to provide the ability to copy some data to the pasteboard. In this case, I’m working with a UILabel, but a similar paradigm already exists in many Apple-supplied apps where one can hold down on an image and be presented with the Copy menu option.

Going in it seemed pretty straight-forward, but it ended up taking me the better part of an afternoon of trial and error alongside the Event Handling section of iPhone Application Programming Guide to work it all out, so I believe a tutorial is in order. A reference project with sample code is available on Github.

Getting a Hold of a Hold

One can easily calculate the length of time a touch was held when the touch ends (by calculating the difference between the timestamp properties of the passed UIEvent and UITouch objects), but I found making this the point of responding to the event less than ideal because it means responding to the user’s interaction after the user lifts her finger, rather than while she is holding down on the screen. I’d rather respond while the user is still holding her finger down to let her know that the instruction was received. If the software will only respond after the user lifts her finger, she has no idea how long she has to hold her finger down, which is a nuisance, really.

Old Cocoa pros and experienced UIKitters probably saw the solution from a mile away: we intercept the touches began event for the view we’re interested in, and tell some object to do something after a long enough delay (the minimum time we want a user to have to hold to do something). We then cancel the request if any of the other touch events fire before our delay hits. That looks something like this, depending on your needs:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *t = [touches anyObject];
if ([t locationInView:someViewWeAreInterestedIn])
[self performSelector:@selector(showMenu) withObject:nil afterDelay:0.8f];

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showMenu) object:nil];

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showMenu) object:nil];

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showMenu) object:nil];

There may be better ways to do this, but this seems pretty solid. In the sample code you can see this at work in the view controller, which shows a hidden image once a user holds down on another image for long enough. Just under a second (0.8s) seemed to feel right to me.

- (void)holdingView:(id)view {
[hiddenView setHidden:NO];

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *imageTouches = [event touchesForView:imageView];
if ([imageTouches count] > 0) {
[self performSelector:@selector(holdingView:) withObject:imageView afterDelay:0.8f];
[super touchesBegan:touches withEvent:event];

Implementing a Custom Copy

I feel like there’s real pun-potential for this subtitle, but reasonably groan-inducing text is eluding me. In any event, now that we can detect when a user has held our view long enough to warrant a response, we need to make a move: presenting the UIMenuController with the Copy option and actually copying something in response. I’m sure there are various approaches that can be taken, but my approach was to start by subclassing UILabel, curious to hear other ideas.

First, I wired the subclass to intercept touch events, and to save that touch-down for the extra point (ho!):

- (BOOL)canBecomeFirstResponder {
return YES;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if ([self canBecomeFirstResponder]) {
[self becomeFirstResponder];
UITouch *t = [touches anyObject];
holdPoint = [t locationInView:self];
[self performSelector:@selector(showMenu) withObject:nil afterDelay:0.8f];

// (other touches* methods implemented to cancel perform) ...

Showing the menu itself is a touch awkward, you need to provide a “target rectangle” (CGRect) to UIMenuController to tell it about where on the screen you want the menu to appear (it can appear above or below this point, depending on proximity to the screen bounds).

- (void)showMenu {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(reset) name:UIMenuControllerWillHideMenuNotification object:nil];

// bring up editing menu.
UIMenuController *theMenu = [UIMenuController sharedMenuController];
CGRect myFrame = [[self superview] frame];
CGRect selectionRect = CGRectMake(holdPoint.x, myFrame.origin.y - 12.0, 0, 0);

[self setNeedsDisplayInRect:selectionRect];
[theMenu setTargetRect:selectionRect inView:self];
[theMenu setMenuVisible:YES animated:YES];

// do a bit of highlighting to clarify what will be copied, specifically
_bgColor = [self backgroundColor];
[_bgColor retain];
[self setBackgroundColor:[UIColor blackColor]];

Note that I’m registering for a notification: I basically wanted to know whenever the menu disappeared, because that would mean it’s time to stop high-lighting the text in the label, and restore the original background color. Totally not required for getting the menu on screen.

Next we have to make it clear to the UIMenuController that we mean serious business, and what kind of business we intend to conduct. In my case, I was only interested in Copy, but other options are available:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
BOOL answer = NO;

if (action == @selector(copy:))
answer = YES;

return answer;

And in my case, the data I’m looking to copy is simply the text of the label itself, and I just want to put it on the general pasteboard so the user can paste it into another app, or wherever:

- (void)copy:(id)sender {
UIPasteboard *gpBoard = [UIPasteboard generalPasteboard];
[gpBoard setValue:[self text] forPasteboardType:@"public.utf8-plain-text"];

That’s it!

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Link: Intercepting UITableView Touches

Permalink - Posted on 2010-02-19 00:00

Recently I did some digging into how I could customize the response of UITableView to touch events. Mostly, I wanted the touch to be forwarded on to a sub-view I’d stuck on a UITableViewCell, which is a tricky and somewhat quixotic journey that I think every iPhone app developer needs to make. In the end, I decided I didn’t like the functionality I was implementing, but on the way I found a great tutorial by app developer John Griffiths on how to get there.

Building Static Libraries to Share Code on iPhone AND Mac OS X Projects

Permalink - Posted on 2010-02-15 00:00

There are numerous good resources out there, like Clint Harris’ excellent tutorial, that describe how one can share common code across iPhone projects by keeping the shared code in a separate project, and including it in your various projects using the cross-project reference technique. The technique is further complicated due to the need to use static libraries for iPhone projects, as dynamic libraries are not allowed by Apple in iPhone apps.

Despite the nuisance, the technique works pretty well, and we’ve been using it as detailed here on Mobile Orchard for building OpenSSL and SQLCipher for iPhone projects. However, recently we started sharing a lot of our SQLCipher-specific code (like our custom data model, etc) with our upcoming Mac OS X application, Strip Sync. Therefore, numerous libraries we were sharing were linked against our openssl-xcode build, which is necessarily a little customized. Using the shared library there worked great for development (“Debug”) builds, but came to a screeching halt once it came time to do a “Release” build.

The Release build process sets up a universal binary. Thus, using the common technique described above, the linker ends up trying to link a PPC build of your binary against our static openssl library, which was only building either i386, or ARMv6. If you are using the code and instructions we described in our SQLCipher tutorial to use SQLCipher in your iPhone project, and you decide to use that technique for a Mac OS X project, this problem will affect you (if you are building the standard universal binary on release builds).

Happily, we’ve got a fix! Once we realized what was going on, I mentioned it to Stephen, who put together our handy openssl-xcode project, that provides you a drop-in way of setting up the static library for iPhone development. In a few minutes he hooked up a new version of the Run Script build phase that sets up the static library to do the usual for iPhone builds, but to detect a universal binary build and do the right thing:


if [ "$SDKROOT" != "" ]; then

## this is a universal build
if [ "$ARCHS_STANDARD_32_BIT" = "i386 ppc" ]; then

mkdir -p temp-universal

make clean
./config -openssldir="$BUILD_DIR"
cp libcrypto.a temp-universal/$BUILDARCH-libcrypto.a
cp libssl.a temp-universal/$BUILDARCH-libssl.a

make clean
./config -openssldir="$BUILD_DIR"
cp libcrypto.a temp-universal/$BUILDARCH-libcrypto.a
cp libssl.a temp-universal/$BUILDARCH-libssl.a

lipo -create temp-universal/*-libcrypto.a -output libcrypto.a
lipo -create temp-universal/*-libssl.a -output libssl.a
echo "***** BUILDING ARCH $BUILDARCH ******"
make clean
./config -openssldir="$BUILD_DIR"

ranlib libcrypto.a
ranlib libssl.a
cp libcrypto.a libssl.a "$BUILT_PRODUCTS_DIR"
exit 0

We’ve updated the Github project with this change, so if you are using this technique and openssl-xcode, you can simply download the latest (or pull from github master), and drag and drop the new project file into your XCode build directory and be off and running.

Again, the previous technique worked just fine for sharing code across iPhone projects, but doing a universal build of the static library is absolutely necessary if you use the same shared code in your Mac OS X project and you try to link it against a universally-built binary.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Encrypted iPhone Applications

Permalink - Posted on 2010-02-06 00:00

It was just over four months ago when we set about learning the iPhone SDK and putting together our first application, a revamp of STRIP, the personal information manager that was so popular for the Palm platform.

Now that we’ve got a mostly-finished product (we’re still making a few tweaks and getting ready to start the beta), we took a step back to look at the code we built to keep the development DRY and enable quick development of future applications. Essentially, we’ve built ourselves a framework for building applications that have a fully-encrypted database layer using SQLCipher, with a robust data model, a login facility, random password generation and seeding, etc.

What took us four months to do at first, now only takes us a few days. Using the code we extracted from STRIP we were able to put together one of our other app ideas in less than four work days. Introducing Codebook, a secure notepad:

Codebook is a LOT like the built-in Notes application on the iPhone. They aren’t exactly the same, but the critical difference is that no one is getting in and reading your notes unless they have your password:

Coming Soon: Strip Sync

Permalink - Posted on 2010-01-30 00:00

Updated: 6/6/2012 This blog post is out of date, and the software referenced in it, Strip Sync, has been discontinued in favor of Strip for Windows and Strip for OS X.

We’ve been getting a ton of mail lately about Strip, mostly along the lines of, “when will the desktop client be ready?” We’ve made a ton of progress over the last few weeks, and we really appreciate the various letters of encouragement and everyone’s enthusiasm.

Strip Sync

We are calling the initial desktop client Strip Sync. It provides some really critical functionality for the Strip platform going forward, and it will be offered for free here on our website. It runs on Mac OS X 10.5 and later, and most modern versions of Windows (although “modern” feels like a weird term, given the leap into the future that seems to be taking place at the moment). It’s really two separate, native applications that provide the same excellent and much-needed features:

  • Import from CSV – with files from Palm Strip Exporter or any other resource.
  • Synchronization with the iPhone – you’ll be able to bring over your old Palm data.
  • Independent back-up – for many people, the iTunes backup just isn’t enough.

At some point soon Strip Sync will also provide handy export and printing capabilities, but we’re really eager to get these much-asked-for features out there already, so export and print may not be introduced in the initial version. We’ll see soon.

We’re about ready to start looking for beta testers, we’ll post a notice here on the blog soon and send out a message to the mailing list. If you’d like to be added to our mailing list, send us an email, or just fill out the form over on the Strip product page.

Once Strip Sync is out the door we’re going to use it as the basis of the full-featured desktop version of Strip, which will allow you to enter and edit your data from the desktop, as opposed to having to slowly tap away with your thumbs on the iPhone.

What About Android?

We’ve been getting a lot of queries asking for a version of Strip for Android, but this one really jumps out:


Years ago, around the turn of the century, I used to work as an
engineer at Palm Digital Media (eBook division of Palm); all of the
devs and admins in our group worshipped your Strip app.

I have recently acquired an Android device (Nexus One). Please release
a version for Android.

Thanks for making one of the most useful applications ever,

We’d really love to do this, I mean, really, love. Right now our hands are a bit full with those two aforementioned native desktop applications! Once we have the desktop component firmly in place, we can begin to explore other platforms like Android, but for now it’s going to have to wait. We do expect to see an explosion of Android devices over the next year or so, and it would be a fantastic addition to the Strip platform.

If you’ve just got to have Strip on your platform of choice, please let us know, we’re listening.

Co-working Open House in Brooklyn 1/29

Permalink - Posted on 2010-01-26 00:00

My co-working space, The Change You Want To See, in North-side Williamsburg, is hosting our monthly open house event this Friday, the 29th of January. Anybody is welcome to drop in our space during normal hours, but our open-house event is a great time to meet other local professionals and free-lancers. People tend to be very focused during the day, and then at 5pm we do our happy hour (“beer o’clock”).

So, if you’re thinking of checking out co-working, or you just want to chew my ear off about one of our products, you’ll be most welcome. Do check the link and add your name if you plan on coming.

Tempo API Mailing List

Permalink - Posted on 2010-01-15 00:00

Our time-tracking service Tempo has an API available (an Application Programming Interface) that allows our customers to integrate their own software with Tempo directly. In the interests of fostering discussion, sharing tips, and providing another vector for making announcements directly to consumers of the API, I’ve created a mailing list on Zed Shaw’s new service Librelist.

To sign up, simply send any old email to: tempo.api@librelist.com

You will receive a confirmation message, and once you are all confirmed, you should be good to go. If you are running code that integrates with our service, or are building something now, I encourage you to join the list and to share with us any difficulties you experience, that we might share knowledge that so often gets trapped in our “support” email box.

That said, if you want to address an issue privately, you’re always welcome to get in touch with us directly.

MTA NYC Transit Opens Data

Permalink - Posted on 2010-01-14 00:00

As a New Yorker and a firm believer in mass transit and open data policies, I am happy to see the big news that came with yesterday’s unveiling of the new MTA website:

The agency’s new policy does away with time-consuming data-sharing procedures and burdensome licensing requirements. As of today, schedule, route and fare information are available directly from the MTA website in a standard format, and the data will be updated whenever service changes. Similar set-ups have allowed developers to create scores of transit applications for cell phones and web browsers in other cities, giving riders convenient access to up-to-date information.

Amen! Visit the new developer access page to sign up for accessing to the MTA’s data. Looking forward to seeing what evolves, as I’m sure that apps like Across Air and Exit Strategy are only the beginning. I’ve come to use Exit Strategy a lot, more often for the built-in Subway map than for the nearest door to the NQRW stairway. Maybe I’m a touch old-skool, but I prefer a well-designed map to the augmented reality thing. Get off my lawn! City Transit apparently provides you with a lot of similar getting-around features, plus service advisories, which is handy.

I’m guessing the developers at iTrans really love dynamic programming, because the shortest-path problem is not an easy one, but they’re not content to leave it up to Google, as their app provides this offline, running its calculations on your phone. I need to give that a shot. This particular app is nice because it provides you further info outside the Subway, like PATH and NJTransit (although how accurate that data can be is questionable, as there has been no sign of opening up coming from either NJTransit or the Port Authority).

Cocoa: SQLCipher Manager Available

Permalink - Posted on 2010-01-06 00:00

We’ve posted a new project to Github: SQLCipher Manager.

I’ve got to make this brief because I have a ton of work to do, but we’ve recently split out a few chunks of re-usable code from our iPhone application Strip in order to facilitate sharing that code across multiple projects, both for the iPhone and for Mac OS X development. Most of that stuff will be staying internal, and wouldn’t be of much use to others anyway, but we decided to make SQLCipher Manager available as open source software under the same MIT-style license as SQLCipher itself.

The project on Github is an XCode project that builds a static library. You can use cross-project references to utilize this code from other XCode projects and to link against the static lib (required by Apple for us iPhone developers). There’s a great reference on doing this over at Mobile Orchard, so I’ll refrain fro going into the process here.

In short, it provides a singleton that handles your database connection to SQLCipher, keying, re-keying, notifying your app when the database has been created or opened, etc. This sounds like a no-brainer, but you end up re-using this code quite a bit, so it only made sense to define it and a delegate protocol:

@protocol SQLCipherManagerDelegate <NSObject>
- (void)didOpenDatabase;
- (void)didCreateDatabase;
- (void)didEncounterRekeyError;
- (void)didEncounterDatabaseError:(NSString *)error;

This means you’d do something like this in your app delegate, to initialize the manager for your application, and handle schema events:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(@"Setting up sqlcipher manager, and ourself as delegate...");
// setup the db manager register as the delegate
SQLCipherManager *dm = [SQLCipherManager sharedManager];
[dm setDelegate:self];
// set the databasePath property (required), use default iphone app documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [paths objectAtIndex:0];
NSString *databasePath = [saveDirectory stringByAppendingPathComponent:CONFIG_DBNAME];
NSLog(@"setting db path to %@", databasePath);
[dm setDatabasePath:databasePath];

[self launchLoginView];

# pragma mark -
# pragma mark SQLCipherManagerDelegate

- (void)didOpenDatabase {
NSLog(@"Database opened");
SQLCipherManager *dm = [SQLCipherManager sharedManager];
NSUInteger schemaVersion = [dm getSchemaVersion];
if (schemaVersion != CONFIG_SCHEMAVERSION) {
NSLog(@"handing off to schema manager, found old version %d", schemaVersion);
StripSchemaManager *schemaManager = [[StripSchemaManager alloc] initWithSQLCipherManager:dm];
[schemaManager migrate:CONFIG_SCHEMAVERSION];
[schemaManager release];

- (void)didCreateDatabase {
NSLog(@"Database created, migrating");
SQLCipherManager *dm = [SQLCipherManager sharedManager];
StripSchemaManager *schemaManager = [[StripSchemaManager alloc] initWithSQLCipherManager:dm];
[schemaManager migrate:CONFIG_SCHEMAVERSION];

- (void)didEncounterDatabaseError:(NSString *)error {
NSLog(@"Database error! %@", error);
SQLCipherManager *dm = [SQLCipherManager sharedManager];
[dm closeDatabase];
abort(); // ouch, yo, but it leaves us a crash log for later

- (void)didEncounterRekeyError {
[self lockApplication];
[self presentError:[NSError errorUsingDatabase:@"An error occured rekeying the database. Please login again using your original password" reason:@""]];

Your login view controller (or whatever you are passing control to as the application sets up) would actually do the opening, or creating, of the database. Ours looks something like this:

- (IBAction)submit {
SQLCipherManager *dm = [SQLCipherManager sharedManager];
BOOL databaseExists = [dm databaseExists];

// just bail if the submitted password is invalid
if (![dm passwordIsValid:passwordField.text]) {
errorLabel.text = @"Invalid password";
self.passwordConfirm = nil;
passwordField.text = nil;

// if this is the first time through, require confirmation
if(databaseExists == NO && !self.passwordConfirm) {
self.passwordConfirm = passwordField.text;
passwordField.text = nil;
passwordField.placeholder = @"Confirm your password";
[passwordField becomeFirstResponder];

loadingImage.hidden = NO;
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0, true);

// seed OpenSSL RAND (removed)

SecureAppDelegate *appDelegate = (SecureAppDelegate *) [[UIApplication sharedApplication] delegate];
if (databaseExists) { // what mode are we in?
// attempt login, we only have passwordField present on screen
if ([dm openDatabaseWithPassword:passwordField.text]) {
[passwordField resignFirstResponder];
[appDelegate launchAppView]; // push new view controller, etc... wait we have no navigation controller...
} else {
errorLabel.text = @"Incorrect password";
[passwordField becomeFirstResponder];
} else {
if ([self passwordIsConfirmed]) {
[passwordField resignFirstResponder];
[dm createDatabaseWithPassword:passwordField.text];
[appDelegate launchAppView]; // here again we need to get our navigation controller going
} else {
errorLabel.text = @"Passwords didn't match";
[passwordField becomeFirstResponder];
passwordField.placeholder = @"Access password";
self.passwordConfirm = nil; // wipe fields
passwordField.text = nil;
loadingImage.hidden = YES;

Those are the basics of using SQLCipher in a Cocoa Touch application, and the approach is easily ported to Mac OS X. Can’t go into the various details right now, hopefully it’s explanatory enough. Questions should be posed on the SQLCipher-Users mailing list. Bugs and enhancement requests should be filed using the Issues tracker on the Github project.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Announcing the Palm Strip Export Utility

Permalink - Posted on 2009-12-31 00:00


Back in 1997 we released the first version of our mobile password manager and data vault Strip (Secure Tool for Recalling Important Passwords) for PalmOS. It quickly grew to be one of the best and most widely recognized security applications for the platform, gathering accolades from the likes of ZDNet and CNN. A few years ago we dropped support for PalmOS Strip after the decline of the Palm platform. Then, last year, we resurrected Strip by bringing a completely redesigned system to the iPhone sporting a flexible data model and new open-source encrypted database engine.

Yet, many former PalmOS Strip users have let us know that they are still trapped on their old devices, in dire need of a way to export information from their Palm databases. Some people have switched to Strip for iPhone, others just want to back up their information in case of device failure.

Today we are pleased to release a free utility that can export your legacy PalmOS Strip databases out to a simple Comma Separated Value file. Once your databases are exported you can print them, open them in Excel or import them into a separate program. Most importantly, these export files will be directly importable to the iPhone when we release our first Strip desktop sync tool in the coming months.

How To Export

Note: This exporter only works with Palm Strip 1.0 or 2.0 Databases. If you are not running one of these versions you should upgrade first. This utility is not intended for use with the iPhone version of Strip (we will be releasing a iPhone sync package soon that will provide similar functionality).

Start off by downloading the exporter program:

Save the program to your computer and then run it:

  1. Enter the password for your Palm-Strip database. This is the same password you would enter into the program normally.
  2. Click the “Choose Directory” button, and navigate to the location of your Strip Databases. These will usually be in your Palm desktop install folder, usually something like C:\Program Files\palm\<username>\backups.
  3. Click the “Save As” button to choose the location to export the file.
  4. Click the “Export To File” button.

The system will then export your entire database out to a CSV file at the selected location. Your data will be left intact, with the exception that line breaks will be removed from Note fields to allow the export. Open your file in a spreadsheet like Excel or in a text editor like Notepad to verify the results.

Credits & Code

This new exporter tool is based on the pioneering work by David Dribin’s perl-strip, an early exporter for Strip databases. We’ve taken his great Palm::Zetetic::Strip module and forked it on GitHub. Our updates include the use of newer digest libraries and updates to support the full Strip 2.0 database format (including service types). We’ve also released the source to the palm-strip-export application on GitHub.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.


Gone Nomading? Try Coworking

Permalink - Posted on 2009-12-30 00:00

Terralien’s Nathaniel Talbott has an interesting article up on their blog about an activity they’ve termed nomading, or nomadic programming. Basically, Terralien is what you might call a remote company, in that a good number of their people work from geographically distinct locations, often not meeting in person but keeping in touch and coordinating their projects and work over the Internet. We work this way, too, so we’re always interested when other firms write about their experiences.

Talbott’s article is interesting in that Terralien is using this concept of nomading to help mitigate the problem of isolation one can experience remoting:

But no matter how much we appreciate the flexibility of working from wherever, we still often feel the need to spend some time in the same place with fellow geeks. The wife and kids can only take so many explanations of the latest cool hack we pulled off, and a change of scenery can really help get the creative juices flowing. As with so many other remote workers, we started heading out to a coffee shop on occasion, which was fun, but still didn’t quite cut it.

I can tell you from first hand experience that a year and a half of working out of my apartment was a pretty isolating and eventually depressing thing. I’m sure it’s not a problem for some people, but I think most people who try it for any considerable length of time run up against this problem. It comes down to a pretty simple notion — you need to get out of the house, and by the end of your work day, you’d ideally want to enjoy being home.

Terralien’s Matthew Bass, who coined the term nomading, describes how he arrived at his solution:

I don’t mind being alone to a certain extent, but after a few straight weeks it can get pretty lonely. Recently, I’ve started doing what I’ve termed “nomadic programming.” Namely, spending the day roaming between various wi-fi hotspots instead of working from home. This has worked really well for me. So well, in fact, that I think the concept needs to start spreading.

I actually disagree, having tried nomading when I started to get stir-crazy. While I do think it’s a good first step for anybody who’s been working in isolation, you quickly run into some problems doing this that make it a somewhat incomplete solution to the problem. There’s really nothing that comfortable about hanging out in one or more coffee shops all day long, buying obligatory coffees and snacks, using their power outlets under the glare of the manager, not being welcome for quite so long, flakey network connections, and finally, do you really want to leave that $2000 computer alone by itself in Cafe Grumpy while you go to the bathroom? Do you want to take it in there with you, for that matter?

Coworking has been the ideal solution for us here at Zetetic, as we’re now working out of two coworking locations, Williamsburg Coworking in Brooklyn, NY and Indy Hall in Philadelphia. One of our guys is planning to open a new space soon with some partners (so I can’t reveal any details), and our founder Stephen Lombardo has been thinking for some time of starting one in central NJ (if you’re in central NJ and you are interested, get in touch!). It makes us really happy, keeps us extremely productive, and we can’t recommend it enough.

We pay monthly fees to use our spaces — it’s a lot cheaper than renting commercial office space. We have ergonomic chairs, we have personal storage areas where we can keep keyboard trays and the like. We have a fridge, a kitchen, wifi, and a really fantastic social group of thinkers, artists, programmers, writers, you name it. Distractions are low, productivity is high, we have people to bounce ideas off of who’ve become our friends, we even prepare lunches together sometimes to save money (and because it’s fun, Zane’s a great cook). We even have an excellent library of somewhat “alternative” reading materials.

When I started working here, my productivity shot up like woah. In addition, I’ve learned how to screen print and pickle vegetables. I’ve made some great friends and I get to bounce ideas off extremely smart people. And this is a very large community — our space is part of a network of locations all over the world, and any of us is welcome at those spaces if we’re traveling (read more about Coworking Visa). I think the main reason people here get along so well is that there’s no one here who doesn’t want to be here, it’s the total opposite of being trapped in an office. And having done a bit of nomading myself, it’s a lot less stressful.

These coworking spaces are popping up all over the country, the world, and they work. They’re even potentially lucrative businesses, although I prefer our space’s non-profit setup. If you’re considering nomading, we encourage you to try coworking as well, you can find many locations by searching the wiki.

Zetetic is the creator of the super-flexible Tempo Time Tracking system.

How to encrypt a plaintext SQLite database to use SQLCipher

Permalink - Posted on 2009-12-29 00:00

Note: the content in this post is outdated. Please use our new recommendations for how to encrypt a plaintext database with SQLCipher.

We’ve fielded several questions on the SQLCipher mailing list recently about how to convert a standard SQLite database to an encrypted SQLCipher database. This is a pretty common requirement for applications with existing databases that need to be converted to use SQLCipher full database encryption.

Attached Database (Recommended)

SQLCipher 1.1.1 added support for attaching an encrypted database to an unencrypted database to copy data between them. For instance, assume you have an standard unencrypted SQLite database called unencrypted.db with a single table, t1(a,b). To create an encrypted copy you could open up the databases and run the following:

ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'secret'; -- create a new encrypted database
CREATE TABLE encrypted.t1(a,b); -- recreate the schema in the new database (you can inspect all objects using SELECT * FROM sqlite_master)
INSERT INTO encrypted.t1 SELECT * FROM t1; -- copy data from the existing tables to the new tables in the encrypted database

It is fairly trivial to get a list of all schema objects from the sqlite_master table you would just repeat the CREATE TABLE / INSERT cycle once for each table. Then you can delete the unencrypted database and re-open the encrypted version with the sqlite3_key or PRAGMA key. This approach requires more work that just calling rekey, but it is be much more stable across versions.

In the mean time, we are working on finding a way to improve the built in rekey functionality in future versions. Keep an eye out here, or join the SQLCipher mailing list to keep up to date on the latest development.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Improvements to SQLCipher - cross platform SQLite Encryption

Permalink - Posted on 2009-12-28 00:00

We’ve been really busy over the past week finishing up some big enhancements to SQLCipher, the open-source full-database SQLite encryption extension that powers Strip, our Data Vault for the iPhone.

The latest version SQLCipher 1.1.1, is based on the most recent release of SQLite (3.6.21), which has a many improvements and bug fixes. In addition the new SQLCipher features include:

  1. Code clean up to allow compilation with VS.NET on windows.
  2. Enhancements to the codebase to allow encrypted databases to be attached to unencrypted database for the purpose data migration
  3. Resolution of a minor memory leak in the pager subsystem
  4. Documentation and test enhancements

The newest build makes SQLCipher truly cross-platform – it’s now been used successfully under Mac OS X, iPhone, Linux, and Windows (across MinGW, Cygwin, and native VS.NET). The new version is a drop in replacement for previous releases, so we’re recommending that all SQLCipher users upgrade to the latest.

Check out SQLCipher on GitHub.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Vote for Strip in Best App Ever Awards!

Permalink - Posted on 2009-12-22 00:00

Today and tomorrow I’ll be bringing you some news and updates related to Strip, answering some common email queries, and providing an overdue update on where we’re at with the desktop version. Before I get into the upcoming stuff, however, we could use your help! Strip for iPhone been nominated in the Best App Ever awards, under the Best Productivity Enhancer category. As I know there are a lot of you out there who have quite an affinity for Strip, mind clicking over to the page and voting for us?

Strip – Password Manager & Data Vault…
Best Productivity Enhancer

We really appreciate your continued support and enthusiasm for the platform. Stay tuned for updates!

NSDate (Helper) in Kevin Smith app

Permalink - Posted on 2009-12-21 00:00

Having been a big fan of CLERKS and most things brought into this world by Kevin Smith, I was delighted to receive an email this morning telling us that our NSDate category made itself into the credits for the new Kevin Smith iPhone app by DenVog. It’s exactly what you’d expect from Smith — it’s silly, awesome, immature, and well done. I can’t tell you how many times I watched CLERKS in high school, so being exactly that mature still, I downloaded it immediately.

This is my favorite part:

Weekend terror will ensue. None will be spared!

Snoochy Poochies!

NSDate (Helper) is continually being used in our own Cocoa projects, and I’m constantly mucking with it and pushing new changes to the github project. It’s probably due for a touch of code clean-up.

Update On Tempo Issues

Permalink - Posted on 2009-12-04 00:00

Since Tuesday’s outage on Tempo, we’ve been working hard to not only prevent that from happening again, but to further improve our system’s response time and optimize our resource utilization. This kind of spring cleaning and infrastructure maintenance was long overdue and took a backseat while we were building out the most recent update.

I’m happy to report, and hopefully you’ve noticed, that we’ve managed to not only stabilize our runaway memory consumption, but to dramatically improve response time over all (go Unicorn!). Now that things have stabilized and in fact improved, we’ll be working to further cut down on memory consumption in our application code. It’s very easy to have memory bloat in Ruby code, because Ruby doesn’t really release memory back to the system, so we’re profiling our code to cut back where ever we can.

As an aside, there’s this great Engine Yard post about memory bloat in Rails apps with pointers for pinpointing problem spots and cutting back. However, I take issue the notion that “it’s not a memory leak, it’s bloat.” That’s a lot of garbage, not returning unused memory to the system is a leak, and to pretend otherwise is a laughable bit of delusion. I agree that it’s important to recognize this as a known flaw of the platform, but to start thinking of it as a feature is probably not a good idea.

Tempo Issues, Tuesday Dec 1st

Permalink - Posted on 2009-12-01 00:00

Tempo was down this afternoon shortly after 4pm EST due to a nasty memory issue. It’s fixed for now and the service is back up, running nice and snappy, but we still need to implement a permanent fix. Keeping the service available to our customers at all times is exactly the point of web-based software, and we’re committed to providing you the best product possible.

We’ve been running on Nginx-Passenger for a few months now, and been trying to fend off a memory leak that just keeps coming back, and when we don’t catch it in time, like today, it can turn into a big mess. We are dropping pretty much everything to make sure we don’t end up in this position again. We will post an update here once we’re confident that we have a permanent solution in place.

Thanks for your patience, and our apologies if you were unable to access Tempo when you needed it this afternoon.

Tempo Upgrade Trouble or Questions? We have Answers!

Permalink - Posted on 2009-11-23 00:00

Over the weekend we rolled out a pretty extensive update to Tempo, our time-tracking service. Some of the changes have been confusing for our customers, so we’d like to take a quick stab at some of the common questions we’re getting and put them here on the blog.

I got an email about my URL changing, is this real?

Yes, it is! If you go to https://app.keeptempo.com, you’ll see that you can’t just go right on in anymore, you have to specify an account, or go directly to the account URL you got in that email. For instance, we access Tempo at https://zetetic.keeptempo.com. If you are having trouble finding your account, please get in touch!

What changed?

Before the upgrade, every user on Tempo had one unique profile, and worked with other unique users by grouping them together in various projects. The way Tempo works now is that users are grouped under a proper account, with an owner. For some Tempo customers, in particular for paying customers who shared projects with other paying users, they find themselves with more one account or domain that they can log into, and some of their time is in one account, and some of their time is in the other accounts.

To that end we have tried to make it as convenient as possible to use multiple accounts by hosting them on separate domains. That means you can keep a logged-in session to both your account and another person’s account in your browser at any time. You will still be able to run reports, log time, view data, etc.

Why did this change?

These changes were really critical for Tempo to continue operating effectively. As the system has grown there has been growing confusion on the part of new and existing users about the way that groups of people use Tempo. Previously there was no clear account owner, customized domain name, or centralized user administration, which added to the problem. Some companies even required multiple pay plans to support their needs, etc. While many of our customers had a clear understanding of the old “shared account” workflow, most people who tried out Tempo experienced problems setting up their company, creating projects and working with groups. Thus, this upgrade re-organized the model to make everything more consistent.

My time / co-worker / project is missing, help!

Don’t worry, your data is still here! We created an account for all paying users, and for all free users who had their own time outside of time logged to projects on paying accounts. Projects were moved under the account of the user who created them. If you would like us to consolidate your projects under one account, we’re ready and happy to help, please get in touch.

Am I being charged more now?

No! No one is being forced to upgrade, we’ve grand-fathered the plans of all our existing customers.

Do I have to upgrade because I have N users?

Nope! You may have noticed that our new plans charge users by how many people are in their account, as opposed to how many people they can have per project. Because this would be quite an unpleasant change for our existing customers, we decided to hook it up:

We calculated the total number of users you work with, added 2, and set that as the number of maximum users for your account. Previously, our plans were limited by people-per-project. So, if four was your limit, you could potentially have been working with 20 other people as long as they were on different projects (and your projects are unlimited). In that case you’d end up with a new limit of 22 users! For free!

Why has the Mac OS X Dashboard Widget stopped working?

Make sure you’ve updated the Site setting on the back of the widget to correspond with the new URL for your account, and that you use https! (e.g. we use https://zetetic.keeptempo.com). Make sure you leave off any trailing slash, or it won’t work (we’ll get to fixing that in an update to the widget).

Is the bookmarklet broken?

You just need to grab the updated bookmarklet. Log into your Tempo account, go to the Time screen, and grab it from the Time Entry form at the top of the screen.

How do I get to the mobile version?

For some mobile devices, we provide the mobile view automatically, but for some newer or unrecognized devices, you can click the ‘Switch to Mobile View’ link on the login screen. We will be adding a link to the mobile view from inside the application very soon for logged-in users.

Another option is to go to https://m.keeptempo.com. You will be shown a mobile version of the account lookup screen. Simply tap in your domain name or lookup your account, and you will be redirected to the mobile time entry screen for your account.

Why does it say that my billing info needs to be updated?

Because there’s a bug that we’re working on fixing right now! We have a list of affected users, but feel free to send us an email anyway if you want to be kept abreast of this issue once it is resolved.

Can I request my own subdomain? Or change it my self?

Absolutely! If you are the account owner, log in to your account, and click the Account tab from the left-side menu. Click the ‘change domain’ link on this screen and you’ll be taken to the form for changing your sub-domain.

We will keep updating this post today if we identify more issues.

Teams: Mission Accomplished

Permalink - Posted on 2009-11-22 00:00

I love seeing the change summary after a large and major branch is merged into the master branch. I think this is our best one yet:

282 files changed, 11893 insertions(+), 12129 deletions(-)

We successfully deployed the Tempo update “Teams” last night. There are a few lingering issues that we’re working hard to resolve. If you notice anything funny, please get in touch so we can get to work on it.

Tempo Maintenance: Saturday Nov 21, 9pm

Permalink - Posted on 2009-11-20 00:00

Tempo will be unavailable from the web this Saturday evening, November 21st, at 9pm EST / New York time, while we apply a significant update to the service. Time entries sent over Twitter or Email will be queued up and processed when the service comes back online. API access and the Mac OS X Dashboard widget will not be available while the system is unavailable.

We will post updates to the blog and the Tempo Twitter account about our progress Saturday night for those of you who wish to keep track.

If you have any questions or comments, please don’t hesitate to get in touch!

Tempo: A Peak at the Team Views

Permalink - Posted on 2009-11-18 00:00

In anticipation of the upcoming update to Tempo, codenamed “Teams,” here’s a quick look at two new screens that we think add a new dimension and value to our time tracker.

First up is the Team view itself:

As you can see, it lists the members of your team by name, provides you an entry point to edit a user, to run a report for that user, info on the user’s last time entry, and recent stats. Of course, clicking that spark line will present you with a utilization bar graph for yet more information. It’s our hope that this view gives you a new tool to see how your team is doing!

See that ‘Team Status’ link in there? Well, while we were putting this screen together, we kept having an itch to build a supplementary view. Something simple and concise that shows you just what your team is working on right now. Thus, the Team Status view was born:

As you can see, it looks a lot like a Twitter feed! It’s low noise, shows you what’s going on in your group right now, and there’s even a handy mobile view:

We’re hustling to get ready for the update this weekend. Will post a notice here when we’re ready to set an exact time for performing the update, as it will result in some downtime Saturday night.

Tempo: Customize Your URL

Permalink - Posted on 2009-11-16 00:00

As we’ve mentioned previously, big changes are coming for Tempo in our next release, codenamed “Teams”. After this update you and your company will be able to login to your own private Tempo address, e.g zetetic.keeptempo.com. However, we’re not telepathic and we can’t tell what domain you’d prefer to use, so we have provided a way for you to choose the preferred domain for your account before the migration:

  1. Log into Tempo at http://app.keeptempo.com
  2. Open your preferences by clicking Account on the Left-side menu
  3. Click “Subdomain!” From the top Account menu
  4. Enter your preferred sub-domain
  5. Click “Save Changes”

If you follow these steps your account will use the new subdomain after the release. If you choose not to set a preferred domain the system will automatically choose one for you based on your login name, e.g. username.keeptempo.com. Don’t worry, you can always change it at a later date.

We are currently planning to release the new version of Tempo on Saturday, the 21st of November, late in the evening US-time. After the conversion, you and all of the users on your account will be emailed with the new URL so you can update bookmarks and widget configurations. We’ll provide an update here on the blog later this week to let you know exactly what time we plan to launch the new version.

Thanks so much for your continued business, and extra thanks to those of you who’ve helped us test this update, we really appreciate your feedback.

Responding to RFPs

Permalink - Posted on 2009-10-28 00:00

Since the topic is going around lately, I figured we’d chime in. Max Cammeron of Big Bang makes a strength-in-numbers appeal to consultants everywhere to abandon RFPs, while Carl Smith from nGen Works has a post up making a strong case that RFPs aren’t good for his clients. We don’t respond to RFPs either, and this isn’t because we’re starving artists/consultants. Many of the comments on Max’s article at Hacker News seem to be pushing this notion that responding to RFPs is the cost of business for a consultancy, and they couldn’t be more wrong.

We don’t respond to RFPs, and all of our business comes from repeat customers and referrals. And we’re not exactly making web sites for Jumpin’ Jack’s Chicken Shack, we’ve got some really big clients. Stephen gave a really good run down of why we don’t need ’em in a recent interview with Subvert.ca (emphasis added):

When we get a referral or start a new project for a past customer, there’s already a relationship in place. The client already knows that they can trust us, and it cuts out the entire “dance” that we’d otherwise have to do to prove ourselves. There are other benefits, too.

People only ask us to prepare a proposal when they are seriously considering a project. Plus, we rarely find ourselves as column fodder behind another incumbent company — we call it column fodder when you have no hope of winning a deal and your estimate is just filling in a cell on a spreadsheet for comparison purposes.

This level of trust also means that we can work more closely with our customers to develop requirements. They take our estimates and advice seriously. In the end it works out better for everyone involved.

We can talk ourselves blue in the face about the effectiveness or lack thereof in the RFP process, as I’m sure they will remain in the industry for some time, but in the end, nothing replaces good work combined with good communication, and trust. We only work with people we trust, and so do our clients.

Stay tuned, sports fans; later this morning I’ll post a run-down of where we’re going with Tempo, our time-tracker. Change is afoot!

Coming Soon: Tempo Teams

Permalink - Posted on 2009-10-28 00:00

Over the last year a whole lot has changed with Tempo, our time-tracking system. Actually, in the last two years the system has seen constant development and two major re-designs as we added features, responded to our customers’ feedback, and addressed rather-justified gripes about our lack of design skill shown in the early revisions. At this point Tempo has a fantastic look and feel, is extremely stable, and has a satisfied and steadily-growing base of free users and paid subscribers.

However, all that work takes a long time and involves a great deal of testing, usually with a number of our customers helping us beta the changes before release, for which we are quite grateful. After a major revision of Tempo is released, there’s always a period of adjustment for our users, too, so there’s a hidden cost there as well.

With that in mind, I’m happy to say that the next major revision of Tempo, Teams, is almost here, and should involve very little adjustment for those who are using the system every day. The changes are big, but they are mostly below the surface. This revision makes Tempo a lot more flexible for us and our customers, and is allowing us to implement some oft-requested features from our long-time users. This revision is called Teams because it is specifically aimed at making the management of a team on Tempo as easy as it ought to have been in the first place.

If you’d like to get an early look at the new system, please get in touch with us and we’ll send you the link and some short instructions.

Here’s a list of the bigger changes:

  • Quick assignment of users to multiple projects.
  • All paid users will have an account associated with their user identity.
    • Free users working on their own will also have accounts generated.
  • All of these accounts have their own subdomain (e.g. zetetic.keeptempo.com).
  • Accounts can have managers with more control than project managers.
  • All people on your projects have been copied or moved into your account.
  • Paid plans will be scaled by people-per-account, not people-per-project.
  • Every paid account is gifted an extra two users to accommodate that change.
    • e.g. Moderato accounts with 10 users on various projects would be get 12 users.
  • Auto-detection of mobile browsers for an updated mobile view.
  • Legacy support for the ‘m.keeptempo.com’ mobile address.
  • Saved Reports can be organized into groups.

We haven’t set a release date just yet, but we’re aiming for the middle of November, so that we can address any issues before the end-of-month billing period.

Working with mobile-fu and Rails

Permalink - Posted on 2009-10-23 00:00

Bret and I have been working on a pretty extensive update to Tempo, our time-tracking service, that required revisiting how we detect mobile devices and provide mobile views where appropriate and/or available.

To that end I took a look at mobile-fu, a Rails plugin by Intridea’s Brendan Lim, which automatically detects mobile devices and sets the request format to :mobile, a commonly used mime-type alias for those looking to provide mobile views. You can check out his blog post on the plugin for full details, but the basics of it are that by setting the request.format to :mobile, you can automatically serve up custom views (e.g. new.mobile.erb), perhaps in a custom layout, etc. The plugin also will automatically attempt to include mobile_blackberry.css if you are already including a mobile.css file and the user is working off of a blackberry.

That’s almost perfect! However, we don’t support mobile views all over Tempo, it’s a bit impractical at the moment, especially given how well smart phone browsers like Mobile Safari handle normal web pages. Instead, we provide a basic mobile interface for logging in and logging time. We do want that to render automatically, but we also want the user to be able to exit out of the mobile view easily, and have that stick with his session.

So I forked mobile-fu on github, got things working the way I needed ‘em, and posted the changes back up. It now provides automatic detection of mobile devices with more dynamism (you call before_filter yourself, where you want it, with the options you need), and you can use the ’bypass’ parameter on any request to toggle the session-based bypass of the mobile view that allows the user to avoid it if he doesn’t actually want it.

Pushed-to-github-and-blogged-too-soon Update:

The use of a ‘bypass’ in the way I’ve done it here becomes somewhat less useful when you want a user to be able to easily enable the mobile view when their mobile device is not detected (e.g. a ‘Switch to Mobile View’ link on the login screen). So, I’ve hacked away at this a bit more and I’ve got another implementation to commit and push to this fork when I get a few minutes.

The main problems I ran into in all of this were not really the problem of mobile-fu, but more of an issue with how Rails handles the use of request.format, the aliased mime-type (i.e. :mobile => 'text/html'), and forwarding from one domain to another. Will try to detail how we’re handling it all shortly.

Get Excited and Make Things

Permalink - Posted on 2009-10-20 00:00

Designed by Mr. Matt Jones, of the British Experimental Rocket Group (BERG):

You know you want one. I just ordered mine.

BERG does amazing things like this:

Immaterials: the ghost in the field from timo on Vimeo.

Been real busy here at Zetetic HQ. Bloggery to resume soon!

Strip Updates On the Way

Permalink - Posted on 2009-09-10 00:00

I was intrigued by Steven Frank’s recent blog post describing how Panic software approaches communicating with customers about feature announcements and product updates. Like Panic, we tend to say little, work a lot behind the scenes, but it sounds like once in a while it’s a good idea to get out in front with a blog post to let your customers know what we’ve been working on and what’s coming.

Our primary development focus with Strip at the current time is a replication library that will be the core of our sync process, and it will likely become an open source project. Many folks have been emailing us to say that they love Strip on the iPhone, but they need desktop sync, and some of them miss the old beaming functionality of STRIP on their Palm devices. The replication engine is almost complete, and is the key to enabling these additional pieces of the Strip platform.

Meanwhile, we’ve got a maintenance update brewing for Strip on the iPhone. We expect the following issues to make it in to the next update, time permitting:

  • Bug: Loss of typed data on lock out while creating a note. (Fixed)
  • Convert existing database cipher mode to improve compatibility with standard SQLCipher configuratione. (In-progress)
  • Rename Lite → Strip migration button for clarity. (Fixed)
  • Fun: Facebook Connect hook for spreading the word. (Complete)
  • Allow copy & duplication of entries so that you can create “template” entries or share common fields. (In-progress)
  • Protect database re-key from application interruptions. (In-progress)
  • Enable FTS3 (full-text) searching, search on type.
  • Bug: Attempts to re-order the Add Field row cause a crash.
UPDATE: have just released a free Palm Strip Export utility for Windows that can dump your Palm OS 2.0 databases to a CSV text file. Check it out here.

acts_as_union to the Rescue

Permalink - Posted on 2009-09-07 00:00

So here I am, minding my own business on Labor Day, working on the upcoming teams branch of Tempo. Basically, it introduces a new account model that’s distinct from users and projects, ideally facilitating the setup of teams for small organizations. Accordingly, an account has an owner, and every user belongs to an account. In addition, users can be managers for the whole account (new!), or users can be marked as a manager for a particular project assignment.

This all sounds great on paper, but in the Projects controller there arise a number of concerns:

  • The account owner or one of the managers should see all the account’s projects on the projects index, and also the /archive resource collection
  • All other users should only see accounts they are assigned to as managers
  • index should only show active projects and archive should only show inactive projects
  • index and archive both support an id parameter for the XML api, enabling the lookup of an aribitrary collection of managed projects

As you can imagine, this could lead to a lot of spaghetti in a controller method, that you’d want to hide away in a model. Typically, you’d want your User model to set up the various project collections as association (has_many) resources so you can provide find options as needed (such as :conditions => { :is_active => true }). That keeps your redundancy down, but your controller (or a model method) would have to conditionally decide which resource to provide. There was the possibility of adding a method to the user model that handled the conditional logic and passed back the right result set, but it would have been a royal pain to correctly pass through find options, especially given all the various circumstances above..

To make things further complicated, we need to also use these methods for the reporting interface and to make sure users only see the time entries they are supposed to see. That means keeping nonsense and code repetition to a minimum is critical.

That’s where acts_as_union saves the day!

has_many :managed_projects,
:source => :project,
:through => :assignments,
:conditions => [ 'assignments.is_manager = ?', true],
:order => 'projects.name ASC'
has_many :owned_projects,
:source => :projects,
:through => :owned_account,
:order => 'projects.name ASC'
acts_as_union :manageable_projects, [ :owned_projects, :managed_projects ]

ActsAsUnion is included in our ActsAsNetwork plugin, and it allows us to UNION together multiple associations and operate across them as we would any other association, by supporting the various find_* options we are used to with has_many.

Now I can do any of the following:

@projects = @current_user.manageable_projects
@projects = @current_user.manageable_projects.find(:all, :conditions => { :is_active => false})
@projects = @current_user.manageable_projects.safe_find_from_ids(params[:id])

On a tangential note, safe_find_from_ids is a quick and dirty monkey-patch we throw in an initializer so we can look up a set of ids that returns an empty set instead of raising an exception when no ids are found:

class ActiveRecord::Base
def self.safe_find_from_ids(*args)
ids = args.kind_of?(Array) ? args.flatten : [args]
ids.empty? ? [] : self.find(:all, :conditions => ["#{self.table_name}.id IN (#{ids.collect{|p| '?'}.join(',')})", ids].flatten)

It’s not ideal, but it gets the job done. There may be a better way of doing it in recent versions of Rails, need to look into that.

Happy Labor Day!

Zetetic is the creator of the super-flexible Tempo Time Tracking system.

Video: Command Line Time Tracking

Permalink - Posted on 2009-09-04 00:00

Recently we hired Aaron Aiken’s Trim Trab Creative to put together some videos demonstrating how Tempo works, and the videos are coming out great (check out the main tour vid here). He has a real knack for putting together interesting demos and communicating the concepts at work in a piece of software.

We put a lot of thought and work in Tempo’s interfaces, but sometimes it gets tricky to explain some of the concepts to new users, especially some of the advanced controls that can save you a lot of time. Introducing people to the benefits of using our simple command line for time tracking is one of those tricky things. Aaron hit it out of the park:

Tempo Time Tracking – Text Entry Demo from Zetetic on Vimeo.

Tempo: Spit and Polish, and the Future

Permalink - Posted on 2009-09-03 00:00

We’ve been working pretty hard on Tempo since we released the new design this Summer, fixing bugs, refining the interfaces, and making those subtle tweaks that can really make a difference with a piece of software that we use frequently while we work. With that in mind, we’ve got another maintenance update out that should provide some requested changes and fix yet more “things” that needed fixing.

Here’s the full list of what’s changed, then I’ll go into what we’ve got coming down the pipe:

  • New user utilization chart on Time screen, click the spark-line to activate!
  • Modal charts return! Click stats metrics and spark-line on Reports screen to activate
  • Modal edit of time entry view was a little mussed in IE7
  • After entry edit, form fields were not clearing
  • After entry add, edit, start, stop, etc causes stats on screen to update for accuracy
  • API: setting exclude-tags param in reports search was ignored, now handled like tags
  • Saved Reports with specific end dates were skewed by a time zone / serialization issue
  • Future dates on reports were being improperly set to ‘today’
  • Last active project cannot be archived or deleted (causes mad bugz, interim fix)
  • Batch tag add and remove with no managed entries resulted in an error
  • Saved reports with exclude tags were broken
  • Hide tag auto-suggest when user hits space bar (a relieving fix)
  • Expanded command line entry form
  • Busted link to Mac OS X Dashboard widget

Coming Soon

We’ve been working hard behind the scenes on another major update for Tempo that should dramatically improve our ability to set up teams and collaborate. The current system can be a little bit confusing for first-time users who are looking to set up a Tempo account for their organization and invite their teammates. In the future, the setup process will distinguish between an Account, and a User. An Account will have a distinct name, e.g. Conglomo, and a subdomain for accessing the account (e.g. conglomo.keeptempo.com). Billing functions will move to the account and users will be set up directly under the account by the account owner or any users assigned as managers.

Once we’ve got that in place, we plan on putting together an iPhone application (we’ve got some experience doing that now), making some much-needed improvements to our API, and getting to work on some of the integrations people have been asking for.

Oh, we’re cooking up a Gadget for the Windows Sidebar, too!

Hewitt is Right, Arment is Wrong

Permalink - Posted on 2009-09-02 00:00

Update: Corrected misspelling of Marco Arment’s surname.

Joe Hewitt, developer of Firebug and Facebook’s iPhone application, writes in an article titled, Innocent Until Proven Guilty, that Apple’s review process for third party iPhone apps in the iTunes App Store should be eliminated entirely. I was impressed with this, as it’s really the elephant in the middle of the room, that few commenters seem to address. The driving justification behind Joe’s short article is quite powerful:

Does that sound scary to you, imagining a world in which any developer can just publish an app to your little touch screen computer without Apple’s saintly reviewers scrubbing it of all evil first? Well, it shouldn’t, because there is this thing called the World Wide Web which already works that way, and it has served millions and millions of people quite well for a long time now.

Indeed, somehow we’ve managed all these years. And while the Internet has brought us various catastrophic influenza and garbage, the iPhone OS is already exposed to those threats, and third party applications are sand-boxed to the point of being a much poorer vector for malicious activity than looking for your classic remote buffer overflow. Hewitt continues, emphasis mine:

If you think that all apps should be held prisoner by Apple until proven safe, you should also be able to convince yourself that this is how the web should work.

I think the issue becomes a bit clearer if you change that statement to read, “that this is how your personal computer should work.”

In any event, there are many other developers out there who’ve been beating the drums of discontent, griping at Apple and earning some page views in the process, but the writing is usually done with an oddly sycophantic bent. Marco Arment, who is prone to such outbursts (wherein he righteously chastises Apple but then repeats over and over how much he loves the company and the iPhone itself, perhaps to prove his bona fides), recently pushed back against Hewitt’s sentiment, offering the article, Apple can’t stop reviewing iPhone apps. His main point, that Apple has no choice but to continue to review all apps lest some rogue iFart yield bad press or screw it up for all of us, rings quite hollow and altogether avoids Hewitt’s challenge: should this be how the Internet works? More to the point, should it be how your personal computer works?

Even if Apple stopped reviewing apps completely, they would still be blamed in the press for the effects of problematic apps. This creates a difficult position: Apple must attempt to be the gatekeeper in a market full of gray areas, but any decisions they make fall under intense scrutiny, and many decisions don’t have an indisputably “good” option.

Apple must attempt to be the gatekeeper? Arment is missing the painfully obvious, that Apple has been getting a ton of negative press, the likes of which they don’t normally ever see, thanks to their asinine review system and their poor behavior as a business partner. And that’s for the best, for App Store developers. It’s important to take off the Apple Fanboy bifocals long enough to look at this as a question of business relationships and investment risk.

Rather than fighting to abolish app review, it’s far more productive to guide and influence Apple, through both public and private interactions, to improve the system that we’re all, including Apple, probably stuck with for a long time.

Appeasement, or perhaps I should say bargaining with no chips, doesn’t seem very productive so far (is it ever?) Sure, it works well enough that popular developers like Arment have options for recourse; under the current system, if you are already a very popular developer with a wide audience, you can publicly embarrass Apple before that audience in order to get half-decent treatment as a business partner, adding value to their product and generating continued additional revenue for them.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Zetetic.Ldap - Bringing LDAP + LDIF tools to .NET

Permalink - Posted on 2009-09-01 00:00

We’ve just released the Zetetic.Ldap library to github, which makes it, to the best of our collective knowledge, the first and therefore most kickin’est .NET library for working with RFC 2849 LDIF, LDAP schema, and LDAP entry change tracking.

LDIF: This file format is still the best and most universal way to move data in or out of directory systems like OpenLDAP, Active Directory, Fedora or Red Hat Directory Server, etc. Zetetic.Ldap makes it easy to write and read directory entries with LDIF.

LdifWriter ldif = new LdifWriter(@"c:\temp\stuff.ldif"); 
ldif.BeginEntry("cn=joe cool,o=zetetic");
ldif.WriteAttr("givenName", "joe");
ldif.WriteAttr("jpegPhoto", File.ReadAllBytes(@"c:\temp\joe-photo.jpeg");
ldif.WriteAttr("dateCreated", DateTime.Now);

Zetetic.Ldap knows how to format binary data, dates, and long fields in the proper way — you don’t have to mess with it!

The same is true for reading entries out of an LDIF file.

LdifEntryReader ldif = new LdifEntryReader(@"c:\temp\stuff.ldif"); 
for (Entry entry = ldif.ReadEntry(); entry != null; entry = ldif.ReadEntry())
Console.WriteLine("Found: {0}", entry.DistinguishedName");

We’ve also included a command-line pivoter program that transforms LDIF files into tab-delimited files, for easy loading into Excel, RDBMS, or what-have-you. This can be incredibly useful for analyzing the data in your directory.

Change tracking: Normally, if you’re using Microsoft’s System.DirectoryServices.Protocols classes, you’ve got to manage the concept of preparing specific LDAP modification commands yourself. It can get pretty complicated, and sometimes you have to resort to trial-and-error to learn the right way to delete an attribute, for example, or rename or move an entry. Zetetic.Ldap provides a wrapper around this complexity, and will track your changes until you’re ready to send them to the server.

MutableEntry entry = MutableEntry.CreateUncommitted("cn=frank grimes,o=snpp", "person");
entry.SetAttr("sn", "Grimes");

MutableEntry entry = new MutableEntry(mySearchResult);

Schema: This part is a little more abstract. Directory servers contain an area that describes the allowable objectClasses (types) and attributes (fields), and those attributes have syntaxes (like string, number, date, etc.). The classes in Zetetic.Ldap.Schema help you work with these data programmatically, so you can quickly discover what the server supports. Moreover, you can find out what kind of value (syntax) each attribute uses conceptually, without delving into the world of OIDs.

Here’s a snippet from the project’s unit tests, showing how to export the basic objectClass definitions from a Microsoft LDAP server.

ISchemaInfo target = new AdsSchemaInfo();
using (LdapConnection conn = new LdapConnection("localhost:20389"))

foreach (ObjectClassSchema o in target.ObjectClasses)
System.Console.WriteLine("oc: {0}", o);
foreach (AttributeSchema a in o.MustHave)
System.Console.WriteLine(" must: {0} as {1}", a, a.LangType);

foreach (AttributeSchema a in o.MayHave)
System.Console.WriteLine(" may : {0} as {1}", a, a.LangType);

We also included some helpers to manage parsing special attributes like GUIDs, or “pwdLastSet” and “accountExpires,” which are usually treated like DateTimes, but stored as 64-bit integers, sometimes outside the range of what DateTime can handle—I always enjoy telling people, “Oh, it’s simply the number of 100-nanosecond intervals since January 1, 1601 UTC!”

So anyway, when you find yourself working with LDAP or LDIF on .NET, grab the release at github, and drop us a line, we’d love to know how you like it.

Interview with Subvert.ca

Permalink - Posted on 2009-08-20 00:00

There’s an extensive email-based interview of us over on Subvert.ca. There’s juicy bits about certain large companies trying to kill off one of our early projects, column fodder, and the approaches we’ve developed for taking on new clients and starting new development projects. Here’s an excerpt:

Many people we speak to find it unusual that we don’t actively prospect, solicit, or answer blind RFPs, etc.

Honestly, we like it this way: when we get a referral or start a new project for a past customer, there’s already a relationship in place. The client already knows that they can trust us, and it cuts out the entire “dance” that we’d otherwise have to do to prove ourselves. There are other benefits too.

People only ask us to prepare a proposal when they are seriously considering a project. Plus, we rarely find ourselves as column fodder behind another incumbent company—we call it column fodder when you have no hope of winning a deal and your estimate is just filling in a cell on a spreadsheet for comparison purposes.

This level of trust also means that we can work more closely with our customers to develop requirements. They take our estimates and advice seriously. In the end it works out better for everyone involved.

That’s a Good Plan

Permalink - Posted on 2009-08-17 00:00

Great blog post from Carl over at nGen Works about what’s he learned over the last six years running his business, in particular this list of goals, or statements of intent:

  1. Understand what we want personally and align company and individual goals as much as possible
  2. Discuss issues openly and honestly
  3. Admit mistakes and fix them
  4. Take the high road in grey areas
  5. Consistently recognize good stuff and hold people accountable for bad stuff
  6. Support each other through successes and failures

Item 1 is not something you often see out of a company, especially the larger sort. Items 2 and 3 are things that people always struggle with, and they are a nice reminder to me who runs a musical operation on the side. It’s always tempting to make unilateral decisions or to try and cover up mistakes, especially public ones, and doing so always comes back to haunt you.

Deep Thought (Sticky Email)

Permalink - Posted on 2009-08-17 00:00

Shouldn’t I be able to attach notes to an email, say in Gmail or any other mail client, for internal/personal use? Things to remember, to come back to later? Almost like Stickies, or the Task list? Obviously it would just be a local thing, for organization, but man, that would be handy. Especially in our support bucket.

Maybe that’s one of those things Outlook has always done that I was never privy to, but it strikes me as the kind of thing that’s been missing for a long time. I do remember a time when I had pieces of paper on a desk that I had to deal with, and I would often attach post-it notes to those pieces of paper, writing down reminders about what needed to be done.

Maybe a Firefox plugin like FireGPG to hack into the DOM of a Gmail inbox! Okay, back to work now.

Data Wholesalers &amp; Monopoly

Permalink - Posted on 2009-08-14 00:00

Clay writes over on the Sunlight Labs blog:

Once you start editorializing data— well, you’ve lost both accountability and transparency as well as credibility.

Sunlight Labs is a pretty cool project, where their focus is taking all that data the government makes available and digging into it to find out what’s actually going on. And one of the problems they have with a lot of the government projects like Recovery.org is that while they espouse transparency, they don’t actually provide the raw data, they editorialize it and provide websites and displays that spin it to their advantage. When you look at it like that, it’s the opposite of transparency. In fact, if you want to set up your own data mining and digging, and you want FEC data, you’re probably better off getting it from Sunlight, who’ve already taken the time to build machine readable databases for you.

On a related note, there’s an upcoming set of presentations called BigAppsDevCamps, for those who want to use New York City municipal data in their apps. It’s probably of interest to many mobile developers, and I was planning on stopping by if I can. I think that might be an example of government being a good wholesaler, as opposed to a bad retailer. Although that depends on what they make available and how. I don’t like the notion of filing an RFP just to get access, when it’s public data.

SQLCipher Users Mailing List

Permalink - Posted on 2009-08-12 00:00

We’re starting to get a lot of questions about SQLCipher from developers, ranging from getting the source code to build environment integration and linking. In order to better facilitate use of the library, encourage the growth of a developer community, and to hopefully avoid repeating the same answers too often, we’ve started the SQLCipher Users mailing list on Google Groups. You can sign up over here.

If you use SQLCipher in your project, you should subscribe to get news about updates (like integration of upstream changes from SQLite), changes, and new features. Traditionally we’ve fielded questions about SQLCipher from our support email account, but from now on we’d appreciate it if all requests for help with this software be posted to the mailing list.

Another AT&amp;T Anecdote

Permalink - Posted on 2009-08-12 00:00

Since every day seems to be boo-AT&T-day, I figured I’d add another anecdote to the chorus.

Lance Ulanoff writes over at Yahoo! Tech that the AT&T 3G service on his Blackberry seems to be crummy when he goes underground or out into the suburbs:

AT&T appears stuck in some year 2000 time warp

Lance, I think AT&T is caught in a 1988 time warp, and I for one would like the accordingly fashionable and gigantic phone to go along with it. Also: a hoverboard. It’s a real disappointment to have what basically amounts to an $800 personal computer phone thing in your pocket that can’t hold a call for more than two minutes.

My AT&T service on my iPhone (3G and Edge) stinks everywhere, all the time. It’s consistent fail coverage. It barely works in my apartment in Greenpoint, which is just across the East River from Manhattan. Calls get dropped all the time, and the sound quality is almost always terrible. It also doesn’t work for anyone at all in our coworking space in Northside Williamsburg. We often have to take a walk to have a chat on the phone, and that means putting up with the noise of buses and trucks on the street.

It doesn’t work in the ‘burbs, and yes, it doesn’t work underground. I don’t expect cell phones to work underground, and it’s nice when they do, but I do expect that they should work in freakin’ Brooklyn and I shouldn’t have nearly so many dropped calls. I mean, come on. This isn’t the Pine Barrens of New Jersey, I’m not trying to make calls from a secret lair.

NSDate (Helper) Updated

Permalink - Posted on 2009-08-07 00:00

We’ve got a small category extending the NSDate class found in Cocoa with some really convenient methods that allow us to work with date objects without cluttering up our code with NSCalendar and NSComponent objects and operations. If you’ve ever had to do date manipulation or formatting in Java, I can tell you that it’s as much a nuisance in Objective-C, too.

In any event, I finally got around to putting up a proper description of each method, and added a new instance method, weekday, which gives you the day of the week for an NSDate, 0 – 6 (0 being Sunday).

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Spolsky on Twitter and Real Conversation

Permalink - Posted on 2009-08-06 00:00

Joel Spolsky on the Stack Overflow podcast last week:

The trouble with Twitter though … as soon as the conversation threatens to become actually real, the 140 k limit [sic] and the fact you don’t want to just sit there and tweet all day actually forces you to stop. Then you’re not having any kind of real conversation.

It’s time to escalate.

One of the greatest bits of inspiration for me coming out of the #futureruby conference was this notion of just replacing things. You don’t like it? Change it. Build a new thing. Launch a thousand ships against the ebays and amazons and apples of the world. That clever Panic fellow has the right idea.

Serious Doubts, Indeed

Permalink - Posted on 2009-08-05 00:00

There has been growing, vocal discontent from iPhone developers on the net in the last couple of weeks, with many high-profile developers throwing in the towel, declaring Apple’s somewhat draconian platform too risky for serious investment, or simply too odious.

Today, Gruber posts:

Apple censored an English dictionary…. Apple requires you to be 17 years or older to purchase a censored dictionary that omits half the words Steve Jobs uses every day.

This does not inspire confidence in the platform. It seems like the hits keep coming daily, and Apple continues to blatantly ignore all criticism, sometimes with outright hostility and arrogance.

Every time we consider a new app idea here at Zetetic, it’s mitigated by fears that taking the time to invest in building it out, and building it well, may end up being months flushed down the toilet. There are a number of neat projects that we are unwilling to pursue because there’s a high likelihood of having the app rejected or pulled from the store for what seem like incredibly inconsistent and/or competitive reasons. No code written is ever a waste, but who wants to design and build an ornate structure only to see it washed away like some sand castle? More importantly, who can afford to?

We’re going to continue to develop applications for the app store (we’re about to submit Codebook, actually), but we’re really leery of starting anything new, as it seems that none are immune to the king’s whims. In fact, the continued bad press (especially with regard to the exclusive US carrier AT&T) is extremely bad for the platform as a whole, and threatens its growth and viability in the marketplace.

Mass Market Encryption CCATS Commodity Classification for iPhone Applications in 8 Easy Steps

Permalink - Posted on 2009-08-03 00:00

“Export laws require that products containing encryption be properly authorized for export. Failure to comply could result in severe penalties.”

Anyone who has developed an iPhone application will recognize that quote from the first screen of the App Store submission page. If an application is using encryption technology then it’s necessary to provide documentation to Apple that demonstrates review by the Department of Commerce (DOC) Bureau of Industry and Security (BIS) and classification of the application a mass market encryption item.

What does that really mean? For starters, your company is required to document and submit details of your application, including the specific ways it is using encryption, to the DOC and the “ENC Encryption Request Coordinator” (the NSA) for review. Your submission will be used to determine whether it meets the US government’s Export Administration Regulation (EAR) criteria for a mass market encryption item.

More practically, it means that you have a pile of paperwork to complete. A typical submission will require review of several EAR guidelines, completion of multiple online forms, and preparation of 7-10 pages of supporting documentation. You could spend days navigating the maze of information on the BIS site. Oh, and the review can take 30 days or more to complete, so get started early!

The good news is that this article will save you most of the headache by walking through the entire process from start to finish. We’ve created stepwise instructions and even prepared templates for critical supporting documentation.

Step 1. CIN and PIN Request

There are two ways to submit an application to the DOC, either using a snail mail submission or electronically. For the purpose of this discussion we will cover electronic filing only because its faster for repeat filings.

The first step is to apply for a PIN to access the DOC Simplified Network Application Process – Redesign system (henceforth referred to as SNAP-R). Head over to the PIN request page, where you’ll find a PIN request template. The DOC expects the template to be printed on your “company letterhead”, so copy and paste the text into a word document that includes your company logo, address information, etc.

Take care to fill out each of the fields with correct information, especially the table at the bottom of the document. You’ll need to fill out one row in the table for each individual requiring a PIN. Each person should sign and date their individual row, and an officer of the company must sign and date the document as a whole.

Print off a copy and create a cover that includes your contact information (the DOC processors will call you if they have questions) and make sure the subject reads something like “Company Certification Letter for SNAP-R”. Fax the document over to to the number listed at the bottom of the PIN request page.

It will take one or two weeks for the DOC to process each PIN request. A coordinator will make contact once the approval is complete to communicate the Company Identification Number (CIN) and Personal Identification Number.

Step 2. Create a SNAP-R account

The CIN and PIN alone are not sufficient to access the SNAP-R site. Navigate over the the Login ID And Password Setup Page and enter the required values, along with a username and password of your choice, to create a SNAP-R account.

Step 3. Online Application

With a SNAP-R username and password in hand online we can begin the application process. Start at the SNAP-R login screen and enter the username and password created in the previous step along with the CIN number assigned in Step 1.

Click Create Work Item on the main SNAP-R screen to start a new application.

Select Commodity Classification Request from the Type select box. Then enter a reference number of your choice into the next field. The reference identifier should be seven characters long, consisting of three letters followed by 4 numbers. It’s usually a good choice to use the first three letters of your company name, followed by an incrementing sequence, for example, ZET0001.

Contact Information

The following commodity classification request screen is divided into six sections. Start by filling in the contact information for the application.

License Information

In the second License Information section enter the at Special Purpose of “Mass Market Encryption”. It’s absolutely critical that the special purpose contain that exact value or it won’t be routed properly for approval and the request may be delayed.

The bulk of the Applicant information section will be pre-filled based on the CIN request data from Step 1. Populate the Employer Identification Number (EIN) field if this submission is on behalf of a US company.

Export Item

The Export Item section is of the critical importance:

  1. Select the “5D992” code for the ECCN. This code corresponds to mass market software.
  2. Leave APP blank
  3. Enter the software application name into the Product / Model Number as it would appear in the App store, for instance “STRIP
  4. Leave CCATS Number blank, unless requesting an update to a previously approved application
  5. Enter your company name as the Manufacturer

Finally, a short technical description is required. This exact text will be printed on the final approval documentation so it must include details of the software including it’s purpose, algorithms used, etc. The description should be brief, as the description is limited to 250 characters. Here is an example we used in a submission for STRIP:

STRIP is a secure database application for the iPhone/iPod touch that can store sensitive personal data like passwords and financial information. Strip uses a password based key and AES-256 to encrypt data before it is written to it’s database.

Click the Add Export Item button to attach it to the request.

Additional Information

The Additional Information section must include the final details of the submission, including descriptions of the supporting documents that will be prepared and attached in the following steps. The description should clearly point out how each document addresses the relevant EAR requirements, for instance:

This submission includes three attachments.

The first is a letter of explanation and a request for Mass Market Encryption certification. This letter directly addresses Note 3 requirements for Supplement 1 of Part 774.

The second attachments is a technical specification for the product and directly addresses all items under Supplement 6 to Part 742.

The final attachment is a screen capture of our product website that we will be using for marketing purposes.

Save the application as a draft after completing the additional application section. We’ll revisit it after preparing the supporting documentation.

Step 4. Document Preparation

The online application is just a high level summary for the DOC. The real content and application descriptions must be prepared in separate supporting documents.

The exact requirements are spelled out in parts, 742, 744, and 748 of the EAR. The requirements are buried within about 250 pages of regulations, but we’ve done most of the hard work by creating document templates based on our previous submissions to meet the requirements:

  1. Introduction Letter addressing Note 3 requirements for Supplement 1 of Part 774
  2. Technical specification addressing Supplement 6 to Part 742

These documents are intended to provide a foundation and outline for submissions. They also contain specific language for applications built using our SQLCipher encrypted database library. If you’re not using SQLCipher and OpenSSL you’ll need to modify the appropriate section.

Carefully read each document, section, and question. Make changes as necessary to ensure the response addresses the details of your application specifically and accurately. While we’ve successfully had previous applications approved using similar documents, your mileage may vary. DO NOT JUST SEARCH AND REPLACE THE APPLICATION NAME AND SUMBIT THE RESULT – it is YOUR RESPONSIBILITY to make sure the supporting documents are correct. Make sure you answer all questions accurately and make truthful statements. For instance, don’t answer ‘no’ if the user actually can alter the method of encryption just to get approval. Bad things can happen.

The DOC also wants to review applicable marketing materials as part of the classification process. Screenshots of the product website or App Store page can be used as supporting documents to meet this requirement.

Once all of the supporting documents are completed and reviewed for accuracy the should be uploaded into the SNAP-R. Note that the system requires that all documents be converted to PDF before submission. Open up the draft work item and click View and Manage Supporting Documents.

Convert each document to PDF and upload it to the system. Each document should be assigned a descriptive title, author, publication date, and docuent types such as “Letter of Explanation”, “Technical Specification”, or “Other” respectively.

When you are finished the work item form will list out all of the attachments.

Step 5. Submission

Take one final pass through the Work Item to make sure all items are complete. Click Check For Errors and if everything is fine then Preview Work Item to Submit. Review the final application document and then submit.

Finally,fill out the electronic signature information on the next screen to finalize the submission.

All most done!

Step 6. Hardcopy!

Unfortunately, the online forms aren’t sufficient to complete a submission. The final step is to make hard copies of all application materials and mail them to the ENC Encryption Request Coordinator at Ft. Meade. Astute readers will recognized the address as NSA headquarters.

First, print off a copy of the online work item application from SNAP-R. Then print each of the supporting documents and the screenshots or marketing materials. Paperclip each document together.

Within 2-3 hours of submission SNAP-R will have assigned an Application Control Number (ACN). Each document must also have this ACN written on the top of it. Log back into SNAP-R and click List Work Items from the left navigation. Look for the ACN column of the work item list. It should contain an identifier starting with ‘Z’, like “Z234567”. If the column is blank wait a bit longer, or call the DOC coordinators for a status. Take the Z-number and write it on the top of each document, like so:

Reference ACN: Z234567

Package up the application form, supporting documents, and marketing material printouts. Take them to the Post office and send them via overnight mail to the Encryption Request Coordinator address at the bottom of this DOC page, currently:

Attn: ENC Encryption Request Coordinator
9800 Savage Road, Suite 6940
Ft. Meade, MD 20755-6000

These documents must go out via overnight express mail the same day the application is submitted to the DOC or the the application could be delayed or rejected.

Step 7. Patience…

The approval process will take between 30 and 45 days to complete. If everything goes well the DOC will send out an email indicating the approval of the application and will mail you a classification document containing the CCATS number.

Step 8. Submit to Apple

If you’re lucky at this point it’s been about 40-50 days since starting the application process. Now it’s time to submit the software to Apple for review.

Log into iTunes Connect and start an application submission. On the first screen will ask 4 questions related to the software’s encryption.

Answer yes to each, and then click “Choose File”. Upload a high resolution scan of the commodity classification document and continue with your application upload. This will flag the iPhone application for additional scrutiny by Apple’s export team. Expect an an additional delay of 3-4 on top of the normal application review period.

Conclusion & Disclaimer

We have successfully used this process to submit multiple applications to the DOC for review. However, we must caution that your experience may be different. Every application is reviewed and approved on an individual basis.

If you have trouble there are a number of other resources at your disposal. There are detailed instructions online and a dedicated helpdesk for SNAP-R. BIS Export Counselors are available to answer questions about the review process and specific EAR requirements. They really are very helpful. You can also consult an attorney that specializes in export law.

One final reminder – we aren’t attorneys or export control experts. We are just a company who had to figure out this complex process to sell our own software. We decided to document it to save you the trouble, but we are providing this information AS IS, with no warranty whatsoever. Use this information at your own discretion and consult an expert if you need guidance. If you follow these steps but still end up inside a federal penitentiary, or worse, Guantanamo Bay, don’t come crying to us!

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Waiting on Palm for a Native SDK

Permalink - Posted on 2009-07-29 00:00

We’ve been getting a lot of emails recently asking about our plans with regard to Strip and Palm’s new platform WebOS. We really appreciate the inquiries! At the current time we don’t have any plans to build a port of the new SQLCipher-based Strip to WebOS / Palm Pré. It’s not that we don’t want to do it, it’s more a matter of a lack in the SDK.

Palms Mojo development framework, the SDK they are providing for developing apps on the Palm Pré, only provides for development in Javascript, HTML, and CSS. There is at this time no support for developing native applications, or applications with access to native libraries. SQLCipher is a specialized build of SQLite, written in C and using OpenSSL, that provides for transparent, page-based encryption of an embedded database, and it’s at the core of Strip. Without a native SDK, we simply can’t compile it for the platform and get to work.

We have made inquiries, and we’ve heard of some development shops getting special access, but so far we’ve not heard anything. If you’re a fan of Strip and you want it on your Palm Pré, it probably couldn’t hurt to chime in and send Palm your support for this.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

iPhone 3GS Hardware Encryption Considered “Useless”, even Harmful

Permalink - Posted on 2009-07-29 00:00

We agree with that assessment. When the iPhone 3GS was announced, Apple listed hardware encryption and better security among the new features, aimed at getting a better foothold in the enterprise marketplace where Blackberry tends to be the dominant mobile platform, and where corporate security policies can effectively shut out insecure technologies.

Surprising no one, details from Apple are scant, but based on their carefully worded statements it would appear that full-device hardware encryption (with the key on the device) was being employed to provide fairly scant security features. In fact, it poses the appearance of security with the potential for many considerable attack vectors. At the time of the announcement, Stephen wrote:

While there is no doubt that the encryption features will enhance iPhone device security, it remains to be seen how the practical improvements will compare to the launch hype. I strongly suspect that highly sensitive information storage will still require dedicated security applications.

More information is now coming to light. Brian X. Chen has an article in Wired titled, Hacker Says iPhone 3GS Encryption Is ‘Useless’ for Businesses, further making the case that what Apple is providing isn’t what security-conscious professionals really require:

Apple claims that hundreds of thousands of iPhones are being used by corporations and government agencies. What it won’t tell you is that the supposedly enterprise-friendly encryption included with the iPhone 3GS is so weak it can be cracked in two minutes with a few pieces of readily available freeware. “It is kind of like storing all your secret messages right next to the secret decoder ring,” said Jonathan Zdziarski, an iPhone developer and a hacker who teaches forensics courses on recovering data from iPhones. “I don’t think any of us [developers] have ever seen encryption implemented so poorly before, which is why it’s hard to describe why it’s such a big threat to security.”

Obviously, we have a vested interest in making the case for our own security applications for the iPhone and why we think they are so useful and provide such better security. But the most glaring thing about all this is Apple’s lack of disclosure, and poor implementation with the appearance of security. It’s not suitable for our own personal use, never mind in the enterprise environment.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Open Letter: Worth more than “Free”

Permalink - Posted on 2009-07-24 00:00

An irate user sent us an email today about Strip, our iPhone data vault software. She wasn’t mad about a bug, or a missing feature. She was upset that we were charging money for it.

I am highly annoyed that your company would jump from a free app to a $9.99 app with such a limited number of entries. No, I will not be upgrading.

We don’t take this kind of feedback personally, but do feel it warrants a response. We decided to reply in an open letter explaining the motivation behind our software pricing.

Dear Customer,

I’m very sorry to hear that you’re upset about the charge associated with upgrading Strip. The App Store is filled with inexpensive applications: some of these are low quality, hastily developed, and quickly released. Hopefully you recognize through your evaluation that Strip doesn’t fall into that category.

Strip took 6 months for our team to build and represented a big investment for our company. We spent countless hours refining the design and adding features to make it easy and pleasing to use. Working with a large group of beta testers delayed our release but ensured the application was stable and high quality. It took months for us to wade through documentation and approval with the US Government to have Strip’s encryption classified for mass market release. On top of this we continue to provide support, bug fixes when problems occur, and new feature updates. We even released our secure database library as open source software to the community so that other developers can use it.

Strip Lite is as an opportunity for everyone to try the software without purchasing it first. That’s also why the description in the App Store clearly explains that the Lite version is an evaluation limited to a small number of records.

We are a small business that builds software. We have employees and families, and our objective is to make money. Our software, and the time that we spend building it, is worth more than “Free”. It’s worth more than $0.99 cents-a-pop, too.

What’s more, the vast majority of our customers agree. We have a growing community of active users that were happy to purchase a quality piece of software at a reasonable price.

The decision to upgrade or stop using Strip is entirely yours, but I really hope you will reconsider its value. Thanks so much for your time.



Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Staying Motivated and Creative

Permalink - Posted on 2009-07-23 00:00

I saw this post from The Flying Jalapeño Lives just now, wherein Corey poses a couple of methods for staying motivated as a programmer, particularly somebody works solo or remotely, possibly out of his or her home. They aren’t bad suggestions, but I figured I’d respond with another take on things, since I have some first-hand experience with the matter.

No amount of mental tricks and playing with your IDE can make up for the importance of real human company. For about a year and a half I worked out of my home, just me and the cats, and it was incredibly isolating. When you work alone all the time, you begin to actively seek out distractions on the intertubes (as if there aren’t enough to begin with!) Being around other flesh-and-blood people is critical to staying grounded, and really helps me to focus and stay motivated, rather than distracting me. I’m not the only member of Team Z in a co-working setup, either. Our man Steve Kradel is a recent convert down in Philadelphia.

I mentioned my problem to Lennon/R-Coder last year at RubyFringe, and he said something to the effect of, “dude, you need to get out of your house! Find a coworking space!” I’d never heard of such a thing, but The Bossman went and looked up Williamsburg Coworking, and I’ve been there almost every work day since. My productivity shot up by a lot (we checked, using Tempo!) I get to work with really smart people like Alexis and Stan from Percent Mobile, I’m in a creative environment, I have people to talk to, and it’s really easy to stay focused. Can’t recommend it enough. If you’re looking for a space in your city, get in touch. There’s quite a network of coworkers out there (ours spread across some 47 cities) who’d be glad to have your company, and I’d be happy to put anyone in touch, just send me an email.

On a tangential note, I saw this great interview with Amanda Palmer, which has some delicious quotes about staying on your work (or not!):

I got to a certain point where I realized that the voices in my head were working on an old, conditioned blueprint of what it actually means to be fulfilled and happy.

Slowly, I started to let that blueprint go and starting to improvise another one, just for the day. And now, I draw a new blueprint every day and then set it on fire at the end of the night. I think the key for me has been realizing that every day and week and month is an improvisation…and that I can never define my success or happiness by last week’s measuring stick…I wrote when I feel like it, and I don’t feel catholic guilt anymore when I don’t.

Interesting stuff, and as a song-writer myself, I know that guilt, I know it well. Obviously, composition and programming aren’t the same thing, but you do have to know when to walk away and recharge. Having other people around can help prevent you from banging your head on your desk instead of relaxing and trying to look at things differently. It’s time we all started valuing one another’s company more.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Trading Ideas from #futureruby

Permalink - Posted on 2009-07-16 00:00

I’ve been meaning to get a post up about Future Ruby, the fantastic conference hosted by Unspace last weekend in Toronto, but I haven’t had a chance. Since we got back our team has been playing catch-up, so I wanted to pause quickly to highlight some interesting developments since the conference.

I got to chatting with Dan Grigsby about a possible means of offsetting the iTunes App Store’s negative review bias, and he went and made it a reality, with sample code and all. Very cool.

There were a number of inspiring and challenging presentations that have inspired post-con discussion and debate. If you search on the #futureruby hash tag on Twitter you’ll find all sorts of links to discussions, comment threads, summaries and even video. Looks like even BoingBoing took notice! Many of the attendees (including myself) have taken to watching the tag to keep up and keep in touch with each other.

More thoughts to come tomorrow, there’s more testing to do this afternoon on Tempo for the maintenance update.

IE users on Tempo have been dropping off

Permalink - Posted on 2009-07-16 00:00

Like most web programmers out there, we’ve wasted spent some “kwality” time trying to get our page layouts for Tempo to work and look good in Internet Explorer 7 (we don’t support IE6). The advent of IE8 has made this a bit easier by providing a compatibility mode for going back and forth, helping us to identify needed fixes for our ie7.css file.

As we delayed another over-due set of updates in order to fix some IE issues, I started to wonder what percentage of our users actually use IE, and if that percentage justifies spending all this time. According to Google Analytics, only 10.25% of our visitors (which is a larger group than our active subscribers) in the last two months were using some form of Internet Explorer.

Ten-odd percent of our users certainly warrants us taking the time, but it’s still a surprising metric. Furthermore, it’s down 1% from July of 2008 when IE clocked in at 11.28% of our users, despite the fact that our traffic and active users have climbed substantially from that period. I’m not sure if this indicates a preference on the part of our customers and our would-be customers, or if it means we haven’t provided IE users with the kind of interface they really want.

That said, we’ve been hard at work on a number of adjustments to Tempo’s interface to tidy things up, and many of these adjustments specifically address some display issues in IE7. We’re working on it, dear customers!

The Case for Strip-ing

Permalink - Posted on 2009-07-15 00:00

When people ask us if we have any iPhone apps in the iTunes App Store1 and we tell them, “yes,” they invariably get excited. Their expectations of some cool, new, game-changing technology seem to dampen when we tell them about Strip (unless they are cryptography enthusiasts). However, we often hear back from many of these same folks a few months later, telling us that they use Strip all the time, and can’t live without it.

Our friends and colleagues are starting to get worried about the bazillion sites on which they’ve set the same password. Maybe I’m preaching to the choir here, but we all do it from time to time. There’s just too many to track: car insurance websites, bank accounts, social networks,newspaper site, some online community where you registered to leave comments, some new online tool you want to try out, a thing here, a thing there. You probably sign up for something new on the Inter-tubes at least once a day.

As far as settings passwords go, you really have two options:

  1. Set something different for each one and actually remember them all (good luck with that).
  2. Use some clever ‘p4ssw0rd123’ or variant for all of them (e.g. p4assw0rd-facebook).

Choosing option 1 is the most secure, and the most difficult. Option 2 leaves you exposed to massive risk – one good guess, a password cracker, or a break-in on a site that didn’t hash your non-unique password could allow an attacker to get into your online bank account. Many sites e-mail your password back to you – then your ‘p4ssw0rd123’ has gone through quite a few tubes and machines in clear text by the time it arrives in your inbox. Which is also on someone else’s computers, isn’t it?

The basic work-flow of Strip was designed to fix this very problem, and it seems to get people hooked. Say you want to sign up for some new web service to try it out, but you don’t want to use that bank account or email account password. You hit the sign-up screen, you get to the password field and you fire up your iPhone (or Palm, for the Old School-ers), open up Strip, create a new entry, and generate a random password. Save it in Strip, set it on the site, and you’re done. Sure, it introduces an extra step, but now your brain isn’t filling up with garbage and you’ve drastically reduced the risk to your online information and identity.

Obviously, Strip itself could be a point of potential failure. If you left your iPhone (or Treo) in a taxi like many of our customers have done, you wouldn’t want the cabby or the next occupant to have access to private networks and mail servers. To mitigate this we use high-grade, peer-reviewed open source cryptography to make it very unlikely that anyone will ever unlock your copy of Strip before the heat death of the universe (so long as you set a strong password!) At this point we’ve got 12 years of experience under our belt, and the code is out there for anyone to see, improve, and criticize. We will continue to update Strip’s encryption engine, SQLCipher, to stay on top of the latest encryption updates, protocols, and techniques. We’ve even strengthened SQLCipher since we launched Strip in the App Store. Don’t take our word for it, have a look yourself.

1 Overheard snark last week at FutureRuby: “They managed to build an App Store without actually building an App Store.”

Tempo Maintenance Tonight

Permalink - Posted on 2009-07-07 00:00

Starting at 11pm EDT tonight, Tues July 7th, Tempo may be briefly unavailable while we update the application. We’re moving the beta to production!


Permalink - Posted on 2009-07-07 00:00

I have somewhat consistently maintained that the Apple Push Notification Service for iPhone developers is a really bad kludge. I still stand by that! It’s a poor stand-in for the local system scheduler that’s already on the device.

That said, there’s a proper tool for every job, and APNS is absolutely perfect for Prowl:

Prowl is a Growl client for the iPhone. Notifications from your Mac can be sent to your iPhone over push, with a full range of customization and grace you expect…. As soon as a Growl notification pops up on your Mac, Prowl will forward it to your iPhone or iPod Touch over the push notification service found in iPhone OS 3.0. Which notifications are pushed is configurable, allowing only the important messages to be delivered.

The possibilities there are really huge. Not to mention that it’s a geek’s dream, and perfect for sysadmins. Now you never need to miss those sweet nothings your desktop whispers in your ear when you’re out and about tolerating the company of other fleshy ones. Imagine:

  • unix box: OMG disk is full!
  • mail server: OMG OMG OMG I/O SPIKE!

All kidding aside, this is a nice bridge to between web/internet services on a dedicated connection and mobile devices, and it in no way involves text messages. Anything that cuts into the bottom line of the Text Message Tax Collectors makes me smile.

Another recent innovation with APNS is the arrival of the first middleman, Urban Airship, which handles the details of maintaining state with APNS so you don’t have to construct the infrastructure yourself.

Image snagged from the Prowl website.

Deep Thought

Permalink - Posted on 2009-07-02 00:00

The Well was the first social network.

Although, I’m just being a contrarian to the social network hypers. The good old BBS probably pre-dates the Well, anyway.

Tempo’s New Look: An Introduction

Permalink - Posted on 2009-07-01 00:00

In preparation for taking Tempo’s new design out of beta and moving it to production, we’ve put together this overview of what has changed.

Will I still be able to use the old interface?

No, this is it! We’ve spent quite a lot time and hard work responding to your feedback and incorporating it into the new design. We know it’s not going to make everyone happy, but we’re pretty certain that after you use it for a little while, you won’t miss the old skin.

We are planning to make the move as early as next week, so if you still haven’t taken a look at the new version, if you still haven’t told us about that one thing that’s missing that you really need, now’s the time to try it out and get in touch!

The Layout

The basic layout consists of a left-side navigation bar, a footer (unseen in the image above) and desktop-window-like modules in the main content area. What you are looking at above is the Time screen, which is new to Tempo. Well, sorta.

In the initial version of Tempo, there was one screen that did just about everything – entering new time, reporting, viewing, exporting, etc. This became more and more cumbersome as we added features. For starters, you had to modify the current report view just to see your own time! In the second major revision of Tempo, we tried splitting a ‘My Time’ screen off of the main reporting screen, but it was poorly received. Our design skills just weren’t up to snuff, so we reverted.

In the new design, however, I think we’ve really nailed it, thanks to nGen Works. The Time screen gives you stats pertaining to your recent performance and a full listing of all your time (reflected in the API, as well).

It also allows you to easily switch between full-form entry of time, with all the various options laid out for you, and the simple command-line entry that we prefer here at Zetetic:

In the image above you can see the new tagging setup we blogged about recently, which includes support for Suggested Tags on a project! Here’s the command-line entry form, on the same Time screen:

One other big change here is in the table showing entered time. Have you ever found yourself looking at a data set, and thinking, “Hmm, what else is on this project?” Or, “I’d like to see all entries this goofball has tagged with ‘foo’.” Now, it’s as simple as clicking on the labels on an entry to dial up a new report on the Reports screen, fitting that criteria!

But, I’m getting ahead of myself. Before we discuss reports, let’s take a look at another one of the major design changes:

The Sidebar

One of the biggest changes is the introduction of a sidebar for navigating the application. There were a couple of things we wanted to emphasize here, aside from providing quick and easy access to the main areas of interest on the site.

The Add Time link produces a modal dialog (sample) allowing you to enter new time from anywhere in the application, even the Project or Account screens. Your Reports links out to a full listing of each of your saved reports, with creation dates and details, and the report links below it provide you quick and easy access to those reports you need to run at the end of each billing cycle.


The Reports screen is what used to be the one-stop-shop for all reporting functions in Tempo. This is probably the interface that changed most dramatically:

Still at your fingertips alongside Tempo’s powerful reporting are the charts, exports, invoicing, locking, batch-tagging, and saved reports features. There’s something about these various features that always threw new users, and hopefully this new design makes it clearer: they all pertain to the current report! E.g. If I dial in all time billed to Spacely Sprockets for the current quarter and then click on Export or Invoice, I’ll be exporting or invoicing all the time billed to Spacely Sprockets for the current quarter!

For those of you who are used to Tempo, these functions haven’t changed much, beyond their skin:


We needed to give the Projects screen some love to bring it into the fold of the new design, and also to pave the way for new features. The project listing itself isn’t new, but hopefully breaking out the team management helps to make things a little bit more obvious for new users:

Coming soon: individual project dashboards! Each project will have its own page where we can provide project-specific tracking and statistics.


Finally, the account screen got a facelift. This is where all manner of things are handled, from billing to user profile to account preferences, it was all here and it was getting to be a long mess! This time around we’ve sectioned things off to make it way easier to work with.

That about wraps up the major changes in this round of hacking. It’s mostly design-centric, aside from some non-insignificant API changes you should be aware of, if you have your own software that interacts with Tempo’s API. We’re not done yet, there’s still more tweaking to do, more fixes to implement that have been sent in by our always-helpful customers! There’s still time to comment on the changes and make your voice heard, please get in touch right away if you haven’t already; we’re looking to push this out next week, barring any show-stoppers.

Quote: Only the Art is Irreducible

Permalink - Posted on 2009-06-29 00:00

Musician and writer Tris McCall:

michael jackson’s death may hasten the day when we put aside the garbage once and for all and hear only the music. but that was bound to happen anyway. gossip is gas and dissipates; only the art is irreducible.

A tremendous and inspiring thought.

New article published: migrating data from Lite to Paid iPhone applications

Permalink - Posted on 2009-06-29 00:00

Stephen has a new tutorial published over on Mobile Orchard, in which he introduces a means of migrating the data from a so-called “Lite” application to the paid version. A lot of apps don’t provide this facility, and others use (or suggest using) a server component, which can add considerable development overhead. Our solution, which we use for Strip and Strip Lite, is really easy to implement and the migration happens on the device itself. Check it out and let us know what you think!

The Unofficial iPhone SDK Feedback Project

Permalink - Posted on 2009-06-26 00:00

Now this strikes me as a very good idea:

…there isn’t an acceptable way for iPhone developers to constructively provide feedback with gravity.

Sure, Apple takes bug reports. However, the system is effectively opaque. Is the submitter alone with his/her issue, or does it effect a silent majority of developers? Furthermore, while bugs are objectively resolvable, they’re a subset of the much larger category of subjective feedback, e.g., policy/behavior changes.

There is evidence that Apple responds to constructive feedback: They dropped the NDA, they’ve reversed app rejections (e.g., Eucalyptus), and there are reports that they actively try to avoid bad blood.

So, to provide the iPhone developer community with a mechanism to collectively submit constructive feedback with gravity to Apple, I’m pleased to announce: The Unofficial iPhone SDK Feedback Project

I’ve already created a nugget of feedback, go vote it up and help out your fellow devs!

Fresh Gear

Permalink - Posted on 2009-06-26 00:00

I’m very excited, our man Bret Morgan from Bands On a Budget just sent us a pic modeling our new t-shirt:

I know it’s not as design-intense as those South-East-Asian Zetetic threads (I never did figure out how to order from them), but I’m stoked. We just ordered these to have for friends and fam, but if you’ve got to have one, hit us up.

Rocking the Podcasts

Permalink - Posted on 2009-06-25 00:00

I spend quite a bit of time in front of a screen all day hacking away, so I love to put on WNYC in the mornings, sip my pot of coffee and get to work.

Lately, however, I’ve taken to following more and more podcasts. This morning, on the walk from Greenpoint to Williamsburg Coworking I found myself listening to Stack Overflow, which is getting more and more entertaining as the weeks go by. The guest on the current episode is Damien Katz of Couch DB fame, who we saw give an incredibly inspiring talk at Ruby Fringe last year. The conversation ranges from fascinating computer science to some lively anecdotes about IBM (“full of douchebags”), Erlang, and Lotus, which keeps re-appearing in tech conversations lately. I’m only 40 minutes in, and it’s been fascinating.

Yes, I know I’m a nerd. But if you’re in the business, this is pretty interesting stuff. And we are totally in the business.

Another ‘cast that I look forward to every week is Dan Grigsby’s Mobile Orchard Podcast, focusing on iPhone development and the iTunes App Store. Dan keeps the topics very technology focused, but some of my favorite moments are when the guests (who are always iPhone developers) and Dan (a great developer himself) go into the business aspect of things. Few people have such a magnetic focus on market trends and data, and it also frequently turns up in Dan’s writings. Full disclosure – we were interviewed recently for this one.

And then there’s Savage Love, which is not even a little bit tech-related; it’s Dan Savage’s relationship advice column gone wild. Not safe for children, no, but very, very entertaining. This one can get a bit distracting, I’ll admit, but I absolutely cannot help but listen every week, it’s great.

Rocking the People

Permalink - Posted on 2009-06-25 00:00

This post is a tad off-topic, but I know some of us share this sphere of interest. I recently got a great write-up for a show my band played in Brooklyn:

There are no airy disco beats, no acoustic jams, and certainly no taking of prisoners as Ben Franklin is a live act that goes for the jugular with every song. Even the borderline kitschy, “Timmeh,” dedicated to our Treasury Secretary Tim Gieger [sic], is a sludge rock tune that sounds like Dinosaur Jr.’s J. Macis if he ever got the rocks removed from his mouth and asked, better yet demanded, “Where are my taxes?!”

Not bad. I didn’t know that we could be described as “neopunk,” and I never would have thought “sludge rock,” but this is not a review to complain about.

How Can You Go Wrong With Giant Robots?

Permalink - Posted on 2009-06-24 00:00

Apparently Michael Bay shows us how. Very funny review of the new Transformers movie, via @warrenellis.

Future Ruby Panels

Permalink - Posted on 2009-06-24 00:00

As the Future Ruby conference in Toronto draws near, I’m getting more and more excited about the event. Within the last day or two the full list of speakers
has been posted on their site along with summaries of the talks, and it’s eye-popping. They range from the philosophical to the far-out to the highly technical. Programming with DNA modules? What?

def MajorKusanagi
mixin homo_sapien, cyborg

add :xray_vision, :therm_optic_camouflage
suppress :cancer

I’m particularly looking forward to experiencing another Giles Bowkett presentation, learning about the Rhodes, Cucumber and Tokyo Cabinet projects from the people behind the tech, and attending another FAILCamp.

We did a lot of chatting with people at Ruby Fringe last year, it’s a good place to put your finger in the air and see which way the winds are blowing. I’ll be curious to see how many of the folks are moving into iPhone and other mobile platform development.

I think there are still a few tickets left — you should come! You don’t need to be a Ruby programmer to dig on a lot of this.

Expanding the Tempo Beta

Permalink - Posted on 2009-06-24 00:00

As the regular readers and some of our customers know, we’ve been running a limited beta test of the newest version of Tempo. At this point we’ve gotten quite a few big bugs and show-stoppers out of the way, and we’re ready to let everyone have at it. Hopefully, this will help us uncover any lingering issues, nagging nuisances, and hidden bugs. It will also introduce the new interface to everyone! We hope you not only find it easy on the eyes, but more importantly that you find it extremely functional and efficient.

We worked very closely with nGen Works to design this interface, bringing to them all of the concerns and difficulties our customers have expressed over the last couple of years. It’s a radical change, design-wise, although all the functionality we know and love is still there and improving. It will take a little getting used to, for sure, but we’ve found that after even just a little time in the new interface we can’t bring ourselves to use the old one anymore.

Without further ado, you can join in the beta here:


  • Your web-browser will likely balk at the SSL certificate with a warning – we assure you that it’s safe to ignore this warning and proceed, it’s a self-signed cert.
  • This is live data, your data!
  • You can always go back to the current interface at this link.

So kick the tires, spend some time with it, and tell us what you think. The end-of-month is coming up, we’re particularly curious to see how it holds up for others when it’s time for billing — it was all aces for us last month (after we fixed a few bugs).

Amanda Palmer Shows Them How It’s Done

Permalink - Posted on 2009-06-24 00:00

One of my favorite artists, Amanda Palmer of the Dresden Dolls, has managed to make more money over Twitter in 10 hours ($19,000) than she has from her recent major-label released album ($0). She’s got a great write-up describing how she did it, but the main points are brilliant and obvious — she’s dealing direct, she’s giving the people what they want. This isn’t so much surprising as it is one of those bell-weather moments for the music industry. It’s also the first time I’ve actually heard of anybody really making money off Twitter, and it’s nice to see it’s not one of those “Internet marketing experts.”

Keep the Criticism Coming

Permalink - Posted on 2009-06-16 00:00

There were some very discouraging signs from Apple out of the WWDC with regard to iPhone developers and the App Store review process, but it sounds like the pile of online criticism is having some effect on them:

I also learned, through various statements and implications, that the App Review team tries to actively avoid major blog publicity about bad rejections, and it’s something they take very seriously. This means, fortunately for us as iPhone-dev bloggers, that we matter and we should continue to bitch incessantly whenever anything is rejected for an invalid or ridiculous reason..

iPhone SQLite Encryption with SQLCipher

Permalink - Posted on 2009-06-16 00:00

Just a quick note that Stephen’s tutorial on building encrypted iPhone applications with SQLCipher has been published by the fine folks at Mobile Orchard. Thanks, Dan!

Getting Tagging Right in Tempo

Permalink - Posted on 2009-06-16 00:00

This post is mostly concerned with the beta version of our time-tracker, Tempo. Every time we do a redesign round, we try to fix nagging issues with the UI, and I think we may have actually made a long-overdue improvement to how tagging works.

Being able to arbitrarily tag time entries is one of the things that makes Tempo’s reporting so flexible and dynamic, but it comes with some trade-offs over more static associations that other time trackers use (e.g. Activities, Tasks). One of the many benefits of using tags over tasks is that there’s no need for an administrator to set up your activities in advance – when you need a new label for an entry, you just use it. However, such dynamism can be pretty confusing to those who are entirely unfamiliar with the ideas of tagging and meta-data — which is a lot of people. Some new users end up looking at the new entry form and ask, “how do I designate my time?”

Once you explain to new users how tagging works, their next obvious (and reasonable) question is “how do I know what tags to use?” We were recently assisting a new client shop that was starting to use Tempo, and one of the main concerns there was the possibility that people might use different tags to label tasks that needed to be grouped together, that one person on their team might bill their consultation hours as ‘meeting’, while another person might use ‘meetings’. Clearly, we want new users and teams to be able to hit the ground running, so this needed to be fixed1.

To make matters more interesting, our current interface could become quite cumbersome for anybody using tags extensively. The control for adding tags is just a text-field, so all you need to do is type them in. But users sometimes want and/or need to see the tags they’ve already used. To solve this we provided auto-complete (a type-ahead suggest) on the field itself, so that if the user pauses while typing, suggestions are given based on tags they’ve already used. In addition, there’s an optional display of all tags on the selected project that the user can choose from. Predictably, this list gets pretty big, pretty fast:

What to do?

The first thing we decided to do was to give projects a set of “preferred tags”. When a user sets up a new project, she can now assign a list of tags that her teammates could/should use when billing their time:

From there we put together some custom SQL to roll-up the most frequently used tags on a project (the top ten), as well as a union of those frequently used tags with the project’s preferred tags. It’s this collection that we now display for a user in the entry form, below the tag field:

As the image shows, the preferred tags from the previous image now show up alongside popular tags on this project, such as “thuglife.” (Image was taken from our testing account.) If it’s not already apparent, the user can click on any of the tags, causing the tag to be added to the tags field. We think this solves a few problems:

  • It’s more apparent now that the Tags field is for labeling one’s time.
  • A new user can see what tags are commonly used and/or preferred.
  • The list of tags shown will only grow to 10 + (Number of Preferred Tags).
  • We retain the text field for quick entry by advanced users.

This updated interface is now in place on the Tempo beta site. If you’d like access to the beta, please get in touch, we could always use more help tightening all the screws.

1 It should be noted that the batch tags interface allows a project manager to combine, add, and remove tags from all entries in a report. This provides a facility for cleaning up entries that may have been mis-tagged.

Deep Thought

Permalink - Posted on 2009-06-12 00:00

GUID collision
inevitable, but we
live with the odds

Lifted from Mr. Kradel. I know, I cheated a little.

Tempo API Changes in Beta

Permalink - Posted on 2009-06-10 00:00

As we’ve mentioned before, we’ve got a beta of the next version of Tempo running. Most of the changes we made were with regard to user interface, but there are a couple of changes and enhancements (we think) to the API.

Accordingly, I’ve updated the API documentation (this was long overdue), leaving a beta notice on new methods and methods that are changing or going away.

If you have code that relies on the Tempo API, please get in touch with us so we can point you at the beta URL and help with the transition.

To summarize the changes:

  • We are introducing a reports API. It’s not complete, but it’s a start.
  • By popular demand, /entries, /projects, and now /reports support an id[] parameter for pulling specific entities in one call.
  • Searching for entries has been moved to /reports/search GET, replacing /entries/search POST. The /entries/search URL will redirect to /reports/search for now, but you’re better off migrating sooner than later.
  • The /entries GET method used to provide the same data you’d get from /entries/search if you didn’t specify any search criteria — a default context. Instead, /entries will now provide a listing of your own entries.

Some folks have asked us for JSON support, and while we’d really like to provide that now, it will be somewhat burdensome to implement, and will be available to us out-of-the-box in Rails 3, thanks to the provides/display feature of Merb.

Facebook Helper Lib

Permalink - Posted on 2009-06-10 00:00

Dan Grigsby has put together a helper for doing simple Facebook status updates from an iPhone app with a minimal amount of fuss.

Ignore the pirate-speak, that’s my lang setting on Facebook

- (void)session:(FBSession*)session didLogin:(FBUID)uid {
fbHelper.status = @"is learning to set Facebook status programatically from an iPhone";

Most excellent.

APNS: Help Wanted?

Permalink - Posted on 2009-06-10 00:00

Received in email from Apple:

As a developer actively working with iPhone OS, we would like your help in a private test of the Apple Push Notification service. For this test, we have selected AOL’s AIM Developer Preview for iPhone OS 3.0 to create a high-volume test environment for our servers.

I wonder if they are hoping to drum up interest and adoption of PNS, which has received a luke-warm reception from many developers. Putting that aside, I’m surprised to see Apple asking the developer community for help, pro bono. Considering how consistently poorly they treat third-party developers, that’s some nerve.

Wild Speculation on iPhone 3G S Hardware Encryption

Permalink - Posted on 2009-06-09 00:00

At the WWDC yesterday Apple announced the upcoming availability of their iPhone 3G S. In addition to a host of speed optimizations and new OS features Apple announced some new security features for the 3G S models: “Hardware Encryption” and remote wipe.

Ostensibly, the plan is that if your phone were lost or stolen you could issue a remote wipe and be confident that your data couldn’t be accessed. This is a feature that security conscious companies expect based on their experiences with BlackBerry’s “Erase Data and Disable Handheld” feature.

It’s interesting, however, to take a close look at careful wording Apple has used in their communications about the feature:

“iPhone 3G S offers highly secure hardware encryption that enables instantaneous remote wipe. You can even encrypt your iTunes backups.”

It almost sounds like the “whole device” encryption is primarily used to drive the remote wipe feature, not as an active security measure in its own right. If the encryption were used behind the scenes to secure the data on flash, then the remote wipe operation may not delete data. It could just remove the key and the device would “instantaneously” be rendered inoperable.

If that is the approach used there are some potential security implications:

  • If the encryption is fully in hardware, is it really securing the device while running, or is it just enabling remote wipe? Will a strong passphrase (> 4 digits) be required to unlock the key? It’s not likely if background operations and software are running.
  • Next up – the remote wipe trigger. It stands to reason that the device would need cell or network connectivity to initiate a remote wipe. Could you effectively disable remote wipe on an unlocked device by putting it into airplane mode and shutting off networking? What happens if you pop out and replace the SIM card?
  • Finally, there is the matter of the encrypted backups. The statement that you can even encrypt your iTunes backups implies that the feature is optional and that backups wouldn’t normally be encrypted. This may in turn imply that iPhone application data is unencrypted when read off the device during a backup and re-encrypted for storage by iTunes. This lends credence to the idea that the scope of the encryption is limited.

This is all wild speculation of course, since very few substantive details have been released. While there is no doubt that the encryption features will enhance iPhone device security, it remains to be seen how the practical improvements will compare to the launch hype. I strongly suspect that highly sensitive information storage will still require dedicated security applications.

Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

Writing Inspired Software Using Crypto

Permalink - Posted on 2009-06-08 00:00

Stephen and I were just interviewed by Dan Grigsby for this week’s Mobile Orchard podcast. The subject of the interview was SQLCipher, an SQLite extension that provides transparent page-level encryption for application databases. We talked mostly about how SQLCipher works, Strip (our iPhone security app built with SQLCipher), the iPhone build process, and DOC cryptography classification. We even managed to crack some NSA conspiracy theory jokes!

I realized afterward that we didn’t spend any time talking about why we like to work with cryptography and what drives us to do it. I suppose there are quite a few different motivations for us, but being that last week saw June 4th, the 20th anniversary of the Tienanmen Square Massacre, I found myself looking up Tank Man again. Mostly I was thinking about the legacy of his action and that iconic photograph, but I was reminded of why we value cryptography in software.

I have a number of friends who were in China during the recent Olympics for various reasons. One was there to document things that foreign media were forbidden to cover – like the many protests that were squashed outside the stadium. My buddy @noneck found himself in some “interesting” situations. He was eventually picked up by the authorities who went through his personal items, used his credit cards and forged his signature to deport him back to the U.S. You bet they went through his iPhone looking for potentially incriminating data.

Other friends were there to work with the Free Tibet movement, and they had iPhones, too. If they’d been picked up, and their phones contained incriminating information, notes, audio, contacts, etc, it could have severely compromised their freedom and safety, not to mention their particular mission. Obviously, these are chances that Noel and the others were all knowingly taking, but I’m glad they all made it home safe.

When they came back and told me their stories, I was struck by a thought. Smart phones present amazing capabilities, like video recorders and audio recorders, that can enable people to act as journalists and/or mobile broadcasters. Information is power but sometimes it is dangerous. Even having an audio interview on your phone could get you in a lot of trouble if you’re detained by people with an axe to grind.

Unfortunately the access code on an iPhone, like the on-screen locks of most mobile devices, is not a strong barrier to accessing data stored on the device. More and more of us are taking personal photos, videos, writing notes, storing valuable contact and business information, and utilizing applications to which we grant access to our online identities and social networks.

I want to create mobile software that treats this confidential data securely. That’s why we’ve been developing a suite of applications aimed at people who need to keep secrets. Strip, our password manager and data vault, can store all types of security credentials, financial and contact information. Codebook will soon fill the real need for a dedicated secure notes application, and will add some features that we feel are missing in the Apple Notes. We have a secure audio recorder under development, too.

More importantly, SQLCipher makes it possible for other iPhone applications to provide this kind of security without adding significant complexity. It’s open source and on on GitHub so we hope to see it used in other applications some day. The Mobile Orchard interview provides some details about how it works, and how we hooked into SQLite to provide the encryption. We’ll also be publishing a tutorial shortly describing how to set up the Xcode build process step-by-step.

If you’re going to Apple’s WWDC next week, and you find yourself looking to start a new app, we hope you’ll take a look at SQLCipher. Get in touch with us if you have any questions! We’re also eager to collaborate on development, especially with porting to other platforms (some folks have already show interest in Android, CoreData, etc).

Deep Thought

Permalink - Posted on 2009-06-08 00:00

I have enough trouble keeping my amp, guitar and pedals working without an issue on stage as-is, why on Earth would I want to involve my phone in that chain of potential failure between pick-up and and input jack?

As seen on Macrumorslive.com:

11:37 am Final demo — Line6 and Planet Waves. Together they are working on a solution to control your guitar and amp from your iPhone.

11:39 am More demo technical difficulties — trying to show how easy it is to switch between settings on an amp and guitar.

11:41 am Can adjust guitar tuning without actually physically changing anything — nothing can be demoed however, as the hardware accessory isn’t communicating with the iPhone.

That looks like fail to me.


Permalink - Posted on 2009-06-05 00:00

For anyone else out there who has code or services integrated with Twitter, you should take a look at this soon.

The Twitpocalypse is similar to the Y2K bug. Very soon the unique identifier associated to each tweet will exceed 2,147,483,6471. For some of your favorite third-party Twitter services not designed to handle such a case, the sequence will suddenly turn into negative numbers. At this point, they are very likely to malfunction or crash.

Time to haul out some BigInt action.

The Flag of Earth

Permalink - Posted on 2009-06-05 00:00

A rather cool piece of design, seen via Warren Ellis.

A Good Sign

Permalink - Posted on 2009-06-02 00:00

Every time we re-work the user interface for Tempo (we’re now upon our third major overhaul), the same thing happens and it doesn’t take long: I can’t stand to use the old/current interface any longer. The new design by nGen Works is no exception, it totally blows away the last iteration, and I think we’ve very nearly nailed down all the nuts and bolts.

I’m really excited to start the beta and get some of our customers’ feedback. A big thanks to those of you who wrote in asking to participate! We just have some administrative details to take care of and we should be rolling soon. If you’d like to participate in the beta and this is the first you’re hearing of it, just send us an e-mail.

A couple things of note:

  • You will be able to use either the beta interface or the old interface.
  • You will be working against your live, production data

Tempo - tagging bug fixed, call for beta testers

Permalink - Posted on 2009-05-29 00:00

Bug fix

We recently received reports of duplicate tags in Tempo. Turns out that it was possible to submit a tag with leading or trailing white-space from the batch-tagging interface, and this could cause the creation of a new, unwanted tag. This has been repaired and shouldn’t be a problem in the future. We ripped through the database and repaired incidences of this, but if you need us to make any other corrections to your account data, don’t hesitate to ask.

Redesign Beta

We’ve been working really hard on a redesigned interface for Tempo. Our friends over at nGen Works put together a fantastic new design, and we’ve been working it in and testing it over the last few weeks. We have a few more bugs and quirks to iron out, but we’re about ready to start the beta testing. If you want to participate in the beta, please send us an e-mail and we’ll let you know when you can have at it!

STRIP is dead! Long live Strip!

Permalink - Posted on 2009-05-28 00:00

We did it! The initial version of Strip has made it into the iTunes App Store, along side Strip Lite, a free version with a 10-record limit.

Strip is a password manager and data vault for the iPhone. It relies on SQLCipher for data storage – it’s our own build of SQLite that provides military-grade encryption of the entire database using the OpenSSL library. If you want to dig deeper, we have more information on the product site, and the SQLCipher page.

To check it out, download Strip Lite or take the tour.


  • Strip’s entire database is encrypted using 256-bit AES encryption
    (Compare to the weaker 128-bit encryption used by most other applications)
  • Extensible data fields, customizable labels and behaviors
  • Organize entries by category or view based on recent activity
  • Full text search across all database fields
  • Shake-to-create random password generator
  • Assign icons to entries for easy visual identification
  • 2-tap quick entry of common fields (e.g. usernames and email addresses)
  • Launch websites, dial phone numbers and address emails
  • Text or Quick-entry numeric access password input
  • Auto-lock when your device goes to sleep
  • Familiar interface similar in behavior to Contacts

Take a tour of the app if you’re still not convinced it rocks.

Ancient History

STRIP stands for “Secure Tool for Recalling Important Passwords.” STRIP first appeared for PalmOS mobile devices in 1997 and grew to be one of the highest rated, award winning security applications for the platform for over 12 years. This is a ground-up rewrite for the iPhone platform featuring improved usability and enhanced security. Thus, we’ve changed the name to “Strip”.

We discontinued STRIP’s development a couple of years ago due to the decline in the Palm OS platform. We’ve since added the source to Github for anyone who wants to take up the cause themselves. As we previously mentioned here, we will be providing a migration path to the iPhone version for Palm users ASAP, as well as updating strip-dump to support users moving to other platforms and software.


We’d like to extend our thanks to the many beta testers who helped us put together an excellent product. Extra special thanks goes out to nGen Works for designing Strip’s new identity, logo, and badge. Last but not least, the various articles and tips on Mobile Orchard, including a post on how to avoid app rejection, have been enormously helpful.

Mobile Orchard iPhone Workshop for Rubyists

Permalink - Posted on 2009-05-26 00:00

Our man Dan Grigsby is kicking a new course this Summer, in coordination with the aforementioned Future Ruby:

I’m teaching a discounted, adapted for Rubyists version of our Beginning iPhone Programming Workshop in Toronto on July 9-10 — the Thursday and Friday immediately preceding the FutureRuby conference…. Details about the class, including a FutureRuby discount, here.

The course is specifically aimed at would-be iPhone developers, particularly those coming from a Ruby background, who have no previous experience with the iPhone SDK. No need to know Objective-C! It’s also being offered at a big discount.

Dan’s a really sharp guy and gave one of the best presentations at Ruby Fringe last year. His class is already getting some great accolades from Ruby hackers, and his baby Mobile Orchard is turning out to be one of the most competent and in-depth resources on iPhone development. Well worth your ducats, especially if you want to start developing iPhone applications and need a way to bootstrap your knowledge.

Memorial Holiday Update

Permalink - Posted on 2009-05-22 00:00

It’s been a little while since we’ve given any updates on the goings-on here at Zetetic, so a wrap-up is in order.


First, some fun: there’s a brand of clothing apparel in Taiwan that shares a name with us. Accordingly, we need to print some rad t-shirts of our own. I could use a thuggin’ trucker hat for FutureRuby:


We don’t attend that many conferences, but we’re looking to change that. And last year’s RubyFringe was just fantastic. It’s hard to describe, but they’re not kidding: it’s a conference for Rubyists, not a Ruby conference. FutureRuby looks just as promising, and Stephen and I will be there. If you will be, too, make sure to say hello! This is what we look like.


“You gotta tame the beast before you let it out of its cage.” ~ Derrick Zoolander

We’ve undertaken a massive design and interface overhaul for our time-tracker, Tempo. Designed by nGen Works, it’s supra-suhweet, and near complete. We’re hammering out final issues with styles and cross-browser compatibility, and hope to offer a beta test to our users very soon. Hopefully we’ll have this live and out of beta by mid-June.

Strip for iPhone

Our encrypted data vault and password manager, Strip, and the accompanying Strip Lite, have been submitted to the iPhone App Store for review! We’ll let you know when it’s out there, and we plan on offering vouchers to our beta testers for being such a great help. It will be launching with a ton of great features, and it’s been heavily tweaked to make common operations quick and easy. Assuming we get through the approval process without refusal or pocket rejection. Fingers crossed.

We still have to work out a solution for users who want to bring over their Palm Strip databases. One of the reasons we haven’t provided a quick hack just yet is because this requires a secure solution. In fact, it probably requires a desktop-based solution. We’ve got a lot of people asking for a desktop version of Strip that syncs with the iPhone version over a local network connection. That goes hand-in-hand with our development road-map; we intended to provide some back-up/sync capability in the next major revision of the app. So I think it’s time to get cracking. Hopefully if you’ve been waiting for an exporter, you won’t mind waiting just a bit longer. In the meantime we’ll see if we can update Dave Dribin’s strip-dump to support Palm Strip v2 databases (currently it only supports up to v1.1).


SQLCipher is our fork of SQLite that provides page-level database encryption. A lot of people are asking us how to compile SQLCipher in an Xcode project in order to use it in iPhone apps like we’re doing with Strip and Codebook. We’re putting together an article that we’ll publish soon documenting the process step-by-step. In addition, Apple first required that we go through a munitions export approval process with the Department of Commerce and the NSA to get our app reviewed at all. That in and of itself is a really complex process, but we’ve got documentation on that, too, describing how to crank it out. We’ve even got some Google docs we can re-use for filling out the paper work quickly. So there’s lots coming in this area, stay tuned!

Open Source Development

Steve Kradel recently posted Zetetic.Chain to Github, a .NET implementation for the Chain of Responsibility design pattern.

Responding to Online Criticism

Permalink - Posted on 2009-05-20 00:00

There I was minding my own business and waiting for a sandwich in the deli last week, when a headline in the NY Times poked me right between the eyes: Snark Attack, by Teri Karush Rogers. As it turns out, renters and prospective buyers in NYC are increasingly turning to online forums and blogs to share their opinions about real estate listings. They investigate, they gossip, they ask questions, speculate on pricing, and they often mock the scams and bad deals. Like all things that involve online commentary, it can get quite ugly (or entertaining, depending on your perspective):

For their part, sellers and their brokers are seething over what they perceive as a lack of accountability, hidden or misanthropic motives, and the fact that defending one’s property — even correcting a factual error — can prolong or aggravate its turn under the collective microscope. Sellers also object to being typecast as Marie Antoinette in the French Revolution-style discourse.

My, how we protest when the shoe is on the other foot. It’s really difficult to find a place to live in NYC that isn’t a complete dump without living beyond your means. Many most of the people you’ll deal with will do their best to rope you into paying a lot of money for a dismal home. It’s a hard slog and only two things are certain: there will be roommates, and it will still be expensive.

It’s no surprise that in a contracting economy people are talking more, and that sellers and landlords (and their often-inflated prices) are the butt of the discussion. Why wouldn’t buyers and renters turn to the greatest communication tool we have to enable the sharing of expertise, bloviation, and derision? It’s also no surprise that there appear to have been no seething sellers or brokers who were willing to be quoted for the article, but I sure was hoping so. It has the trashy appeal of reality television.

Obviously, value is a matter of perception; that’s why brokers always try to get you to believe they will rent the apartment later that day to somebody else if you don’t hand them a deposit immediately. The process is weighted heavily against you and relies on the fact that most people don’t know any better. People having easy access to each other and relevant information about a property changes that dynamic dramatically. Despite my faux-proletarian schadenfreude for the landlords of New York, I have some sympathy; it must be really frustrating to have some stranger come into your house and then go online afterwards and rip the place apart.

The underlying question here is when to respond to online criticism, and whether or not it is helpful. If you are selling something, it’s a pretty important question, and whether it’s helpful is determined by your attitude towards the whole thing. People are going to make online commentary, and people are going to read a lot of commentary to help them determine how to best spend their earnings. If you the vendor are going to sit this out entirely, you are doing yourself a disservice.

We find ourselves in this position once in a while. People write about our products, they make comments on our blog posts, they share their thoughts with entire social networks instantly, and they are not always laudatory. Which is fine! They’re not always accurate, either. It’s been our experience that you’re always better off keeping cool and correcting the record to the best of your ability. Reasonable people can follow along and make their own judgements. If you’re still angry, you’re not ready to respond! There’s no need to try and change somebody’s mind about what you’re selling, but you definitely don’t want any false claims to go entirely unchecked by reality.

The article makes a point of mentioning that many firms forbid or discourage their agents from participating in online threads, seeing a real potential for disaster that I wouldn’t want to under-play. At the same time, in the world of selling things online, it’s not in your best interest to sit things out, just proceed carefully.

Alison Rogers, an agent with DG Neary Realty … noted that anger, defensiveness and denial will almost certainly set off a feeding frenzy, as will a post that seems to be written by the owner or broker without the appropriate disclosure. She favors correcting factual errors and countering negative opinions — but only to a point. “You don’t want to draw conclusions for people.”

In the emerging economy, it’s people who get this who will do a lot better than the folks who just get mad. You can’t really take your ball and go home, anymore.

Zetetic.Chain - Some love for .NET

Permalink - Posted on 2009-05-14 00:00

Today we released Zetetic.Chain on github as open source under a BSD-style license. The inspiration for Zetetic.Chain is Apache Chain, but Zetetic.Chain also takes advantage of some of the things .NET does really well without lots of dependencies, like reflection attributes (well, reflection in general), XML serialization, Remoting, indexer properties, and so on.

The Chain concept lets you work with commands, and stacks of commands, with a simple model—just say the name of the command you want to run, pass it an object in which to get and set state / results, and the Zetetic.Chain library takes care of the rest, keeping your implementation nice and clean. You configure the details of each command in a lean n’ mean XML file. Example:

<chain name="TellStory">
<command name="first" typeName="Storybook.WalkInTheWoods">
<add key="BoysName" value="Hansel" />
<add key="GirlsName" value="Gretel" />
<command name="also" typeName="Storybook.BirdsEatTheBreadcrumbs" />
<command name="ohno" typeName="Storybook.WitchInCandyHouse" />

Your code can fire off the chain of events simply by calling:

ICatalog catalog = CatalogFactory.GetFactory().GetCatalog("storybook.xml");
IContext context = new ContextBase();

So check it out, let us know what you think! Personally I know this library is going to become part of most of my ongoing projects on the .NET platform.

Cool Project: Timelines.com

Permalink - Posted on 2009-05-05 00:00

Scott McMillin posts over on mad.ly:

Timelines is a place for people to record and share history about any topic. We want it to be the Wikipedia of event-based information, but unlike Wikipedia we want everyone to have a voice and add their own perspectives (and photos, videos, etc) about events.

I’m a history dork, so I created an account already. I read history text books for fun (recently I started reading Voices of a People’s History of the United States), and nailing down what really happened is like trying to nail jelly to the wall. The more voices you have (even the biased voices), the more source material, the more you have to work with to try and discern what happened. This has the potential to be an extremely excellent resource.

Scott also gives some details on the infrastructure supporting Timelines.com. Looks like PostgreSQL drives most operations, but the actual event data and media appear to be stored in CouchDB. Very interesting.

JS Date Object Extensions

Permalink - Posted on 2009-05-01 00:00

In our time-tracking app, Tempo, we’ve got a date range drop-down menu, and that allows you to set the start and end dates for a report. Next to it are two text fields for the start and end date, which are over-ridden when the user selects one of the ranges.

This got a little confusing for users because the drop-down selection wasn’t reflected in the text fields, so I threw together some quick javascript for calculating the date end points client-side and setting the fields. In the end, I needed something like:

Tempo.activate_range_select = function() {
var $select = $j(this);

// for each interval, create a start and end date, and insert into date fields
var now = new Date();
var start_date = null;
var end_date = null;

switch($select.val()) {
case "today":
start_date = now.beginning_of_day();
end_date = now;
case "yesterday":
start_date = now.days_ago(1).beginning_of_day();
end_date = now.days_ago(1).end_of_day();

To get here, though, I had to work out these date calculation methods that you can see being used above. Those aren’t naturally occurring methods on the Date class in Javascript, but they can be if you write them yourself! And as you build out the simpler ones, they lend themselves to a full library.

So here’s a little library that extends the Date object with a big pile of handy methods: date.js It’s not all entirely original, I did find some tips out there in the wild and lifted a couple of handy things from the jQuery Date Picker’s date.js. But only a little.

A sampling of some of the methods:

Date.prototype.weekDay = function () {
// in ISO we want Mon = 0 and Sun = 6!
var day = this.getDay() - 1;
day = (day < 0) ? 6 : day;
return day;

Date.prototype.isLeapYear = function() {
var year = this.getFullYear();
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

Date.prototype.end_of_week = function() {
var d = this.copy();
d.setDate( this.getDate() + (6 - this.weekDay()) );
return d;

* figuring out the end of quarter:
# q1 = 31 + 28 + 31 = 90 + 2(leap)
# q2 = 30 + 31 + 30 = 91
# q3 = 31 + 31 + 30 = 92
# q4 = 31 + 30 + 31 = 92
Date.prototype.end_of_quarter = function() {
var d = this.copy();
switch( this.getQuarter() ) {
case 1:
// is this a leap year?
if ( this.isLeapYear() ) {
d.setMonth(0, 92); // allow overflow to set correct month and day
} else {
d.setMonth(0, 90)
case 2:
d.setMonth(3, 91);
case 3:
d.setMonth(6, 92);
d.setMonth(9, 92);
return d;

It’s a Big World

Permalink - Posted on 2009-05-01 00:00

ENTP’s founder Courtenay has an interesting comment up on his blog today:

As a side note, none of these people are from the US, which is a reminder to those of us North American-centric coders that there is a huge world of smart people out there.

Which is funny (or ironic), because on WNYC just now they were discussing 1) the surprising lack of H1B applications for the first time in a long time, and 2) proposals in Congress to make access to temporary worker visas more restrictive. Interesting times.

Tempo Maintenance Tonight: APR-23

Permalink - Posted on 2009-04-23 00:00

We’ll be interrupting service briefly tonight (23-APR-2009) on Tempo for a bit of background maintenance that should improve stability of the service. This will take place at 11pm EDT.

My Thoughts Exactly

Permalink - Posted on 2009-04-19 00:00

On the Apple Push Notification Service for iPhone OS/SDK 3.0, there’s an interesting comment thread over on Mobile Orchard. Ryan Daigle writes:

This has the potential to become a very expensive and heavy-weight hack to masquerade as a local cron system on the iPhone.

As Adrian Hosey reasons in that same thread, it really is a lot of fail-prone nonsense. There should be some kind of local device API for scheduling with launchd or whatever the OS uses.

Campfire could use Save Points

Permalink - Posted on 2009-04-16 00:00

Due to a series of unfortunate events I am in this spot where we lost some code, including some custom PL/SQL written for chart series and data calculations. Most of these queries had been pasted into Campfire at some point so I’m digging through transcripts looking for code to reuse.

Campfire is a web-based chat and collaboration tool; we use it all the time here at Zetetic, so much so that I’ve even taken to using a really great third-party client called Propane for it. In any event, it often happens that I need to search through our transcripts to find a particular conversation or look up bits of code that might not be anywhere else. And it’s always a nuisance to identify what you’re searching for when you search on a string of text and then proceed to click through each matching transcript.

So an idea occurred to me: Save Points! It’s very, very common in many of the interfaces we use (at least in the tech world) to have some kind of toggle in the gutter of a view allowing us to mark an item for later review. GMail and Google Reader both use a star for this:

In Apple’s XCode IDE (and many other IDE’s), we often click in the gutter next to a line of code to set a breakpoint:

What I think Campfire needs is a turn on this type of interface, a feature I can’t help but think of as a Save Point. I want to be able to click in the gutter next to a line of conversation in a Campfire chat so that I can later pull up all my save points instead of searching. In fact, I’d also like to be able to click on the save point and give it a name.

The reason I think it would help me in my current scenario is that presumably when I pasted something like “woot! this is the final version of such and such query and it totally works fast!”, I’d paste the query and then I’d just click a quick save point in case I wanted to return to that point in the conversation at some later date. Here’s hoping the 37Signals folks will consider implementing such a feature.

iPhone SDK 3.0 beta - no backing out!

Permalink - Posted on 2009-04-14 00:00

Right now we’re putting the finishing touches on our first iPhone app to get it into the App Store, or hopefully at least through the approval process. Who knows, really. But we’re hustling, we’ve put a lot of work into these products and we’d like to at least get them out there soon.

In the spirit of staying on top of things, I downloaded and installed the iPhone SDK 3.0 betas (1 and 2) on my development machine. I just wanted to be able to take a look at things so that I could get a head-start on the next generation of our apps. But so far, errors and extreme weirdness have been keeping me from my work on our current apps for the current platform. You’d think when you switch the build environment for platform 2.2.1, the entire XCode environment would adapt, but that’s not what happens. The helpers seem to be generating nib files for the new SDK, I can no longer create grouped-style table views, there are random crashes, nuisance deprecation warnings for the new SDK I’m not using.

Obviously, beta software is beta software, so caveat emptor, but I can’t find any good information on backing out the 3.0 beta installations and resetting my environment. In addition, I’m told that Apple isn’t accepting apps in the store built using this new version of XCode, even if they are built for the current platform, which is in and of itself really lame if true. Still trying to confirm that. So I’d advise anyone doing development right now to hold off on installing the beta SDK environments on their primary development machine. Install it on a spare machine, I reckon. What a nuisance!

Update: Apple does warn you about this on the SDK download page. Among others:

  • iPhone SDK for iPhone 3.0 beta is for development purposes only. This software should only be installed on devices dedicated exclusively for iPhone 3.0 beta application development.
  • iPhone SDK for iPhone 3.0 can not be used for submitting iPhone OS 2.2.1 applications to the App Store.

We Get Email

Permalink - Posted on 2009-04-13 00:00

From BW, a fan:

I loved STRIP [on] the palm and have tried all of the password management apps for the iPhone and they all SUCK. Even if I don’t make the Beta, can’t wait for the release, and will definitely buy it.

This sort of thing has been happening a lot, so it’s got us pretty excited. The next release of the STRIP for iPhone beta is a round the corner, so send your UDID to support@zetetic.net if you’d like to help test and check it out. We just got approved by the Department of Commerce to distribute what they call Mass Market Encryption, so now we can finally submit it to the App Store. More on that madness later.

Twitter API: With Great Power Comes Great Responsibility

Permalink - Posted on 2009-04-09 00:00

Last night the folks at Twitter released a significant update to their API. Among the changes was a massive change to the way the Twitter API responds to time-sensitive queries. In short, the since parameter and If-Modified-Since
header are no longer supported.

For those unfamiliar with the API, these features allowed searches for Public Tweets or Direct Messages that occurred after a specific point in time. It was intended to both reduce load on Twitter’s service and allow API clients to selectively retrieve tweets that they haven’t seen yet based on a time stamp.

The fact that the API changed is not shocking. The Twitter team had a solid reason behind it, as it seems date based queries weren’t handled efficiently enough for widespread use. There is even an alternate API search, based on message id, that can provide a similar function. Therefore these changes could really stand to benefit the developer community as a whole by providing increased capacity and performance for the API.

The API change was dangerous

First, and most importantly, the API was modified in a way that it would simply begin to ignore since parameters as if they weren’t even there. This means that clients querying the API with the expectation of retrieving a limited subset of tweets they hadn’t seen yet would, all of a sudden, start seeing a completely unfiltered feed of tweets, including ones from the past.

Consider the hundreds of applications like our own apps Tempo and PingMe, which process Twitter direct messages they haven’t yet seen to perform operations on a user’s data. Applications polling the Twitter API using the since parameter would be flooded by old, duplicate messages that they had already processed, possibly causing rampant duplication and perhaps data corruption.

edit: Let me draw an analogy: imagine that one day before release MySQL (or pick your favorite DB) decided to deprecate and ignore the the greater than > operator on queries. No errors – it would just pretend that query clause didn’t exist and return all rows for queries that used a >. How would that affect your application?

It is just poor form for a public API to change in such a way that the results of API operations become unpredictable like this. The API release notes claim this approach was used to ensure that existing applications didn’t break, but in fact would almost guarantee catastrophic failure of applications dependent on the function.

Errors are OK

Don’t get me wrong, it’s absolutely Twitter’s prerogative to change the API, and they can do so whenever they want. But with tens of millions of users and thousands of application and sites using the Twitter API, they should be more responsible about these kinds of changes.

If the API drops support for certain operations, just return an error message. Sure, it will be annoying to get error until the application is fixed, but at least you don’t risk corrupting thousands of down-stream integrations with improper data.

24 is only good enough for Jack

To make the situation worse, Twitter gave their developer community 1 day notice about the breaking change. Imagine if you didn’t get that email, or consider a case where an API release occurred without notification.

edit: When you expose a public API it becomes a contract with your developer community. If you make a breaking change to the API you have a fundamental responsibility to effectively communicate the change and ensure that it doesn’t create massive and unpredictable results for clients.

As Twitter grows and becomes more popular in the mainstream it needs to establish a process for notification on API changes and stick with it. Give the developer community enough time to properly code and test changes to their applications before a release. If it’s not convenient to do on the main API, perhaps they could consider some sort of business service that would provide premium access and a stabler environment for groups and teams like ours that really depend on it.

Making NSDate a little less painful

Permalink - Posted on 2009-03-26 00:00

I just made a couple of updates to our NSDate (Helper) project, thanks to a suggestion from Stephan Burlot in our comments. We’re not the only ones who think working with NSDate is a big pain! The code I had in there to determine relative days ago was based off of NSCalendar and while accurate in its own special way, wasn’t quite what you’d want for a relative time display.

In addition to the tweaks made in the code, I finally got around to creating a more illustrative set of examples in the README, and put up a corresponding document in our software archive. Check out how it works over at Github.

Deep Thought

Permalink - Posted on 2009-03-26 00:00

I miss my old Treo’s bluetooth sync capability. And for a device that does syncing (although in a much more limited way) and has bluetooth, it’s somewhat obnoxious that I have to sync over the wire with my iPhone, that wireless sync isn’t available.

It’s amazing that all smart phones still commonly cripple the bluetooth capabilities of the devices to keep you from using them and for all sorts of reasons – Apple doesn’t want you looking at the file system, Verizon wants you to buy ring tones over their EVDO network, etc. I was hoping Apple would be a pioneer here, tell the carriers to shove it, and go further than Palm did, making other bluetooth capabilities available.

On a mostly unrelated note, there has got to be a better way to package up and bundle Cocoa code you frequently use in different applications.

Last night’s changes to Tempo

Permalink - Posted on 2009-03-25 00:00

Last night we deployed a pretty substantial update to Tempo, our time tracker. Many of the changes are unseen, nuanced, and/or performance-related, so I want to give our customers an update on what we’ve done. It looks like a short list, but it was quite a bit of work. Details follow for some of the more significant changes.

Improved Time Zone Support

This was a huge update. In order to support future planned features we needed to overhaul our handling of time localization. There were a couple of hiccups last night during the deploy related to this, but we’ve got it worked out now. Tempo does browser-based detection of your time zone for new users, setting your time zone preference. On the Account screen you can now change this preference, should you so desire.

Remote Command Stability Upgrade

As mentioned last week, we’ve done a bit of work to make sure that our remote command message handlers are rock solid in the face of weird input via email, and outages on Twitter. The remote command handlers are Looper daemons that check to see if you’ve sent in time entries or timers by email or Twitter.

Batch Tagging Performance

Also mentioned here previously, the batch tagging interface received a serious speed bump. This was a bit tricky, because we’ve been caching tags as a concatenated string on the entries for performance. Nothing a little PL/PgSQL can’t fix.

Rails Upgraded

It’s no secret that Tempo is a RubyOnRails application. It started it out on 1.2 and we’ve kept upgrading with each update to the framework; we’re now on the 2.3 series. This brings significant performance and flexibility improvements. It may not seem like a big deal, but the amount of work that goes into making these upgrades a success is well worth the sweat considering the capabilities it opens up for Tempo in the future.

Potential XSS Vulnerabilities Closed

Being a security company, we try to never take the appearance of security for granted. We decided to give our code a thorough review to plug any potential cross-site-scripting vulnerabilities. Generally speaking, such holes allow an attacker to execute malicious Javascript in your browser. Such code can execute as you inside the application in question, which can wreak all sorts of havoc. Fortunately, we’ve been really on top of this from the beginning, so we only found a couple of instances in Tempo where this was possible, and plugged up the few holes we found.

Coming Soon!

That’s that for this update, but there’s a lot more coming around the corner. We have a new feature that’s almost ready, and we’re working with nGen Works to develop a new graphic design and improve the user experience dramatically.

Tempo Update Tonight 24-MAR-09

Permalink - Posted on 2009-03-24 00:00

We’ll be pushing a number of maintenance and performance improvements out to Tempo tonight, at 10pm EDT. This should only briefly interrupt service for our users. More information on the various changes will be posted here once the update is complete.

Moving a Rails app to UTC in PostgreSQL

Permalink - Posted on 2009-03-23 00:00

We all make mistakes. Or we make decisions that we have to later revisit, to put it kindly! I’ve got a Rails app where I wasn’t using UTC back in the beginning, and this was pre Rails 2.1, so ActiveRecord has been storing all the time stamps into postgres as Eastern time. I need to move all those dates over to UTC for this particular app to go through its next growth spurt, so I threw together a migration that does just that. I’d like to think it couldn’t get more DRY, hope it’s useful to anyone else out there. It’s dependent on Postgres, but you could adapt the increment statement to suit your own DB or to be more generic:

Wrapping Up the Week

Permalink - Posted on 2009-03-20 00:00

The last two weeks have seen a ton of development work here at Zetetic. We’ve been working to cut over one of our bigger client’s single-sign-on systems to a new location, we’ve built new features into the Strip beta (update coming soon, promise!), and we’ve completed a pile of performance, stability, and maintenance improvements for Tempo, our time tracker.

I should say that a lot of this work was made possible by an extra pair of hands; we’ve recently brought Bret Morgan onto our team as a developer. He’s been doing a lot of great Rails development work on Tempo and helping out with testing and Q&A for Strip.

Without going into all the changes we’ve made in Tempo, there are two I’d like to highlight:

Message Handler Stability

Tempo provides our customers with various ways to log time remotely and start timers, and our message handler is responsible for scooping up email and Twitter messages. We did some tweaking that dramatically improves its ability to handle the unexpected (you wouldn’t believe the weird stuff that comes in from MS Exchanges and Outlook systems), touches up its ability to respond to erroneous messages, and ensures that Message Handler keeps it up. We had some older daemonizing code in there, and ripped it out in favor of the Looper module we posted to Github recently. We’ve been using Looper in PingMe’s handlers for quite some time now, it was time to gemify it and use it in Tempo.

Tag Operations Improved ++bajillion

Sometimes you need to re-name your tags in Tempo, sometimes you need to add a tag like ‘oracle’ to everything tagged ‘apex’, and sometimes you just need to delete a tag from all of the entries in the current report. To provide this capability we added the Batch Tag interface, and it got the job done, but it was horribly slow. We got down and dirty with the SQL and updated our tag caching strategy to get it right. Operations on hundreds and hundreds of entries that used to take really long times (often leading to time-outs, I’m sad to say) are now complete within a second or two.

The batch tags interface still needs work, I will concede. We’re not entirely happy with the UI itself and expect to overhaul it soon.

We are planning to roll out these updates and more on Monday night EDT, and we’ll publish a full list of improvements made once it’s complete.

So let’s talk Strip. A number of people are already finding that the simple Categories → Entries navigation can be a little restrictive. We’re working on a number of features to allow for easy re-categorization of Entries, but there are two new features that will make accessing your data a lot easier:


Simple idea, extremely convenient, a tab displaying the most recent entries you’ve opened up:

I use this more than the Categories → Entries navigation already.


Sometimes I just don’t remember where I put something, and I don’t really want to figure it out, I just need the information, and I need it now. I also tend to think that perfect taxonomies are a thing of fantasy, and I get annoyed at software that expects me to be a perfect person. Accordingly, the new Search interface allows me to start typing the name of an Entry, or any data I’ve stored in Strip and it will pull up any matching Entries:

I think you can expect to see these new features among others in the next version of the Strip beta early next week. Thanks for all the great feedback, and keep it coming. If you’ve recently e-mailed us about joining the beta, or you’d like to join the beta, be sure to send us your device’s UDID to support@zetetic.net. The Ad Hoc Helper app (free) will actually take care of the details for you.

Bands On A Budget &amp; Ben Franklin

Permalink - Posted on 2009-03-20 00:00

We’re a pretty diverse bunch here, so once in a while I like to drop some info and links to various things we’re involved in.

Bret, who recently joined our team, has a really cool project called Bands On A Budget. I’ve been in a number of musical projects in the last.. uhm… 15 years I guess? And while I love the
whole DIY thing, I have songs to write and shows to book, so I don’t have time to go silk-screening anything, really. For my last band we needed good and cheap t-shirts and stickers on the quick, and we kept going back to BoaB because the orders were always correct, the work was always good (the silk screening of our t-shirts was fantastic).

I’ll definitely be going through them to get merch done up for my next project. The new band is called Ben Franklin. In the words of Scott Pilgrim, we’re totally not sucky, and we’ll be recording our first proper record in the beginning of May.


Permalink - Posted on 2009-03-16 00:00

I’m still keeping an eye on the development of Papernet-like things, and my friend Warren posted a link to an interesting article this morning about the shrinking newspaper/print business and “nichepapers”, which includes this neat little quote:

“When a 14 year old kid can blow up your business in his spare time, not because he hates you but because he loves you, then you got a problem.”

Quite a different perspective that people have these days.

Using SoS for blog comments/discussion

Permalink - Posted on 2009-03-12 00:00

I like Zed’s idea of using Son of Sam for blog comments/e-mail discussion, it’s a really great idea. It’s perfect for sites with high comment rates that need to filter down noise in a discussion and foster some real thought churning. It may give the impetus for actual discussion instead of the common sounding off of anonymous trolls.

Zed’s really into rules (is this blog post even 500 words?), which makes perfect sense for high traffic sites, but a little less restriction on the length of time that a discussion can last and that a user can stay subscribed, it’d be really useful for folks like us who have a blog that does get comments but doesn’t have quite such a need for policing them and keeping the discussion on track.

An interesting marriage between the forum and the mailing list! Too bad the Son of Sam code isn’t up anymore, I’d be looking at it right now (despite my utter and complete aversion to Python). I even checked archive.org, I’m so curious.

It’s TV Time

Permalink - Posted on 2009-03-12 00:00

Hampton has a TV show, apparently! Looking forward to it.

Hack the planet! Someone should totally do Hack the Planet. In face paint. Gotta be authentic.

Some bug fixes for Tempo

Permalink - Posted on 2009-03-11 00:00

We haven’t forgotten about our time tracker in the midst of all this excitement about Strip! We just pushed a small update to fix a couple of outstanding issues.

The Prototype-based Autocompleter we were using on text entry and tag entry had to go, we’re giving the jQuery version a shot now. The old one was driving us crazy, and it really bothered a few users who took us to task. The fix is a bit over-due, but it’s quite snappy now. If you find the new version to be buggy or have any suggested tweaks, do let us know.

Canceled accounts can no longer log in! (doh) Account cancellations happen some times, and we provide a self-cancel service in Tempo. It really does terminate your account, inactivating your projects and making sure that you no longer get billed. However, a small bug was still allowing users with canceled accounts to log back in to the system. This has been fixed. As always, if you want to reactivate your account with us, let us know, we’ll always be glad to have you back!

Looks like in the process we ended up with a small bug in the bookmarklet that whacks the layout just a bit due to a javascript error. I’ve got a fix ready and we’re hoping to move that out shortly!

Thanks for being patient and for using Tempo.

Update: We will be briefly interrupting service on Tempo today at Noon, EDT to get that bug fix out.

NSDate (Helper)

Permalink - Posted on 2009-03-11 00:00

I saw Matt Drake’s post with tips about using NSDate over on Mobile Orchard’s iPhoneFlow today and figured I’d give the drummer some more.

When setting up Codebook (a secure notebook iPhone app we hope to release soon) I needed to do some fancy-pants date formatting all over the place because I wanted to mimic what Apple had pulled off in the Notes application for iPhone. Now, there are many ways to do this, I’m sure I’ve overlooked some useful tricks that Cocoa provides (it has a number of default date format “styles” you can use), but I think what’s important is to always avoid repeating yourself. And to do it in such a way that if, say, I realize that I really should have used the Cocoa candies, I could change the implementation in one place and the rest of my code would be none the wiser. DRY, as it were.

Now date calculations in Cocoa can be nasty. I don’t know if they have to be, but you can end up with a real mess of code involving NSCalendar, NSDateFormatter objects, or calculating offsets by seconds. Totally ugly.

Objective-C’s categories are a really nice way to bottle up some of this code and re-use it. In Codebook I used categories to implement helper methods on built-in objects and classes, like NSDate. So in the aforementioned example of Codebook, I implemented a series of methods for doing date calculations, and convenient methods for getting calculation-based formatted dates. Wrapping them up in NSDate (Helper) allows me to do things in the app like:

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

// figure out date display data at top of view
NSDate *relativeTime = (!targetObject.timestamp) ? [NSDate date] : [targetObject date];
dateLabel.text = [NSDate stringFromDate:relativeTime withFormat:@"MMM d"];
timeLabel.text = [NSDate stringFromDate:relativeTime withFormat:@"h:mm a"];
daysAgoLabel.text = [relativeTime stringDaysAgo];


The really tricky part on the notes listing was getting the conditional display like ‘11:59pm’ for an entry updated today, ‘Friday’ for a date within the last 7 days, ‘Jan 23’ for a date in the current calendar year, and ‘Nov 16, 2008’ for dates not in the current calendar year. And how simple is it now?

self.dateLabel.text = [NSDate stringForDisplayFromDate:date];

This gives us:

I have posted NSDate+Helper on Github, anybody is welcome to use it, fork it, add things, send pull requests. I bet we could build up a nice library of these guys for use in our applications.


Zetetic is the creator of the encrypted iPhone data vault and password manager Strip and the open source encryption-enhanced database engine SQLCipher.

And we’re off!

Permalink - Posted on 2009-03-10 00:00

So today the Strip beta has actually kicked off! We got the last few UDID’s that were sent to us into the mobile provisioning profile, and blasted out a link to download everything with instructions to everyone who signed up. Thanks for waiting!

Apple has made this process – using Ad Hoc provisioning to beta test your app – an incredible time sink. In other words, really expensive. You can get a sense of the process over here.

For those of you who didn’t get a UDID in to us already, send it in, I think we should be able to get you into the next round of provisioning and we’ll re-issue the profile with the next version of the beta once we’ve had a chance to take a look at everyone’s feedback and fix any issues that stand out.

So, please send us your feedback to support@zetetic.net, we’re really looking forward to it!

Hang Tight

Permalink - Posted on 2009-03-09 00:00

A few folks have asked us what’s happening with the Strip beta. We’re almost finished provisioning all the Ad Hoc profiles. Don’t worry about what this means, other than it’s unbelievably annoying crap that Apple makes us do so we can have beta testers without making you pay for the app. Feel free to write them a strongly-worded letter!

Other things to read while you wait:

  • Unspace has opened up registration for their follow-up conference to RubyFringe: FutureRuby (Stephen and I will be attending!)
  • The AppleiPhoneApps.com folks coin the term Pocket Rejection, which I think is very clever if depressing.
  • Geithner out by June?


Permalink - Posted on 2009-03-06 00:00

STRIP isn’t the only iPhone application we’ve been working on. Can’t really go into the details right now, but I just wanted to give a heads up:

Strip Beta List

Permalink - Posted on 2009-03-02 00:00

We’re getting the beta email list together for Strip on the iPhone, we’ll be announcing the details shortly. If you want to participate, please shoot us an e-mail at support@zetetic.net. For those who aren’t hip with it just yet, Strip is our personal information and password manager. It stands for Secure Tool for Recalling Important Passwords, and you can read more about it over here.

Thanks for your patience while we’ve been getting the app together. It’s basically all set to go, but needs some user-vetting, and we need to spend a little time cranking out some utilities to migrate Palm Strip users to the new app (or to at least give them a CSV they can use to migrate to another platform).

And now I leave you with the Moz, got work to do:

Deeper Thought on webOS

Permalink - Posted on 2009-02-28 00:00

I have admittedly ragged on Palm a bit of late, but I just watched their webcast on Developing Application for webOS, and I had but one thought:


Seriously, though. If you’re doing iPhone development, sure you get the Cocoa framework and access to OpenGL and all that, but you don’t get such open access to the system and other applications (with Sync!) like you will with webOS. At least, that’s my hunch, I guess time will tell. But just the basic layout of the high-level architecture warms my heart.

You know what else is awesome? The API has “stages” and “scenes”! That rocks.

Jury is still out as to whether you can run processor intensive games in this platform, but honestly we’re not game programmers, and this does seem to uniquely enable easy development.

On a total tangent, I went to the Jelly NYC event at my workspace today and mentioned that next week we’ll be starting the beta for Strip on the iPhone (sign up for the mailing list over here, or just e-mail us). Of the 15 or so people there, one of them was a hard core, long-time user of Strip, and is still toting his Palm around waiting for a way to migrate to his iPhone. Can’t wait. Stay tuned!

Smashing the Stack

Permalink - Posted on 2009-02-24 00:00

How many of you characters have read Smashing the Stack for Fun and Profit by Aleph1? Just curious. Also, if you did, did you make it all the way to the end?

Git Pr0n: STRIP

Permalink - Posted on 2009-02-20 00:00

We just merged our development branch for Strip into the master branch. Now, granted some of this is XIB files, icon images, and included openssl headers. Nonetheless:

165 files changed, 135150 insertions(+), 2364 deletions(-)

Hoping to have some good screen shots up soon.

Deep Thought

Permalink - Posted on 2009-02-19 00:00

“I’m not a businessman, I’m a business, man!”

Tempo API Update 18-FEB-09

Permalink - Posted on 2009-02-18 00:00

We’re going to push out a couple of changes to the Tempo API tonight at 10pm EST. Last night we found a small bug that prompted us to address a pair of issues, and update our documentation:

A type attribute will be required for multi-value params in context search:

The /entries/search end-point allows you to post an XML document that we call a context. It’s a lot like the Tempo reporting interface, it allows you to specify a set of parameters and it will return the corresponding entries if the request is well-formed.

Certain parameters that you can send up in a context document are multi-valued and must be presented within a type=“array” set. These are tags, project-ids, user-ids, and exclude-tags. Here’s an example:

<?xml version="1.0" encoding="UTF-8"?>
<project-ids type="array">
<project-id type="integer">1024</project-id>
<project-id type="integer">2048</project-id>
<project-id type="integer">8192</project-id>
<exclude-tags type="array">

This has actually always been the case, but our documentation did not reflect this.

The interval parameter will be supported in context search:

As shown the example above, you can use an interval shortcut string to avoid having to specify start-date and end-date. The list of currently available intervals is:

  • today
  • yesterday
  • thisweek
  • lastweek
  • last7days
  • thismonth
  • lastmonth
  • thisquarter
  • lastquarter
  • thisyear
  • lastyear
  • alltime

XML output includes type attribute hints:

For all non-string data in output from our XML API, a type attribute has been re-introduced. This shouldn’t break anybody’s compatibility with the API, as we haven’t had any attributes present in the past for you to look up, but please get in touch if you think this will be a problem for you. This is an example of what that looks like:

<command nil="true" />
<created-at type="datetime">2008-03-31T15:06:46-04:00</created-at>
<creator-id type="integer">2048</creator-id>
<hours type="decimal">5.0</hours>
<id type="integer">8192</id>
<is-locked type="boolean">true</is-locked>
<is-timing type="boolean">false</is-timing>
<notes>client meeting in NYC to discuss project requirements</notes>

Process and Execution

Permalink - Posted on 2009-02-17 00:00

As I wrote last week, I’m really interested in any piece of reading where artists discuss methods of process, or simply getting around to doing their work. Most of the challenge is actually sitting down and setting about doing what you intend without knowing how it’s going to turn out necessarily, and being okay with that.

That’s not quite how it works in programming, but sometimes it is! Sometimes here at Zetetic we set out to find a way to do something without knowing what we’ll find. In fact, new challenges and new ideas always push you in this direction, so it happens pretty often, and like sitting down to create something in the context of art (wherein you see yourself, maybe, as an “artist” or a “poet”), you have to be okay with not knowing exactly how it’s going to turn out, and trusting yourself to make decisions as you create.

There’s an article on the 37Signals blog today, titled, “The moment of truth is a real audience,” and here you find where the lines of art and entertainment cross-over in ways that are challenging to deal with for the artist, but it’s very straight forward for someone who sees himself as an entertainer, a producer, or a manufacturer of software. The article quotes playwright Matt Hart:

[Fellow playwright George S.] Kaufman did not hold with the theory or the practice of having run-throughs for his friends or friends of the cast, or even for people whose judgment he respected and trusted. He held firmly to the idea that no one person or collection of persons, no matter how wise in the ways of the theatre, could ever be as sound in their reactions as a regulation audience that had planked down their money at the box-office window, and in the main I think he was correct.

For the artist, acceptance and understanding of his work is not always in the bag, and the understandable fear of a lack of understanding or acceptance can be debilitating (whether the artist has ever gone out on that limb or not!) For the programmer, I think things are a lot simpler: you made something that does what you intended it to do, or you didn’t. It’s useful to people, or it’s not. But it’s still pretty disappointing when your software fails to gain wide appeal, when it doesn’t quite make the cut of your intended audience.

So, I think the trial by fire of a paying audience is a good thing. Even if you don’t get the acceptance and the understanding you hoped for. Maybe people aren’t ready for your cool idea, or maybe you need to build on your means of expression. YET, I think it’s crucial here to understand that with art, you can perfect your means and reach all your goals and never get critical acceptance, and you can’t expect to. I wonder if you can’t expect to with software either?

Speaking of trial-by-fire, great progress continues with Strip for the iPhone and we should be ready to beta the application very soon. Have you signed up for the beta mailing list? Scroll to the bottom of this page if you haven’t, and sign up! We’ll announce details on beta participation there within the next couple of weeks.

Hey, Look

Permalink - Posted on 2009-02-16 00:00

Palm appears to be making a real effort to re-establish the developer base for their platform. While I’m a skeptic, webOS is a pretty cool idea for an application development platform. Remains to be seen how well it works, and if the trade-off for ease of development is the capability of applications. I’d bet good money that it will be a lot easier to develop applications for webOS than it is for iPhone OS, but I’d also bet that you won’t be able to pull off some of the low-level graphics processing that enables cool games and animations.

The first chapter of an O’Reilly book on developing for the OS is up on the developer site, and it’s being written by the lead architect. Wouldn’t it be great if the API and documentation were up? I’m guessing that means it’s still under heavy revision.

Uncertainty is a Virtue

Permalink - Posted on 2009-02-12 00:00

Lately my subway-reading materials seem to broadly spin around what it means to be an artist, and processes, and what’s involved in actually setting about the doing of your work, the making of your art. I crunched through Haruki Murakami’s memoir What I Talk About When I Talk About Running so quickly that I think I need to read it again (I’m looking forward to it, and I rarely re-read books), and I’ve since moved on to Art & Fear by David Bayles and Ted Orland. This is a particularly interesting subject for me as a song-writer and a programmer, although for really different (and probably obvious) reasons that I’m not going to go into right now, save to pull some choice quotes that I’ve found to be really profound.

This one is from Art & Fear:

Vision & Execution

More often, though, fears rise in those entirely appropriate (and frequently recurring) moments when vision races ahead of execution. Consider the story of the young student – well, David Bayles, to be exact – who began piano studies with a Master. After a few months’ practice, David lamented to his teacher, “But I can hear the music so much better in my head than I can get out of my fingers.”

To which the Master replied, “What makes you think that ever changes?”

That’s why they’re called Masters. When he raised David’s discovery from an expression of self-doubt to a simple observation of reality, uncertainty became an asset. Lessn for the day: vision is always ahead of execution — and it should be. Vision, Uncertainty, and Knowledge of Materials are inevitabilities that all artists must acknowledge and learn from: vision is always ahead of execution, knowledge of materials is your contact with reality, and uncertainty is a virtue.

Implementing asmSelect in Oracle APEX

Permalink - Posted on 2009-02-12 00:00

I’ve been a big fan of jQuery for some time now, and one of my favorite plug-ins is Ryan Cramer’s asmSelect, which is a really cool alternative implementation of a multiple select control. There’s no swing tables, there’s no explaining to users how they need to hold down control (or command for mac users) while they click their desired options. There’s just a nice manageable list, to which you add selections using a drop down. There’s a nice example here, if you’re unfamiliar with this interface.

In any event, some of our clients were not really digging the Shuttle control available in Oracle’s Application Express. “Shuttle” is really just a pair of swing tables. So I figured, “why not set those back to normal select[multiple] elements and run the asmSelect plugin?” However, it wasn’t that easy, so I’ve written up how to get it going. I’m working in APEX 3.1.2, if you decide to follow along.

First you need to make sure you’ve got the select element set to multiple in the interface:

Next, add the needed jQuery libs to your application. There are a number of ways to do this, but since I’m not going for anything fancy, I went with the latest version of jQuery (1.3), the latest version of the asmSelect plugin, the included CSS, and avoiding any jQuery UI animation options:

  • jquery-1.3.1.min.js
  • jquery.asmselect.js
  • jquery.asmselect.css
  • jquery.noconflict.js

That last one is actually a quick little file I threw together to allow for jquery to be compatible with apex’s built-in use of prototype:

/ jquery no-conflict script, sets $() function to $j() /var $j = jQuery.noConflict();

Not much to it, pretty standard.

I attached them to the application itself (Shared Components → Static Files → Create, then select your app for the association). Once they are uploaded, you need to link them in from your page template. Head over to Shared Components → Templates and select your default page template for editing. You can jam this into the head section of the document template:

<link rel="stylesheet" href="#APP_IMAGES#jquery.asmselect.css" type="text/css" />
<script src="#APP_IMAGES#jquery-1.3.1.min.js" type="text/javascript"></script>
<script src="#APP_IMAGES#jquery.asmselect.js" type="text/javascript"></script>
<script src="#APP_IMAGES#jquery.noconflict.js" type="text/javascript"></script>

These statements will include the javascript and css files we uploaded into our app as static files. Below these, in the header template (or in the html header area of a specific page), we can add a script block and some code to activate the asmSelect plugin on every select[multiple] on our page:

<script type="text/javascript">
$j(document).ready(function() {
// wire up the select multiples to be asmSelects
$j("select[multiple]").asmSelect({ });

At this point, if you reload your application page, having saved your changes and such and there are no errors in the setup, you’ll see:

  1. the original select show up and quickly disappear (asmSelect hides it)
  2. the new asmSelect element

However, if you attempt to submit your form, it will explode on you. You’ll get a pretty heinous 404 error message saying that the page couldn’t be found. What’s happening here?

Not Found
The requested URL /pls/apex/wwv_flow.accept was not found on this server.

Oracle-Application-Server-10g/ Oracle-HTTP-Server Server at apex.example.com Port 80

APEX is at heart a set of complex stored procedures made accessible over the web via mod_plsql running in Apache. If you’ve ever written a stored procedure for mod_plsql (htp.prn and all that), you’ve probably run into this problem before: if you send any params that the procedure doesn’t expect, mod_plsql will bomb out with a 404 error.

What’s happening to us here is that by using asmSelect we’ve added a parameter that’s not being expected by APEX. Every form element on the apex page matches an ITEM that you created on the page (like P1_PRODUCT_TYPE above). In this case, asmSelect hides the element represented by P1_PRODUCT_TYPE and drops select#asmSelect0 right next to it in the DOM.

So what do we do?

What can be added to the DOM can be taken away!

I tried faking out APEX by creating a corresponding page-level item with the same name and that didn’t work, so I just moved on to the next obvious thing: remove the asmSelect element when the form’s submit element fires. Here’s how I first tried it:

<script type="text/javascript">
$j(document).ready(function() {
// wire up the select multiples to be asmSelects
$j("select[multiple]").asmSelect({ });
$j("#wwvFormFlow").submit(function() {

That didn’t quite work out, because APEX already has its own ideas about the form’s submit event. And honestly, I don’t really want to mess with APEX, I just want to work around it. So I decided on another trick we worked out some time ago, intercepting the submit event and then letting APEX do its thing afterward:

<script type="text/javascript">
$j(document).ready(function() {
// wire up the select multiples to be asmSelects
$j("select[multiple]").asmSelect({ });

// subordinate the submit function in apex so we can supplant it
function submitOverride(event) {
// remove the asmSelects from the DOM so they don't mess up submitted params

// execute the original submit
document.wwv_flow._submit = document.wwv_flow.submit;
document.wwv_flow.submit = submitOverride;


This really did the trick, removing the asmSelect right after submit fires, sending up the correct form elements. And since asmSelect manages the original selection list as your are making changes, the selected items are preserved.

For one last bit of finesse, hide the original select element (in our case the item P1_PRODUCT_TYPE) on page load by setting style="display:none;" on the element, which makes your page load a bit smoother:

Works like a charm!

Generating a sequential date series in Oracle

Permalink - Posted on 2009-02-12 00:00

I needed a bit of SQL to gin up a series of sequential dates in Oracle that I could use in generating data for flash charts in APEX. It’s important to have a solid series of dates that you can LEFT OUTER JOIN against so that NULL values correspond to one of your series points, keeping all the data properly aligned.

In looking around for some good examples I found some way more complex date series tricks
, but didn’t see any article on the simple basics of doing a series of dates between a start and end date. Here’s what I found along the way:

-- notes for generating date sequences in oracle
-- gleaned from a pretty interesting article by Indrajit Agasti on generating
-- various series of working (non-weekend) days:
-- http://www.dba-oracle.com/t_test_data_date_generation_sql.htm
-- i'm sure this old hat for many oracle devs but i didn't see it out there
-- anywhere so i figured a quick ref of notes i took in the process might
-- be useful to somebody else

-- to knock a string into a date object:

-- getting an integer difference between two dates:
SELECT TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008') FROM DUAL;

-- generating a sequential series using dim (this is odd, admittedly)
-- 0, 1, 2 ... 9 (n - 1)
DIMENSION BY (0 dim) MEASURES (0 rnum)

-- easier, returns 1,1,1... (10 rows), so use rownum to get increasing integers

-- drop in our dates
-- returns 1, 2, 3 ... 31
CONNECT BY LEVEL <= (TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008'))

-- full date set then: (may 1st, to may 31st)
SELECT TO_DATE('01-MAY-2008') + ROWNUM - 1
CONNECT BY LEVEL <= (TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008'))

-- being inclusive of the end-date (june 1st)
CONNECT BY LEVEL <= (TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008') + 1)

Palm Strip: Fork and be Merry

Permalink - Posted on 2009-02-11 00:00

We’ve mentioned in the past that we’re no longer supporting or developing Strip on the PalmOS platform. Even so, people still ask about looking at the code and making updates. Strip for Palm OS is free and open-source software, so we’ve pushed the code up to Github to facilitate any further development others may wish to do. It’s the beauty of open source – feel free to fork it, hack it, send pull requests, or release your own version. Fair warning – the code was written a long time ago on an ancient (in relative terms) platform so it might leave something to desired if you’re used to more modern toolkits!

The State of MySQL: The Elephant in the Room

Permalink - Posted on 2009-02-10 00:00

It’s been in the news for a few days: two of the MySQL execs, Martin Mickos and Monty Widenus, are leaving Sun Microsystems, Sun having bought and absorbed MySQL AB.

I’ve always been a Sun fan (Solaris FTW), but it’s a well-known joke that being bought-out by Sun is the kiss of death. So what happens to MySQL now, and what happens in the open-source database space? Drizzle, an open-source and derivative project led by Brian Aker, doesn’t seem to have clearly defined its space (“the cloud?”), with people wondering if it’s really just a SQLite competitor (alternative might be a better turn of phrase because it’s got a long way to go before it could “compete” with SQLite). Speculation aside, what is known is that it drops many of the features that make MySQL a full-featured relational database.

Ladies and gentlemen, I think that we have a winner, the elephant in the room: PostgreSQL. Somebody’s gotta say it. Sorry to gloat. PostgreSQL is and has been “the most advanced open-source database,” long before these MySQL upstarts came along.

In the end, MySQL was never a completely open project. MySQL AB offered a GPL version but only included code that they owned the copyright to. Contributing developers wouldn’t see changes included in the core unless they were rewritten by MySQL AB or donated (read sign over their IP) to the company. It’s pretty heinous to tout such a model as an open-source success story, and it looks like the opposite is now true: MySQL is clearly floundering.

Strip: News from the Workbench

Permalink - Posted on 2009-02-10 00:00

It’s a been a little while since I’ve given any kind of update on our progress with STRIP for the iPhone platform. We’ve been hammering away at our data model and at this point I think we’ve arrived at a fairly stable first implementation and work-flow for the app. After changing it what seems a billion times, I think we’ve got it. For now.

There are still some tweaks we need to make before we start the beta of the initial version. Also of note: wireless backup and sync won’t be available in the initial version. It will be done, oh yes, and it will be done well, but not in time for the first release. We want to at least get this out there for Strip fans to test it out and make sure we’re going in the right direction here. This feature is really important to us, as it’s one of the features that really made the previous versions of Strip stand out, and we’re committed to its implementation.

We’ve put together a mailing list just for Strip (low volume, announcement only) for those of you who want to be alerted directly when we’re ready to do the beta. Sign up for it over on the Strip page.

We still need to put together an export tool for old Palm OS Strip users who want to migrate to various systems, and a means to import that export into the iPhone version. We intend to have that piece in place by the end of the beta, before we go live, but I can’t commit to a time-frame just yet.

Thanks again for your patience as we work hard to get this right.

First Takes

Permalink - Posted on 2009-02-06 00:00

On the 37Signals blog today there was some talk about Axl Rose and Frank Sinatra, two musicians I love to gab about:

Sinatra’s one take style produced classics. Axl’s dithering produced a pile of mush. We can all learn something from that. It’s easy to fall into a trap of nitpicking over things that don’t really matter. Instead, focus on the essence of what you’re doing. Press record, get it done, and get it out there.

Lately I’ve taken our first takes on demos for the new band, or just scrapping them and coming back to it when the time is right. Sometimes that means a different approach, sometimes a better room sound. I almost always go for a first take on a guitar solo, if I don’t double it with another one for maximum shred \m/.

With that in mind, an update on our progress with Strip should be forthcoming.

Evolving Tempo’s Command Line

Permalink - Posted on 2009-02-06 00:00

When we set out to build Tempo time tracking, we knew it would be important get out of the user’s way when they need to entering time. The way we saw it, there were three problems:

  1. Staying productive while busy is challenging – we often change tasks (and therefore the client we are billing changes).
  2. It can be difficult to accurately remember how much time we spend on individually tasks.
  3. It can be a real work-flow interruption to load up a website and type information into a form.

That’s why we created Tempo’s command line text interface. For instance, I can simply type in what I am working on next, and Tempo will time me. When I need to change tasks I just type in what I’m working on next and the last timer stops:

doing a screenshare demo #bigcorp @support

Similarly I can log time via this command line, not just start timers:

3:00 re-worked DataModel #strip @iphone @development

But if you don’t already have Tempo loaded in a browser then starting things up to enter your time can be an interruption in the flow, a disturbance in the force. Thankfully, text entry can come from anywhere! So we created various alternate ways to quickly enter time with minimal impact:

This text syntax has been a big win for us and our customers. While we’ve seen a few services out there implementing similar features, we’re pretty much the only game in town that takes it this far.

We’ve found that when people first try Tempo, the convenience of the command line and all these points of entry go unseen for a little while. We have a core group of customers that love these features, but many folks who might use them don’t know they are there until we show them and explain how it works. Then a light bulb goes off and we’ve won some new fans.

Obviously, that means we’ve got some work to do on the UI. The good news is that the awesome team at nGen Works is working with us to help us improve the ease of use and aesthetics of the application.

Meanwhile we want to expand what Tempo’s command line is capable of, and we could use your input here. Many of our customers have been asking for new features and we’d like to add in some of our own. But to do this we need to make some changes.

First the initial commands themselves (log time and start a timer) don’t actually have a command! This isn’t such a problem when the command itself is easy to distinguish — the widget, the bookmarklet, the website itself all send in a specific piece of text to parse. Things get much trickier with e-mail, where the commands also have to work, and where we have to scan the message for the command.

E-mail comes with a lot of junk in it, especially e-mail from web-based services, or e-mails quoting other e-mails. There are lots of tricks to parsing out what you don’t want, but finding a start command like this is like trying to find a needle in a haystack:

I am doing stuff

Yup, that would be a valid start-timer command. Now, if you check our text-entry cheat sheet, you’ll see that I’m fudging things a little bit here. We do require a keyword for timers sent in by email – start. We are thinking about standardizing the use of keyword prefixes across text entry methods. For instance, this is our proposed syntax for timers:

start writing about the CLI #tempo @bloggingstop

And this is our proposed syntax for logging time directly:

log 1h did some stuff #tempo @developmentlog 1:30 …

Requiring a keyword at the beginning of every command would allow us to expand the syntax and add new features in the future like these:

stop 2h [ stop timer and add two hours ]stop -30m [ stop timer and take off 30 minutes ]start 1h … [ indicates I started an hour ago ]log start 3pm stop 4pm [ record 1 hour between 3 and 4 pm ]

We’re fairly sure this is where we want to take it, but we’d love to get some feedback. Let us know what you think.

The unspace kids are up to something

Permalink - Posted on 2009-01-30 00:00

Something is apparently cooking over at unspace, the people who’s brainchild was the RubyFringe conference last Summer.

I’d been thinking of trying to put together some kind of geek talent show or battle of the band geeks or what have you, and talking to some other hackers about it (as in Zed and Hampton), and this is bringing the idea back into my head. (I’m a bit of a ham, so I’m inclined to do these sorts of things.)

Zed’s Freehacker’s Union (FU) is a really cool group/grouping/idea and he’s pretty into doing technology and instrument hacking and the idea of putting together regular presentations or performances. I had been thinking of just trying to find the various Rubyists and hackers in the amorphous community who have bands or performance projects and get them all to play some show together in tandem with a conference like RubyFringe or as some kind of accompanying nighttime event. There seems to be interest in this sort of thing. Hampton had mentioned he was looking to put together some kind of website or page presenting hacker music projects (or maybe mixtapes??? just occurred to me now).

Anyway, enough thinking out loud from me, there’s work to be done.

July 9-12: the nerds are planning something!

Coworking in Brooklyn is Awesome

Permalink - Posted on 2009-01-30 00:00

My daily workspace is in Brooklyn at the Williamsburg Coworking space. I have to say it’s been a pretty rad place to work, and it’s way better than working out of the house or in a corporate office park. Needless to say, it’s your coworkers and environment that make it worth doing, and I’ve been pretty lucky that this space is run by a politically active art collective, and the people who show up here are all creative, positive folks who are also good coworkers; no one is noisy or rude, etc, and the atmosphere is quite relaxed.

In addition, we sometimes have really cool events here:

on friday, we will host “work at jelly” and at 2pm we will pipe the inaugural session of “Jelly Talks” featuring Chris Messina (Board member, OpenID) and Dave Morin (Senior Platform Manager, Facebook). starting at 5pm, we will break into a vivacious happier hour! we hope that you can clear your schedule, snag your laptop and join us – this friday (25 July) from 9:30 till 7pm!

I realize this is a bit late notice, but if you’re in Brooklyn today, feel free to drop by, say hello and check it out.


Permalink - Posted on 2009-01-29 00:00

My friend the writer Warren Ellis is full of good ideas (and various poisons), and the one that he’s been kicking around to some of us lately is really compelling. He calls it PAPERNET:

The social letterbox may just be as simple, in the first instance, as a dedicated Gmail account, where I can just press Print without opening the attached document. In kicking this around within a Secret Society, my friend Alasdair Watson knocked together a proof-of-concept in an hour — email comes in, paper comes out. Automagically, like a podcast that spits out paper.

It’s not like a fax machine, where some bastard buys your number and there’s a sheaf of junk hanging out of the thing in the morning. It’s roll-your-own one-sheet POD. And it’s also subscription-based POD, if you know someone who semi-regularly does interesting things with a sheet of paper and decides to share. They’re either sending directly to your letterbox-email, or you’re on an announcement-only mailing list (or Google Group). Or, as I say, as simple as me pressing Print so they’re spat out for me to take to the pub, or on a train journey. And if they’re not especially personal, I can just leave the buggers on the table or the seat when I’m done with them, too.

Wouldn’t it be cool to set something like this up, the input AND output end of it?

Strip for iPhone development update

Permalink - Posted on 2009-01-27 00:00

Apparently there are more than a few people looking to keep an eye on our progress with Strip for the iPhone. Development was delayed in December and the beginning of January by a rush of year end work for some of our largest clients, which needed to take precedence. While that put us a bit off schedule, we’ve been making great progress in the last couple of weeks and should have more news soon on a beta of the application. Thanks for keeping on us! Since most of the inquiries are coming from users of Palm Strip, we’d love to hear from you about your favorite features, things you can’t live without, and things you never liked that you’d like to see resolved in the new version for the iPhone. Feel free to leave comments or write us: support@zetetic.net.

Always Room For Improvement!

Permalink - Posted on 2009-01-27 00:00

batman with bombWhile we have a lot of development going on here behind the scenes with regard to our time tracking system Tempo, we’re always looking for more feedback from our customers. Ever since we launched the system we’ve gotten some incredibly thoughtful criticism and suggestions that have driven where we’ve taken the app and will continue to do so.

Last night I pushed out some minor adjustments to the interface and we’re planning to do a slew of such adjustments in the upcoming month. With that in mind, we’d like to hear from you about any tweaks you’d like to see. We all tend to notice things that bother us when we are using the site the most, which is generally right around now, at the end of the month. In particular, I’m interested in hammering down any nails that might be sticking up from the floorboards. If you have the time, please hit us up with any changes you’d like to see, major or minor, by writing us at support@zetetic.net.

Thanks again for your support!

Tempo update: date range adjustments

Permalink - Posted on 2009-01-26 00:00

We made a couple of small but necessary adjustments to Tempo’s user interface this evening. The date range selector at the top of the screen had been causing some confusion and from there some unexpected exceptional situations [also known as “bugs”]. As you can see here, there’s a date range selector, and a pair for date fields that allow you to select your own date range manually:

Previously, if you typed dates into those boxes or used the calendar pop-up to change their values, the date range would become immediately unselected. This is because the date range took precedence over what was present in the start_date and end_date fields. If you selected a new date range, the start_date and end_date fields would not change until you clicked “Run Report”, and then you’d see that the range took precedence in the report, and their values would be updated to match the range.

That’s a little bit confusing! Some users thought this was a bug and so would clear out the start_date and end_date fields, and then set a range, hit “Run Report”, and nothing would happen because the server wouldn’t process the report without the missing values – even though they would be ignored. Bug on my part.

So, not only has that been fixed, but the start and end date fields are now updated instantly to the correct dates when you select one of the ranges, so that you get the appropriate visual feedback and can see what it is you’re asking for when you run the report. Apologies for the confusion!

As always, if you see anything weird, please send us a message at support@zetetic.net.

The Dark Side

Permalink - Posted on 2009-01-22 00:00

Sometimes you come across a webpage that is just so bizarre and absurb, you just don’t know how to introduce it to other people. But you still do it anyway. (h/t to Chip Z)

It only gets better from there (safe for work).

In other news we’re still hammering away at STRIP for the iPhone. We take breaks for food and small diversions, but we’re still plugging away.

Update: it would appear that not long after we posted this, the website in question took the page down.

My Spooky Friends Net

Permalink - Posted on 2009-01-21 00:00

Warren Ellis writes:

So, are people rolling their own private microblogging networks yet? And knocking together mobile pages and writing/hacking desktop apps to work with their private microblogging networks yet? It would seem to me to be the obvious outgrowth of the Twitter phenomenon: ambient communication for secret societies.

(Which you can take to mean “gated communities,” “dev teams” “people who like their privacy” or “bomb-throwing anarchists.”) …

I’d happily run two microblogging desktop apps: one for Twitter, and one for My Spooky Friends Net. And, after a while, I’d probably stop using the Twitter app, I’d imagine.

I’d be willing to work on My Spooky Friends Net.

Update: There are a ton of apps that work with Laconica / identi.ca already!

Deep Thought

Permalink - Posted on 2009-01-21 00:00

I need an HTCPCP daemon.

Or an intern.

There is coffee all over the world. Increasingly, in a world in which computing is ubiquitous, the computists want to make coffee. Coffee brewing is an art, but the distributed intelligence of the web-connected world transcends art…

I’m gonna go make some coffee. Blog post on really simple ruby daemonizing coming soon. Stay tuned.

Dead Simple Ruby Daemons Using Looper

Permalink - Posted on 2009-01-21 00:00

There seems to be a bit of interest in the Ruby community lately in putting together handy libraries for creating Ruby daemons, so I thought I’d throw our own particular solution into the mix. Our solution intentionally avoids a lot of the common daemonizing tasks (like detaching from the terminal) so it might not be quite appropriate to call it daemonizing, but it fills our requirements nicely. (As an aside, check out Kenneth Kalmer’s new library daemon-kit for a nice actual-daemon implementation in Ruby.)

We originally tried coding things by hand using Daemons, and then modularizing our oft-repeated code to stay DRY, but we kept running into stability issues. Also, when you fork a Ruby daemon, particularly one that’s loaded up a large stack in memory, you end up at least briefly using twice as much memory. So, memory hogging and crashing needed to be avoided.

None of our daemons required advanced process handling, either. They were simple, single instance workers that had very particular tasks (like schedulers and message handlers for PingMe). We found ourselves asking, “do we really need to be forking child processes for this?”

The answer is no. Instead we are using a module we just pushed to Github that we call Looper. It allows us to take any bit of code or a class and run it as a kind of daemon. Or, more specifically, the class uses Looper to take advantage of its simple signal trapping, loop handling (including sleeping), and the class can rely on Looper to catch any unhandled exception, report it, and keep on keepin’ on.

The loopme method takes a block that it runs for you, handles sleeping between runs, and will catch any unhandled exceptions that bubble up. Thus, if you want to exit on a particular exception, you’ve got to rescue it in your code and set @run to false. It also sets up signal trapping so that signals TERM, INT and HUP will all cause the loop to end (I’d be open to changing this behavior or adding additional signal responses if anybody has an interest).

Here’s an example “daemon” that uses looper to kick it:

require 'looper'
require 'twitter'

class DoSomething
include Looper

def initialize(config)
@run = true
# do config stuff, etc...
@sleep = config[:sleep].nil? ? 60 : config[:sleep]
end # initialize

def run
loopme(@sleep) do
# this is where the meat of your code goes...
messages = twitter.direct_messages({:since => Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z")})
rescue Twitter::EpicFailure => e
puts "bailing out, dude!"
# set run to false to put the kabosh on the next run
@run = false

# and here's how we kick it off:
DoSomething.new( { :sleep => 10 } ).run

Pretty simple, right? No coding up the signals, the sleeping, the global exception handler, etc. You can take a look at looper.rb to see exactly what it does for you. From here, starting and stopping our script is really easy, and can be re-used for each of our daemons. It boils down to starting it up with nohup (and script/runner because we like having our rails stack), and then killing it later with the PID:

$ nohup script/runner -e RAILS_ENV /path/to/DoSomething.rb

There’s no need to use Rails’ script/runner, you could just call ruby itself and save yourself a lot of memory ;-)

The following is an init script that we use to start and stop any of our Looper daemons:

# chkconfig: 345 70 30
# description: control script for daemons

echo $"Usage: $0 {start|stop|restart} {daemon1|godzilla|voltron}"

# daemon name is required as second param
if [ "$2" = "" ]
exit 5

if [ "$RAILS_ENV" = "" ]; then

if [ "$RAILS_ENV" = "production" ]; then
else # assume development



# if the daemon is missing, well, the daemon is missing!
test -f $PROGRAM || exit 5

# See how we were called
case "$1" in
nohup $RUNNER -e $RAILS_ENV $PROGRAM >> $LOG 2>&1 &
PID=`ps auxw | grep ${PROGRAM} | grep -v grep | awk '{ print $2 }'`
echo "Stopping PID: ${PID}"
kill $PID
sleep 2
$0 stop
$0 start
exit 1

exit 0
Zetetic is the creator of the super-flexible Tempo Time Tracking system.

ckFormLogin and a happy user

Permalink - Posted on 2009-01-16 00:00

Today’s dose of win:

“Alright!! It’s working against the production servers – monitoring 6 web apps across three servers. My boss is very happy. That means I am even happier. I have been working with Nagios now for roughly 4 months. The user login test was the final piece of this project. Thanks again for the help.”

How cool is that? We have a plugin for Nagios called ckFormLogin that monitors login processes for popular asset management systems (Oracle CoreID Access Manager, CA eTrust Siteminder, Sun Access Manager, &c.), and when people have a little trouble with it, we’re pretty happy to help them out. But rarely do you get cool feedback like that.

Nagios itself is a really useful and highly configurable piece of monitoring software. The interface is a bit Soviet, sure, but it works great, and it’s open source. So is the ckFormLogin plugin.

Virus Utilization

Permalink - Posted on 2009-01-15 00:00

This post is probably not what you’d expect. But our time-tracker service Tempo has some great charting capabilities. Behold, the effects of a recent virus (of which I will spare you the horrific details) on my productivity:

Above is the Heads-Up-Display, at the top of the main screen. It reads pretty easily – my productivity was sent to bed!

Check out the utilization chart, which is a bit more instructive as to what happened, and when. That’s accessible by clicking the productivity percentage number box in the HUD, or just pulling it up from the Charts tab:


Utilization is a measurement concept in Tempo that is supposed to give you a ballpark idea how much of your time is accounted for, compared to how much time is generally available in a work-day. So, for every day in a report, the par for the day is considered to be 7 to 9 hours (which is a pretty common length for a workday), and that’s the horizontal, light-blue bar going across the graph between 7 and 9 on the Y-axis. The bars then show us a visual comparison of our utilization for the time periods. If I were to expand the date range enough, these would be grouped by week, then by month. Here’s what my utilization looks like since Nov 1st, 2008, until now:

So 2008 was a pretty productive year for us here at Zetetic. I can’t really go through it all right here and right now, but we’re quite excited about the new year, improvements we’ll be making to our existing products, and the new products and services we’re currently building.

And with that I’m going back to bed. Offers to send me comfort whisky, cheese burgers and nurses will not be turned away outright.


Permalink - Posted on 2009-01-11 00:00

I guess it kinda makes sense that Tetris could interrupt the brain from developing PTSD, it definitely interrupted my childhood for a few solid months at a time: (h/t Tim F.)

These results support Holmes’s theory that Tetris can help to prevent PTSD flashbacks by occupying the brain’s energies during the narrow time window when traumatic memories are consolidated. …snip…

But EMDR is only used to treat PTSD and there are several ways of doing that. Holmes’s goal is more proactive – she wants to find ways of preventing the symptoms from appearing in the first place. There are a few potential options for doing that, from drugs to psychotherapy, but few can be delivered so quickly or cheaply as a quick game of Tetris on a handheld machine. The game has another big advantage in that it affects a person’s reactions to an event but not their actual memories of it – Holmes notes that they would feel relief, but their ability to, say, testify in court wouldn’t be diminished.

Yes, I just downloaded the version that’s available in the App Store. What an easy preventative to make available for people — pretty much everyone has a cell phone, especially troops in combat. Doesn’t take much processing power or graphics to run Tetris!

Clearing a Popup Key LOV in Oracle APEX

Permalink - Posted on 2009-01-09 00:00

In the environment of one of our clients, we use Oracle’s Application Express product quite heavily for their identity and access reporting — we’ve got five full blown apps running in that framework at this point. Once in a while we hit a snag in development of an application and post the solution here.

Imagine you’ve got this asset management application for a very large organization, called Conglomo, which has thousands of franchises all over the world. The application holds files that users can see in a portal app. Basically, you upload files, you assign them to organizations (franchises, districts, regions, &c.) and users, and when a user logs in, she can see the files assigned to her or to any orgs in her hierarchy. From there you have a management screen for files, that is basically a report listing them out, and giving you some filters to narrow it down. Say you want to see all files linked to a particular org. The piece of data you need is really the org’s unique ID number, but users need a real way to search for a franchise named “Jack’s Conglomo Outlets Inc,” perhaps and in particular, the one in Bakersfield, California. They don’t want to have to look for org # 5003886, they don’t even know the number.

Well, the ready made Popoup Key LOV form element is just the thing. You drop in some SQL to generate the LOV, and voila you get a nice searchable list. Using a query in this way you can easily concatenate a bunch of fields about the organizations so that when the use is searching for a particular dealer, they have other factors to look at besides the name (and many of them are named quite similarly):

id || '-> ' || arnumber ||' '|| name ||' ('|| division ||' '|| type || ')' as d,
id as r
from organization
order by 1

This gives us a Popup Key LOV that looks like this:

When you select an org, the form element drops the display name into that disabled text area, and in a hidden element it drops the key’s value:

<input type="hidden" name="p_t05" value="105" id="P5_ORG_HIDDENVALUE">

So in APEX-land, when we make a report, it’s nothing like what you see in other frameworks, really. We just have one big query that draws up our table. So when we add a new element above, we need to amend the WHERE clause on our query to include that criteria if it was specified. Here’s an example of what I mean:

to_char(f.created_at, 'dd-MON-yyyy HH:MM AM') as created_at
naap_files f


AND ( :P5_ORG IS NULL OR f.id IN (
SELECT nof.file_id FROM organization_files_join_table nof
WHERE nof.organization_id = :P5_ORG

So, in this simple case, we’ll get all files if :P5_ORG IS NULL (that’s our Popup Key LOV element in our form). If it’s not null, we limit the list of files to those that are listed in the join table as belonging to the specified Org ID number.

And this really works out great until you need to clear the field because you’re no longer interested in files belonging to Org 105. In the image above you can see a “Clear this field” link in the popup. That’s actually the null option in the elements configuration, you can see it here:

When you click the null option, “Clear this field,” you’ll see the disabled text element get cleared. However, it isn’t really NULL that is sent back up to the host when you submit the form next. The hidden field we saw before is actually set to the string 'undefined'.

<input type="hidden" name="p_t05" value="undefined" id="P5_ORG_HIDDENVALUE">

So, when you submit the form, you’re not sending an empty string, which APEX just turns into a NULL value, you’re literally getting the string undefined, which your query then binds as the org id number! And then no rows come back! FAIL! This may be fixed in later versions of APEX (we’re working in 3.0x), but I did some digging and it doesn’t look like it.

Problems sending an actual NULL value for a select list or some other multi-select element in APEX are nothing new, basically the value that is actually sent is '%null%', even though you specify nothing at all. There are a few workaround, but I usually drop an application computation into each of my apps that zaps these guys and terms them into actual NULL values. I found this solution somewhere inside the APEX forum, I didn’t come up with it myself, but it’s pretty much SOP for anyone doing this kinda work, a PL/SQL block that is run On Submit After Computations and Validation:

FOR rItem IN
IF V(rItem.ITEM_NAME) = '%null' || '%'
Apex_Util.set_session_state(rItem.ITEM_NAME, NULL);

Since we have this in place, we can just update this bad boy to zap ‘undefined’ values as easily:

FOR rItem IN
IF (V(rItem.ITEM_NAME) = '%null' || '%') OR (V(rItem.ITEM_NAME) = 'undefined')
Apex_Util.set_session_state(rItem.ITEM_NAME, NULL);

It’s a little odd that even in this fairly recent version of APEX you still have to jump a hoop or two to handle null value submissions, and even weirder that you get '%null%' in some cases and 'undefined' in others. Any web framework has to deal with this kinda thing, but a little consistency would be nice. Hope this is a good primer and introduction to the problem if you’re new to APEX. Although, I have to say that aside from a few weird quirks like this, APEX is absolutely awesome for a situation in which you need to throw together a webapp in a client’s environment and they aren’t interested in any “risky” new fangeled technology like Rails!

It’s hard to convince large companies to work with emerging platforms. There is always a perception of risk that makes tried-and-true platforms like Oracle APEX attractive. I still sometimes yearn to have used Rails for one of these projects, but honestly I can throw together these applications MUCH faster and with way less overhead. I may not have quite the flexibility I get with Rails, but this is all really PL/SQL running on a giant modified mod_plsql, and you can do all kinds of crazy stuff in PL/SQL.

Exporting Palm Strip Data

Permalink - Posted on 2009-01-06 00:00

I’ve responded to so many of these requests by email that it’s probably time to put up a reference for folks who’re looking for some answers.

Palm Strip has been a pretty popular and highly secure password manager for the Palm OS that Stephen built a while ago and released as open source. You can read more background on it over here. Due to the decline in the Palm platform over the last few years, we’re no longer supporting the program. Just as many of our users are migrating to other platforms, so are we. We decided to go with the iPhone platform first, and we hope to have the first version ready by the end of this month. It sports a fully encrypted database layer and the interface is coming along nicely.

As part of our effort to help our users migrate to the new platform, and to assist those users who can’t wait or are choosing to migrate to other platforms, we’re working on an exporter that will rip through the encrypted Palm Strip database (*.pdb) files and generate a file that you could use to migrate to another system. Needless to say, this isn’t ready yet, but it will be available by the time we’ve got our initial version out in the iTunes App Store.

Current options for exporting your data from the old Palm databases are fairly limited. Dave Dribin put together an excellent program called perl-strip a while back and a supporting Perl module. This provides you with an avenue if you’re technically inclined.

It is possible to run Strip on your desktop computer using an emulator:

  1. Get the emulator software by signing up for the developer program at Access Inc
  2. Download the PalmOS ROMs from your own device to the emulator (the safest approach). Alternatively you could try to grab ROMs at this link. Caveat emptor – we can’t vouch for their authenticity.
  3. Use the emulator to open up your backed up copies of the Strip databases

For those asking about whether the next version of Strip will be open source – yes and no. We are believers in open-source technology and the benefits it provides to security software in particular, so our data encryption layer is being made available as open source software for peer review. The rest of the source of the iPhone application will be private, and we will charge a modest fee for the software.

Please don’t hesitate to leave comments or to write us at support AT zetetic.net with any questions!

Hey! You! Get Offa My Cloud

Permalink - Posted on 2009-01-05 00:00

There was a really quite interesting discussion over on Hacker News in response to an Ask HN query, “AWS or dedicated server?” over the last 24 hours. We haven’t made the jump to Amazon’s platform here at Zetetic, but I’d be lying if I said we haven’t been mulling it over. New year, time to revisit some of these questions.

Happy new year, by the way!

Totally off topic: I had intended to leave comments open on our recent post Ranting Considered Useful, and was wondering the other day why we saw none despite the surprising amount of traffic. This would be a PEBCAK error. The moment’s passed, but I have opened up the comments there for anybody who wants to respond.

Ranting Considered Useful

Permalink - Posted on 2008-12-30 00:00

In contrast there are masters in the martial arts who learned their art as a means of survival and became masters in a realistic and hostile environment. We don’t have anyone like this in the programming profession, or at least I haven’t met any. I believe that my generation of developers will produce the kind of masters forged in the real professional world. ~ Zed Shaw

I think that’s probably a prescient assessment of things in the hacker profession right now, and it takes a certain amount of audacity to make such a declaration. Zed Shaw is one of those people who seems to really have his finger on the pulse of things in the tech world, and he doesn’t mince words. I tend to think that his rather contrarian views in the various Ruby circles are mostly a result of an unwillingness to accept gospel over logic, and while some folks see this sort of thing as peeing in the mailbox, it really never hurts to have someone around who’s willing to stand up and call bull when he sees it.

Stephen and I were talking yesterday morning about Zed Shaw’s recent blog post wherein he declared that he is retiring from the ranting-on-ruby scene, and I thought maybe we should put something up here taking notice, because Zed has been an important voice in the Ruby-centric tech community. You may not like his over-the-top style, he may have you given you the finger at some point, but you may have deserved it, too. We generally keep our distance from the spats that seem to break out in the Ruby community (it’s a sport not unlike watching train wrecks, and we’re pretty busy people), and often wonder where some of these folks find the time. So I’m guessing that kind of thing wears on you as a real critic in the thick of it, and I’m not surprised if Zed is getting bored. However, Stephen suggested something this morning that bears repeating:

“Indirectly [Zed’s rants] served as jump off points for a lot of other people to say, you’re right this is screwed up, gave people a way to question the core team, who, by most measures are held up as infallible technology gods. By taking such an unpopular and extreme view he opened a lot of middle ground for people to take up well-thought-out positions that were contrary to the core of the Rails community elite. He kind of made it ok. That is a function that will be missing now, especially with the approaching Rails / Merb love fest.”

I tend to think that more criticism is always better than less, and that’s sort of the point of open-source development. So, if Zed is retiring from the rant stage, I’m hoping that maybe we can look forward to seeing more of his essays, which are really informative, well-written, and considered writings in that style of his:

After reading that first one I found myself engrossed in a historian’s letters on the subject of the popularly accepted but likely fictional accounts of Myamoto Musashi. The second had me learning this cool statistics programming language and graphing toolkit I’d never heard of called ‘R’.

I think we can expect to see more of this, but I hope others have gotten as much out of Zed’s ranting as we have, it’s been a fun read.

Deep Thought

Permalink - Posted on 2008-12-30 00:00

Isn’t it time for Sun to buy Palm and just get it over with already?

Data Pr0n

Permalink - Posted on 2008-12-23 00:00

The newest version of the Statistical Abstract of the United States for 2006-2009 is now available online from the US Census Bureau over here. Invaluable data reference. Murders! Price indexes! Agricultural output! Metropolitan Statistical Areas! Prison counts! Per capita income! Banking and financial stuff! The list goes on.

I was that kid who read history textbooks for fun, so I hope you’ll excuse the geeking out.

Service Announcements

Permalink - Posted on 2008-12-22 00:00

We’ll be interrupting service quite briefly on Tempo and PingMe tonight to push some service updates, around 10pm EST.

  • PingMe: Greatly improved reliability on Twitter follow-backs
  • Tempo: Fix to that nagging issue with Basecamp project imports
  • Tempo: Reverting to context-scoping of tags displayed in Include and Exclude drop-downs

We’re using our own version of the Twitter Ruby gem that has some additional support for exception handling that we needed. Caveat emptor, but it works pretty well for us, solves the issue of being able to respond accordingly to errors as the come back from the Twitter API. Not all 403’s are the same, that kind of thing. You can check it out over here. At some point I’ll get a blog post together describing how it works. Bit busy right now.

Darn Good Website - WNYC.org

Permalink - Posted on 2008-12-22 00:00

I just want to quickly point out what a great website they have over at WNYC.org, a radio feed that I usually leave running all day while I’m hacking away. Aside from the fantastic programming, they have a really keen integration between their on-air programs and the website. While you’re listening to their shows you can hop on over to a thread of the particular segment you’re listening to and interact with other users in the comments. Simple thought there, nothing really new technology-wise, just expertly positioned and well-made.

Someone Who Gets It

Permalink - Posted on 2008-12-16 00:00

The brevity of PingMe’s current syntax isn’t for everybody, but once in a while we run into somebody who totally gets it!

This is crazy week where we try to get an absurd amount of work done before the holiday. More blogging to follow, stay tuned.

Tempo Updates: Timer Display and Widget

Permalink - Posted on 2008-12-13 00:00

We made a quick update to Tempo today, will make this brief:

  • Display of start and stop times in entry notes is now a user preference.
  • In addition, you can specify append or prepend for timer display.
  • There’s a new API field ‘timer-sessions’ on the entry resource
  • Dashboard Widget prevents double-submission of an entry.
  • Dashboard Widget is a little bit taller.

You can download the updated Dashboard Widget for Mac OS X here.

The timer-sessions field presents the start and stop times one after the other, semi-colon delimited. It looks like this:

<command>posting about new changes @blogging</command>
<timer-sessions>11:16 AM - 11:16 AM; 03:56 PM - 03:57 PM</timer-sessions>

Yet Another Deep Thought

Permalink - Posted on 2008-12-12 00:00

Zetetic is too big to fail.

Deep Thought

Permalink - Posted on 2008-12-12 00:00

::You can never have too many user preferences::

The trick seems to be displaying them in such a way that it is easy for the user to identify what she is looking for with minimal effort.

Zetetic.net Launch!

Permalink - Posted on 2008-12-10 00:00

Welcome to the re-designed home of Zetetic! While the company has always been named Zetetic, most of our big clients have known us through our DBA, Identicentric. We decided that one awesome brand is better than two, and as part of our consolidation we had nGen Works come up with a new logo for us, and a whole new website design.

For those of you reading the RSS feed, I encourage you to click on over, check out the site, and leave us your thoughts in the comments. It’s not quite so hid anymore, I promise. Here’s the new logo, that has us really stoked:

One thing I really love about it is that it tells you how to pronounce our name. The badge is actually green on the site, although I think it will be white background when printed without color. But I digress!

We’ve only got the basics up right now: home page, blog, contact. Soon we’ll have the rest of the pages up, including documentation and links for our various resources, products, consulting services, and open-source projects.

Introducing Tempo: Analyst

Permalink - Posted on 2008-12-09 00:00

Today is the day we unveil the newest release of Tempo: Analyst!

It’s been quite a few months in the making, built on our own experiences using Tempo to do our time tracking and billing, and from the constant feedback of our users and beta testers. I can’t stress enough that good communication with our users has been just as valuable as elbow grease. If you’re used to the old interface, you will find the change a bit jarring at first, but we are positive that once you make the switch you really won’t want to go back (for the past three months we’ve used the Analyst interface exclusively and can’t bring ourselves to use the old interface).

For new and old users alike we’ll take a fresh look at Tempo, its unique approach to both tracking and reporting, and show off the new interface along the way. There are a lot of time trackers out there. Many claim to be the simplest; triumphs of design over functionality. Others are top-heavy in functionality but oblivious to how real people work and bill their clients. Our focus with Tempo has always been to make the act of tracking time so natural that it doesn’t interrupt your workflow while providing the powerful reporting you need to keep your business on track and manage your billing cycle.

Simple time entry

Tempo supports quick text entry for logging time or starting timers so you don’t have to track time yourself. You can specify tags using common @tag @notation, and you can specify a #project, #too, or Tempo will figure it out based on your previous billing.

Veteran users will notice a new feature in that screen clip above – quick stats on your personal reporting for easy reference.

Multiple methods of entry – work your way

Why should you have to fire up a whole web app just to log time? We want you to be able to quickly fire off a timer or time log without interrupting your workflow. To achieve this, Tempo supports input via Twitter, E-mail, a Dashboard widget for Mac OS X, a bookmarklet, mobile and iphone-optimized entry screens, and the web app itself. Typing any of the following will log time or start timers:

45m meeting with clients in NYC #conglomo @meetings @onsite

1h debugging evil NullPointerException @maintenance

1:30 full test of single sign-on system #konstrux @testing

working on blog post about Tempo:Analyst! #tempo @blogging

building encryption into iPhone app #internal @discovery

Notice those last two – they start timers! Just leave the time off the beginning of the string and off they will go (more examples). Each new timer you start will stop any other running timer and the time you spend on a task is automatically calculated for you.

Powerful Reporting

Our reporting interface didn’t just get a make-over – it got far more powerful, and faster to boot! For veteran users the major changes are obvious: we moved the controls up top and made the data report wide-screen. But there’s more to it than that:

  • The controls don’t submit on click, which was very annoying with large reports
  • Stream-lined drop-down options and easy-to-read display of selected options
  • Pagination! This is an incredible boon when you’ve got a lot of entries in a report
  • Optional HH:MM formatting, so you don’t have to think in decimal anymore ;-)
  • Sortable columns in the report! Imagine that!
  • An exclude option for tags! This makes our tag based reporting incredibly dynamic

Clearly, I’m so excited that I can’t stop typing!!!!1

With the new Exclude filter you can pull up all your entries tagged “development” and exclude anything tagged “design”, or “oracle”, for instance. We’ve always preferred tagging as a more realistic means for categorizing billed time in an effective way, and being able to exclude entries with a certain tag from a report adds the missing dimension. I don’t think you will get more dynamic reporting from any other time tracker out there.

Being able to quickly dial in your report options makes analyzing your data even easier because in Tempo…

What you see is what you get!

When you go the Reports screen, you are looking at a living, breathing…report, the Current Report. All of our charts, exports, and analytics are based on the current report, like the Heads-Up Display:

It gives you fast metrics to help you determine how things look, and each of the metrics can be clicked to bring up the appropriate chart. Here we can see that I’m at 90% utilization – the percentage of the workday that I spend actually billing time. Win!

Let’s step through Tempo’s reporting so you can get an idea of how this all works together:

1. Dial in a report

Here we see our heroic fictitious contractor Keith Kogane pulling all of his billable projects:

2. Save it!

He saves it for later – you’d normally do this for your Monthly, but here he saves it as Billable YTD:

3. Run it again at any time

Our hero needs to run that report again! Quickly now!

Clicking a saved report is like activating a saved set of filter controls. The new report appears with your settings already dialed-in.

4. View charts

Because Keith has pulled up a saved report, the Current Report displays the entries in the data view, but also modifies all the charts to this report. Keith needs to see a visual break down of hours per project, so he clicks the Project pie-chart icon and gets a modal chart display (that he can print!):

Ah, looks like this year’s bread and butter for Keith is that Conglomo project! He suspected as much, but being able to pull up a pie chart to visually confirm saves him from running a report on each project, writing down the total hours and comparing them. Here he can see visually how much his Conglomo work dwarfs the smaller projects like Konstrux. This kind of insight is important in deciding where to take your business and what priority to give your projects.

5. Export data

Like any smart fellow, Keith doesn’t want to be tied to one product forever, he needs to be able to access the very records that are the life blood of his business. In addition to an XML API, Tempo provides exports for your data:

Clicking the Time Log CSV will give you an Excel-ready export of your data:

Usually you need to export to Excel to hook into your invoicing solution. However, if you already use Blinksale or Quickbooks, you can use Tempo to…

6. Generate invoices!

There’s not much to tell here except that it’s a real nice time saver for us and a lot of the other Tempo users.

Playing to Win

There are a lot of time trackers out there, we know. But we think most of them got it wrong. Tempo is simply the best tool out there for freelancers, boutiques, and small to mid-sized consultancies. No other system makes it as easy to track your time and gives you tools to analyze what you’ve done so far and where you’re going.

Feel free to sound off in the comments, or e-mail us.

Deep Thought

Permalink - Posted on 2008-12-09 00:00

It’s not often you get to see a merge this awesome:

155 files changed, 9382 insertions(+), 918 deletions(-)

\m/ >_< \m/

New version of Tempo is live! We’ll have more to say about it here tomorrow morning.

Check it out

PingMe Updated

Permalink - Posted on 2008-12-08 00:00

Tonight we made the following adjustments to PingMe:

  • When you specify a ping without a year, and the date has already passed this year, the parser assumes you mean next year and adjusts the schedule accordingly.
  • Our follow-back code for Twitter should be a bit more reliable.

More to come in the weeks ahead, stay tuned.

FAILCamp Continued: Word List Fail

Permalink - Posted on 2008-12-08 00:00

Over the Summer, Stephen and I attended the excellent RubyFringe conference in Toronto, hosted by Unspace. One of the best events was FAILCamp, hosted by Joey Devilla. In FAILCamp we all shared our stories of failure, big and small. It was an interesting way to get to know everyone and to share strategies for working through screw-ups and taking something decent away from them.

So, in keeping with that experience, we’re going to share a bit of FAIL; today’s story is brought to us by the PingMe Address generator.

When we need to provide a user with a remote e-mail address on one of our services, we usually want it to be somewhat obscure to that it would be difficult to guess, like red99ballons@gopingme.com. The user can change it, but we set an initial one for her as a convenience, and include it in the welcome e-mail. The design goal was to ensure the address