Apple iCalendar's buggy SNI

TL:DR If you use Apple’s calendar client software, do not run the server on an IP and port shared with any other SSL/TLS services.

I run my own CalDAV calendar server for my family and for myself. For a very long time I used DAViCal, but it’s always been a slight annoyance to set up on Apple devices because they don’t like DAViCal’s URLs. What’s more, recent versions of iCalendar would pop up password prompts at random, and after re-entering the password a couple of times (once is not enough), would finally go on and work. The various devices would also all too often get out of sync, sometimes with the inscrutable error:

Server responded with “500” to operation CalDAVAccountRefreshQueueableOperation

requiring deleting the calendar account and recreating it by hand.

I tried replacing DAViCal with Radicale today, with the same flaky user experience, and I finally figured out why: Apple uses at least a couple of daemons to manage calendar and sync, including dataaccessd, accountsd and remindd (also CalendarAgent depending on your OS version). It seems some or all of them do not implement Server Name Indication (SNI) consistently. SNI is the mechanism by which a TLS client indicates what server it is trying to connect to during the TLS handshake, so multiple servers can share the same IP address and port, and is an absolutely vital part of the modern web. For example many servers use Amazon Web Services' Elastic Load Balancer or CloudFront services, which are used by multiple clients, if Amazon had to dedicate a separate IP address for each, it would break their business model1.

Sometimes, those daemons will not use SNI, which means they will get your default server. In my case, it’s password-protected with a different password than the CalDAV one, which is what triggers the “enter password” dialog. At other times, they will call your CalDAV server with dubious URLs like /.well-known/caldav, /principals/, /dav/principals/, /caldav/v2 and if your server has a different HTTP password for that and sends back a HTTP 401 status code instead of a 404 Not Found, well, that will also trigger a reauthentication prompt.

Big Sur running on my M1 MacBook Air seems to be more consistent about using SNI, but will still poke around on those URLs, triggering the reauthentication prompts.

In other words, the only way to get and Apple-compatible calendar server running reliably is to dedicate an IP and port to it that is not shared with anything else. I only have one IP address at home where the server runs, and I run other vital services behind HTTPS, so I can’t dedicate 443 to a CalDAV server. Fortunately, the configuration will accept the syntax to use a non-standard port (make sure you use the Advanced option, not Automatic), but this is incredibly sloppy of Apple.

  1. Amazon does in fact have a Legacy Clients Support option, but they charge a $600/month fee for that, and if you need more than two, they will demand written justification before approving your request. ↩︎

If WordPress updates hang on a 64-bit OS

The WordPress instance running this site was no longer able to automatically update plugins (and presumably not the core either) after I upgraded from a 32-bit to a sparkling fresh 64-bit PHP install at Joyent. It would start the update, and show a spinning logo and then just hang.

After much debugging, I found out the problem is that the class-pclzip.php that is responsible for unzipping was failing silently with the message:

Downloading update from

Unpacking the update…

Abort class-pclzip.php : Missing zlib extensions

This isn’t terribly helpful, but digging in, it turns out that class depends on the PHP zlib module, and on 64-bit operating systems (more precisely, operating systems with 64-bit large file support enabled), zlib.h #defines gzopen to be gzopen64. PHP does not protect itself adequately and thus the PHP function gzopen gets renamed gzopen64 as well, this throwing class-pclzip.php for a loop, along with a number of other systems like PEAR.

Fixing this requires recompiling PHP. Ubuntu Karmic includes a work-around, but I run Solaris and build from source, so I contributed a patch filed under bug #53829.

Automattic should probably patch class-pclzip.php to deal with gzopen/gzopen64 as there are a great many broken PHP installs out there (the PHP bug has been open for over a year and a half without what I would consider an acceptable solution), and it is surprisingly difficult to find a solution online. I guess a great many WordPress installs are still 32-bit, which is kind of sad.

Fixing Microsoft Office Mac 2011 font woes

This post may be of use to people experiencing the same problem I had. When I opened PowerPoint slides sent by a coworker, I was getting blank slides. Attempting to switch to outline view would crash PowerPoint. A search for possible solutions yielded inconclusive posts or dead-ends.

After much twiddling, it turns out the problem was with a misconfigured Arial font. Microsoft in its great wisdom installs a copy of Arial that conflicts with the system-supplied one, as explained in Kurt Lang’s must-read article on OS X font management, but that was not the root cause of the problem.

Arial was not appearing at all in the PowerPoint font menu, and opening the slides in Keynote yielded a font warning saying non-existent Arial was replaced by Arial Narrow. Clearly PowerPoint is much less resilient than Keynote to missing fonts (crashing in outline view mode is inexcusable, but that’s Microsoft coding sloppiness for you). If Arial is so vital, it should have been included as a resource in the application bundle itself, but I digress.

Font Book did show Arial as installed, with only a single copy after I purged the conflicting fonts as per Kurt Lang’s recommendations. Validating Arial in Font Book yielded a warning about duplicate fonts, but with no indication of where the duplicate may be, since Font Book itself did not know of any other instance.

It turns out I had an old pre-OpenType copy of Arial in my ~/Library/Fonts folder that was causing a conflict. It was functional enough to be picked up as conflicting and disabling Arial in PowerPoint and Keynote, but not functional enough to be listed by Font Book. I am not sure how it got there, possibly from an older version of Office and transferred over many machine upgrades. Removing the file fixed the problem. of blank slides and the crash in switching to outline view.

Of course, if you care at all about typography, you should use Helvetica rather than an inferior ersatz like Arial, but Arial is so prevalent in the taste-impaired Windows world that one cannot escape its gaucheness entirely.


Solving Mac freezes due to ocspd crashes

A public service announcement for anyone experiencing the same problem and who may google for a solution.

A couple of days ago my work iMac started experiencing intermittent freezing, and very slow searches in Rebuilding my Spotlight index overnight using sudo mdutil -Eav did not help. I started suspecting problems with recent versions of Chrome, or iTunes 10.5 Beta 7, but quitting those apps did not help either.

After running the, I noticed the following messages in my logs:

2011-09-14 17:39:20[1]	([3197]) Job appears to have crashed: Bus error
2011-09-14 17:39:21[3201]	2011-09-14 17:39:21.325 ReportCrash[3201:2903] Saved crash report for ocspd[3197] version ??? (???) to /Library/Logs/DiagnosticReports/ocspd_2011-09-14-173921_localhost.crash
2011-09-14 17:50:29[1]	([3269]) Job appears to have crashed: Bus error
2011-09-14 17:50:29[3270]	2011-09-14 17:50:29.964 ReportCrash[3270:2903] Saved crash report for ocspd[3269] version ??? (???) to /Library/Logs/DiagnosticReports/ocspd_2011-09-14-175029_localhost.crash
2011-09-14 17:50:45[1]	([3271]) Job appears to have crashed: Bus error
2011-09-14 17:50:45[3270]	2011-09-14 17:50:45.117 ReportCrash[3270:2807] Saved crash report for ocspd[3271] version ??? (???) to /Library/Logs/DiagnosticReports/ocspd_2011-09-14-175045_localhost.crash

Looking at those crash dumps did not yield very useful information, just some blather like this:

Process:         ocspd [3197]
Path:            /usr/sbin/ocspd
Identifier:      ocspd
Version:         ??? (???)
Code Type:       X86-64 (Native)
Parent Process:  launchd [1]

Date/Time:       2011-09-14 17:39:19.339 -0700
OS Version:      Mac OS X 10.6.8 (10K549)
Report Version:  6

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: 0x000000000000000a, 0x000000010009b210
Crashed Thread:  0  Dispatch queue:

Thread 0 Crashed:  Dispatch queue:
0            	0x00007fff87b59d0b Security::ReadSection::at(unsigned int) const + 25
1            	0x00007fff87b59172 Security::DbVersion::open() + 62
2            	0x00007fff87b58cc1 Security::DbVersion::DbVersion(Security::AppleDatabase const&, Security::RefPointer const&) + 179
3            	0x00007fff87b587ce Security::DbModifier::getDbVersion(bool) + 330
4            	0x00007fff87b58675 Security::DbModifier::openDatabase() + 33
5            	0x00007fff87b582b9 Security::Database::_dbOpen(Security::DatabaseSession&, unsigned int, Security::AccessCredentials const*, void const*) + 221
6            	0x00007fff87b576c1 Security::DatabaseManager::dbOpen(Security::DatabaseSession&, Security::DbName const&, unsigned int, Security::AccessCredentials const*, void const*) + 77
7            	0x00007fff87b575a3 Security::DatabaseSession::DbOpen(char const*, cssm_net_address const*, unsigned int, Security::AccessCredentials const*, void const*, long&) + 285
8            	0x00007fff87b6b294 cssm_DbOpen(long, char const*, cssm_net_address const*, unsigned int, cssm_access_credentials const*, void const*, long*) + 108
9            	0x00007fff87b6ae3a CSSM_DL_DbOpen + 106
10  ocspd                         	0x0000000100006ad9 0x100000000 + 27353
11  ocspd                         	0x0000000100006cab 0x100000000 + 27819
12  ocspd                         	0x0000000100001f68 0x100000000 + 8040
13  ocspd                         	0x00000001000176ed 0x100000000 + 95981
14  ocspd                         	0x000000010001787b 0x100000000 + 96379
15  ocspd                         	0x0000000100017e4f 0x100000000 + 97871
16  ocspd                         	0x0000000100004613 0x100000000 + 17939
17  ocspd                         	0x0000000100001d48 0x100000000 + 7496

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x000000010008e000  rbx: 0x000000010008e000  rcx: 0x00007fff88f0d47a  rdx: 0x000000000000d210
  rdi: 0x0000000100115478  rsi: 0x000000000000d210  rbp: 0x00007fff5fbfe850  rsp: 0x00007fff5fbfe850
   r8: 0x0000000000000003   r9: 0x0000000000000000  r10: 0x00007fff88f0597a  r11: 0x0000000000000206
  r12: 0x0000000100115478  r13: 0x00007fff5fbfecd0  r14: 0x00007fff5fbfecd0  r15: 0x00007fff5fbfed20
  rip: 0x00007fff87b59d0b  rfl: 0x0000000000010297  cr2: 0x000000010009b210

Binary Images:
       0x100000000 -        0x10003cfef +ocspd ??? (???)  /usr/sbin/ocspd
    0x7fff5fc00000 -     0x7fff5fc3bdef  dyld 132.1 (???)  /usr/lib/dyld
    0x7fff80853000 -     0x7fff80859ff7 2.3 (2.3)  /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration
    0x7fff80baa000 -     0x7fff80c27fef  libstdc++.6.dylib 7.9.0 (compatibility 7.0.0)  /usr/lib/libstdc++.6.dylib
    0x7fff811af000 -     0x7fff81268fff  libsqlite3.dylib 9.6.0 (compatibility 9.0.0)  /usr/lib/libsqlite3.dylib
    0x7fff812e9000 -     0x7fff8161dfef 861.39 (861.39)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore
    0x7fff82092000 -     0x7fff82122fff 1.3.0 (1.3.0)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit
    0x7fff8229d000 -     0x7fff822c8ff7  libxslt.1.dylib 3.24.0 (compatibility 3.0.0)  /usr/lib/libxslt.1.dylib
    0x7fff82695000 -     0x7fff826d2fff 2.0 (120.1)  /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP
    0x7fff82954000 -     0x7fff82966fe7  libsasl2.2.dylib 3.15.0 (compatibility 3.0.0)  /usr/lib/libsasl2.2.dylib
    0x7fff82ae1000 -     0x7fff82b81fff 362.3 (362.3)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices
    0x7fff82c8f000 -     0x7fff82c9dff7  libkxld.dylib ??? (???)  /usr/lib/system/libkxld.dylib
    0x7fff82d0e000 -     0x7fff82dc4ff7  libobjc.A.dylib 227.0.0 (compatibility 1.0.0)  /usr/lib/libobjc.A.dylib
    0x7fff82dc5000 -     0x7fff82de6fff  libresolv.9.dylib 41.0.0 (compatibility 1.0.0)  /usr/lib/libresolv.9.dylib
    0x7fff8349e000 -     0x7fff834adfff 3.2.2 (3.2.2)  /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS
    0x7fff83a2b000 -     0x7fff83a41fef  libbsm.0.dylib ??? (???)  /usr/lib/libbsm.0.dylib
    0x7fff83a42000 -     0x7fff83bb9fe7 6.6.5 (550.43)  /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
    0x7fff83bbe000 -     0x7fff83c92fe7 454.12.4 (454.12.4)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/CFNetwork
    0x7fff83c93000 -     0x7fff83cbbfff 1.1.2 (1.1.2)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices
    0x7fff84905000 -     0x7fff849c2fff 359.2 (359.2)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices
    0x7fff849d8000 -     0x7fff84a38fe7 2.0 (???)  /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
    0x7fff850ef000 -     0x7fff8513bfff  libauto.dylib ??? (???)  /usr/lib/libauto.dylib
    0x7fff851a2000 -     0x7fff851ddfff 496.5 (496.5)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE
    0x7fff8525f000 -     0x7fff85270ff7  libz.1.dylib 1.2.3 (compatibility 1.0.0)  /usr/lib/libz.1.dylib
    0x7fff85b42000 -     0x7fff85b43ff7 1.1 (1)  /System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent
    0x7fff87921000 -     0x7fff8796bff7 10.6.3 (507.15)  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata
    0x7fff87b2b000 -     0x7fff87db4ff7 6.1.2 (55002)  /System/Library/Frameworks/Security.framework/Versions/A/Security
    0x7fff88b46000 -     0x7fff88b4aff7  libmathCommon.A.dylib 315.0.0 (compatibility 1.0.0)  /usr/lib/system/libmathCommon.A.dylib
    0x7fff88f02000 -     0x7fff890c3fef  libSystem.B.dylib 125.2.11 (compatibility 1.0.0)  /usr/lib/libSystem.B.dylib
    0x7fff8921b000 -     0x7fff8933afe7  libcrypto.0.9.8.dylib 0.9.8 (compatibility 0.9.8)  /usr/lib/libcrypto.0.9.8.dylib
    0x7fff8933b000 -     0x7fff89378ff7  libssl.0.9.8.dylib 0.9.8 (compatibility 0.9.8)  /usr/lib/libssl.0.9.8.dylib
    0x7fff89494000 -     0x7fff894d5fff 1.10.8 (1.10.2)  /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration
    0x7fff8953e000 -     0x7fff896fcfff  libicucore.A.dylib 40.0.0 (compatibility 1.0.0)  /usr/lib/libicucore.A.dylib
    0x7fff89b66000 -     0x7fff89b66ff7 44 (44)  /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
    0x7fff8a545000 -     0x7fff8a65cfef  libxml2.2.dylib 10.3.0 (compatibility 10.0.0)  /usr/lib/libxml2.2.dylib
    0x7fffffe00000 -     0x7fffffe01fff  libSystem.B.dylib ??? (???)  /usr/lib/libSystem.B.dylib

Some of the information you get when googling for the error message is misleading, suggesting ocspd is somehow tied to nVidia graphics drivers. It is in fact the system daemon that handles verification and revocation of SSL certificates using the Online Certificate Status Protocol (OCSP), a vital component of the Internet’s security architecture, as evidenced by the recent Diginotar fiasco. Thus presumably it is used throughout Internet apps like or Chrome, and the regular crashes (at 3 minute intervals or so) would also freeze any apps that make use of cryptography.

The solution was to delete the the temporary certificate revocation list (CRL) databases ocspd maintains:

sudo rm -rf /private/var/db/crls/*
sudo rm -rf /private/var/db/crls/.fl*

A corrupted database is probably responsible for the repeated crashes I observed, and clearing those solved my problem. You may want to make backups of those files instead of just deleting them.

As usual, I disclaim responsibility for any harm this procedure may do to your computer, or induce it to eat your dog, who ate your homework.

So much for the theory that the Mac “just works”. To paraphrase Churchill, it is the worst operating system, with the exception of all others…

Update (2014-04-30):

Well, at least OCSP works on the Mac. You can test it by trying Google Chrome also rejects this, but being Google, they don’t use the standard and implemented their own seriously flawed CRL distribution mechanism  (they manually blacklisted the GRC test site, for instance). Safari on iOS does not block the site at all (a StackOverflow thread suggests verification is only performed for EV certificates, which is are used in only a tiny minority of SSL/TLS sites).

Clearing custom crop aspect ratios in Lightroom

Lightroom’s crop tool allows you to constrain the aspect ratio to a proportion of your choice, e.g. to 4:3, defaulting to the same aspect ratio as the original. The last 5 or so custom crop aspect ratios are saved, but a minor annoyance is you are unable to clear the list.

Python on the Mac and SQLite to the rescue: this simple script will reset them. If you use a non-default name for your Lightroom catalog, you will need to edit it. To run it, quit Lightroom and run the script. It will back up your catalog for you just in case.

Needless to say, I cannot be held liable if this script corrupts your catalog or eats your dog (who ate your homework), use at your own risk.

import sys, os, sqlite3

# edit this to point to your LR3 catalog if you do not use the default location
lrcat = os.path.expanduser('~/Pictures/Lightroom/Lightroom 3 Catalog.lrcat')

os.system('cp -i "%s" "%s.bak"' % (lrcat, lrcat))
db = sqlite3.connect(lrcat)
c = db.cursor()
c.execute("""select value from Adobe_variablesTable
where name='Adobe_customCropAspects'""")
crops = c.fetchone()[0]
print 'aspect ratios:', crops
c.execute("""update Adobe_variablesTable
set value='{}'
where name='Adobe_customCropAspects'""")
print 'Custom crop aspect ratios reset successfully'