At the Forge - Sharing Calendars
Over the last few months, we have explored the iCalendar standard and the ways in which it allows us to create our own calendars, as well as work with remote ones.
But if you think about it for a moment, you'll realize we are missing a key piece of functionality. We have seen how easy it is to create our own local calendars. We have seen how we can retrieve remote calendars. We have even seen how we can create and distribute remote calendars, generating events dynamically from a Web/database application. But we have never considered how an individual Sunbird user might be able to share his or her calendar with other people.
Anyone who has worked in even a medium-sized organization knows that scheduling appointments can be difficult. Having access to everyone's calendar, and being able to schedule meetings for them, is an increasingly useful feature for our software to have. If every change I make to my calendar is available for everyone to see, it will be easier for them to schedule meetings when I will be around. (Or when I won't be around, if they want to keep something secret from me.) I used to ask clients why they use Microsoft Exchange as a mail server, given the availability of excellent open-source alternatives; inevitably, the answer would have more to do with the calendar support in Outlook and Exchange, rather than the e-mail functionality.
This month, we close our exploration of Sunbird and iCalendar with a look at how we can publish calendars to a central repository for others to share. The results might not be as slick or smooth as some of the commercial alternatives, but as with many other types of software in the open-source world, I believe that this is rapidly changing, and that we soon will see open-source calendar servers that are equal or superior to their proprietary counterparts.
Before we try to share a calendar, we should define exactly what we mean by sharing. You might think that shared calendars are stored in a single place and accessed by multiple calendar programs simultaneously. Although it is theoretically possible to configure Sunbird, or any other iCalendar-compatible program, such as Evolution, in this way, this is not what we would typically expect.
Basically, a shared calendar in the iCalendar world is an iCalendar file that is available for retrieval from a publicly accessible server. That iCalendar file might be updated once per hour or once per year; much like an RSS feed or a Weblog, there is no way to know how often a particular calendar file might be updated. For this reason, we need to make several assumptions: 1) everyone who is interested in this particular calendar is subscribed to it; 2) every subscriber downloads an updated version of the calendar on a regular basis, at least once per day; and 3) the calendar's manager publishes all changes and updates to the public server as soon as they are made.
In other words, the sharing does not take place in real time at all, but rather depends on all of the participating users to publish and retrieve updates on a regular basis. Between updates, a calendar user sees only the most recently downloaded iCalendar file, which is stored on his or her local computer. If a calendar subscriber is scheduled to retrieve updates only once per day, it is quite possible that he or she will miss last-minute updates to the calendar. Just how often someone should subscribe to calendar updates depends on the nature of the organization, how important it is to get updates and the load that might be placed on the server. After all, a server that can provide daily updates to 100 people might have trouble providing hourly updates to 10,000 people.
The easiest way to publish files on the Web is to use the old standby for file transfer, FTP. FTP has gone almost unused on my server for some time now, in no small part because of security concerns, but if you are working on a system that is properly secured, or if you would rather not use WebDAV (described below), FTP is a workable and simple way to share Web calendars.
On my server, running ProFTPd, I decided to create a new user (calendar) with a password (cal4atf). To ensure that this user cannot be used for remote logins or other mischief, I would like to give it a shell of /sbin/nologin, or perhaps /bin/false—both of which are programs that simply exit, without giving a malicious user any chance to log in and take advantage of my system. The problem with this approach is that FTP servers allow only users whose shell is in /etc/shells to log in. This presents us with something of a dilemma. We want to give the calendar user a non-interactive shell, but we also want the user to be able to use FTP. But, adding /sbin/nlogin to /etc/shells might open a security hole on our system. A simple solution is to copy /sbin/nologin to /sbin/nologin-but-yesftp and to add a line in /etc/shells with the latter shell's name.
Normally, non-anonymous users logging in via FTP are shown their own home directories. By default, ProFTPd goes one step further than this, forbidding users from going outside of their own home directories. Thus, we can rest assured that even if a malicious user gets a hold of our calendar user name and password, the worst that he or she can do is destroy or modify our calendar files. This is obviously not something we want to encourage, and in a production environment, you undoubtedly would want better security—giving everyone a unique user name and password, for example. But for this simple demonstration, we will forge ahead with our single calendar user, knowing that a security breach might well take our shared calendar files with it.
Assuming that we have configured FTP appropriately, how can we publish our calendar? From within Sunbird, we select the calendar we want to publish, which is called My Calendar by default. A menu pops up, the last option of which says, Publish entire calendar. If you select this option, a small dialog box opens, asking for the URL to which you intend to publish the calendar.
It goes without saying that the URL will begin with ftp://, but what comes after that? Assuming that the user name and password are as we indicated above, and that the server is calendar.lerner.co.il, we can access it as ftp://calendar:email@example.com/calendar.ics.
As you can see, we separate the user name and password with colons, and then put an @ sign between the password and the server name. Following the server is the name of the file we want to save. Although theoretically it can have any name or suffix, the .ics suffix is considered quite standard and ensures that all of the programs involved will understand the MIME types.
Now, let's say I make a change to my calendar. Must I now manually upload it to the server, going through this same procedure again? No, there is a way around this. Click on the calendar's name to get the same menu that you have already seen. Instead of selecting Publish entire calendar, select Edit calendar. This opens a dialog box that includes, among other things, a text field into which you can enter a URL, as well as a check box indicating that the calendar should be published whenever a change is made. I had mixed results using this functionality, although it worked more often than not and did a good job of keeping my appointments synchronized on different systems.
Subscribing to the shared calendar is similar to publishing it. Enter the full URL, including user name and password, and any iCalendar-compatible program should retrieve and display it. Of course, the configuration that we have put in place requires that the program can handle HTTP authentication.
FTP is fine for some tasks, but it has a number of drawbacks. To begin with, you might not want to run an FTP server on your computer, given its history of security problems. You also might prefer to have everything run over HTTP for performance reasons or because you can encrypt the transmission over SSL. For a variety of reasons, then, you might want to consider another alternative: mod_dav.
DAV, or Distributed Authoring and Versioning, makes it possible to create and modify files on a server, rather than just retrieve and read them. That is, DAV turns HTTP into a read-write protocol. DAV has been around for a number of years already, and mod_dav modules for Apache 1.x and 2.x have existed for some time. I am still using Apache 1.x on my main server, but it should be equally easy to install and use mod_dav for Apache 2.x.
To begin with, you need to download mod_dav (see the on-line Resources). Because I had compiled Apache with DSO (shared object) capabilities, I didn't have to recompile it from scratch in order to incorporate mod_dav. I merely had to tell it where to find apxs, the automatically generated Perl program that gives Apache modules all of the information they need in order to compile without the Apache source code. After unpacking the mod_dav source code, I typed:
Once done, I compiled and installed mod_dav:
make make install
I double-checked to make sure that my Apache configuration file, httpd.conf, was still intact after the modifications provided by make install. Following that, I configured Apache to include a new named virtual server, which I called davcal.lerner.co.il:
<VirtualHost 126.96.36.199> ServerName davcal.lerner.co.il ServerAdmin firstname.lastname@example.org # Directory and file names not beginning with / # are relative to ServerRoot ServerRoot /usr/local/apache/v-sites/davcal.lerner.co.il DocumentRoot www ErrorLog logs/error-log CustomLog logs/access-log combined CustomLog logs/referer-log referer DAVLockDB DAVLock <Directory /usr/local/apache/v-sites/davcal.lerner.co.il/www/> DAV On <Limit PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK> AuthName "Calendar DAV access" AuthType basic AuthUserFile passwd Require user calendar </Limit> </Directory> </VirtualHost>
Notice the DAV-specific directives in the above configuration section. I have set up where the DAV locking will reside with DAVLockDB, obviously outside of the HTTP-accessible DocumentRoot directory. I then turn DAV on for a particular directory and limit DAV access to the calendar user, with a password specified in an external file. That password file, which is also outside of the Web site's root directory, is created and updated with the standard htpasswd program, located by default in /usr/local/apache/bin.
Finally, notice that our <Limit> section specifies limits only for potentially dangerous requests. The standard HTTP GET request, by contrast, requires no user name or password. This is a good configuration if you want to let anyone subscribe to your calendar but give limited access for publishing and modifying the calendar file. If this calendar were going to be used in a business, you probably would want to limit access to it as well, perhaps by giving each user his or her own password.
We can publish this calendar by bringing up (once again) the Publish entire calendar dialog for a particular calendar. This time, we use an HTTP URL, without specifying a user name or password: http://davcal.lerner.co.il/calendar.ics.
This publishes the calendar to the site, as you can tell by looking at the appropriate directory on the server. You similarly can publish the calendar using WebDAV each time the calendar is updated, just as we saw before.
Finally, we can subscribe to this calendar using the same techniques that we have seen in previous months. Choose Subscribe to remote calendar from the File menu and enter the URL for this calendar file. Thanks to the magic of WebDAV, we even can use the same URL for writing and reading the file.
Although the open-source world might not have a fancy back-end calendar system like Microsoft Exchange, solutions exist that are more flexible and more than good enough for most groups.
I should note that Sunbird does appear to have some problems with publishing and subscribing; if nothing else, meetings that were listed as private on my Sunbird application continued to be marked in that way when the file was uploaded—and were then displayed as private when I subscribed to the calendar with a different program. Moreover, Sunbird continues to be slow when working with large calendars; however, that problem has been noted by the Sunbird developers and presumably will be fixed in the coming months.
There is also the promise of a new server for handling iCalendar files in Novell's Hula Project. Since Novell acquired both Ximian and SUSE, Hula is one of the most-hyped new projects to emerge from that combination. If Hula does indeed include iCalendar support, I will be curious to see how it improves on the FTP and WebDAV solutions I have outlined above. Until then, there are workable solutions that satisfy my own needs, as well as those of many other small organizations looking to collaborate with each other.
Resources for this article: /article/8323.