Mailman 3.0 alpha 6 was recently released. It's got a much better REST API now for integration. Please do give it a look!
We have a winner!
The logo contest is over and by a better than 2-to-1 margin, you the fine GNU Mailman community has picked your favorite new logo:
My congratulations to Andrija, and my sincere thanks to all the artists who contributed designs. And thank you Mailman community for helping to select the logo that will take us into the 2010's!
See the full announcement here.
Scheduled wiki downtime
Our wiki hosting provider is going to be updating the instance to the latest version of Confluence. This will require the wiki to be off-line for several hours (it's a big upgrade!). The current scheduled downtime will begin at 2200 UTC on Friday 2010-03-19.
We have a new logo contest!. We invite your submissions until February 28, 2010 March 15, 2010 2200 UTC. We've extended the contest due to some trouble with write permissions on the logo submissions page.
GNU Mailman's development is hosted on Launchpad and now Launchpad itself is officially and fully free software. While it was previously announced that two components would be held back, we (Canonical) changed our minds! Everything is licensed under the GNU Affero General Public License version 3.
This is significant for Mailman for two reasons. First, we are a GNU project so it's personally satisfying that our development is now hosted on free software and to know that now I work only on free and open software, both for pay and for not. Second, Launchpad's mailing lists are run by GNU Mailman so there are interesting integration issues involved. Some of the earliest design decisions about this integration strategy were driven by the need two and a half years ago, to keep a bright line between Mailman and Launchpad. That's gone now so the implementation of this can be reconsidered (although "if it works, don't fix it" applies here). I invite you to join us in the public forums to talk about Launchpad, Mailman, or both.
Mailman 3.0 alpha 2 (Grand Designs) is now available. This is the second alpha release of Mailman 3. It's not ready for production use, but feedback from early adopters is welcome.
Tracker migration to Launchpad: 1200UTC Th 04-Sep
We're planning to migrate Mailman's tracker data from SourceForge to
Launchpad. Expect the conversion to take several hours. The SF tracker must stay up during the conversion so be aware that any new bugs or changes during the conversion will be lost. I will turn off the SF tracker once the conversion is complete.
Pootle is free software that aids in translating open source projects. Thanks to Cristóbal Palmer, the Mailman project now has an experimental Pootle server. We urge all translators to give this server a try so that we can decide whether to officially switch to it, try something different or keep the status quo.
The Frequently Asked Questions are now fully imported into the wiki! Or at least, all the old FAQ Wizard links have been replaced with shiny new wiki links, and many of the pages have improved formatting.
Please note when you're linking entries (especially when posting to mailing lists) that you can get short URLs from the wiki by clicking on the "Info" link for the page and looking under "Tiny Link". Some of those FAQ links can be quite long, so this can be a handy feature.
I've been trying to make the wiki into the one-stop-shop for Mailman documentation, and as part of that process, I made a script that moved the Mailman FAQ entries into the wiki.
Check out the new Frequently Asked Questions!
You'll see that there's around 200 entries in there now, organized into sections as they were originally in the FAQ Wizard.
Unfortunately, my script didn't convert all of the internal FAQ links (ie - any link that starts with http://www.python.org/cgi-bin/faqw-mm.py) to internal wiki links, so I'm looking for volunteers who can help fix those links so they point to the new wiki entries. There's also reformatting to be done. Please take a look around and fix up an entry or two while you're at it, and if you have any questions feel free to contact me.
At long last, I've released Mailman 3.0a1. This being an alpha release – and the first such one – it's not ready for production use obviously. But it is a significant milestone, and should give interested folks a working snapshot of where the project is going. I hope you will download the new version and give it a look.
I have been awarded the 2008 Antonio Pizzigati Prize For Software in the Public Interest for GNU Mailman.
I am deeply honored to win this prize because I believe very strongly in Mailman's role in helping people communicate and organize. I want to thank all of you who have supported me and Mailman over the years, and I want to let you know that I am as excited as ever about where Mailman is going. One of the most satisfying aspects of this project for me has been meeting you, the users, developers and contributors to Mailman, both online and face-to-face.
I'm looking forward to meeting the Pizzigati family and having some time to spend with them learning about Anthony's remarkable life, sadly cut too short.
So again, thank you all and I'm looking forward to the next 10 years of GNU Mailman!
I've written before about what I think are the compelling reasons for the switch so I won't go into them here. But I do want to talk a bit about the process of the switch, which went very smoothly.
The first key thing was that well in advance of flag day, I requested that the Launchpad administrators begin to mirror the upstream Subversion branches that I ultimately intended to move. This wasn't all of the old branches, which will remain in the read-only Subversion repository, but instead just the trunk, 2.1, and admin branches. Then I branched these three locally and occasionally
bzr pull'd updates when the mirror saw commits to the Subversion trees.
This meant that by the time I was ready to switch, I had local up-to-date bzr branches sitting on my filesystem.
I also prepared by creating a few teams and projects to hold all the new data. I created the Mailman Coders team which will be how we manage write permission to the branches, and I created the Mailman Checkins team which will be used solely to feed branch diffs to the already existing Mailman Checkins mailing list.
At conversion time then, all I had to do was to push my local bzr branches to the ~mailman-coders team's hosted branch locations, and I was essentially done. When I pushed the branches with the new url, I used
--remember so that from then on the branches would use the correct url; I did the same with
bzr pull --remember and presto! the conversion was complete.
I should mention that cleaning up the old vcs-import branches (i.e. the Subversion mirror branches) was a bit of a pain, because I don't own these branches, the semi-fake vcs-imports user does. But hey, what a good way to owe my friend, fellow Pythonista and employee Michael Hudson some beers!
I got motivated by my friend Bob Fleck to do passwords right in Mailman. Bob wrote an implementation of PBKDF2 from RFC 2898 in Python. PBKDF2 is a scheme that uses a random salt and an iteration count to hash a password in a fairly secure manner. It also uses a pseudorandom function which we basically hardcode to SHA1, though we could support other PRFs in the future if we wanted.
While this was pretty cool, it really motivated me to do something I've wanted to do since about day one, and that is, to remove clear text user passwords from Mailman. One of the longest and most valid complaints from security-conscious users has been the monthly password reminders that Mailman sends out. This is only possible because Mailman stores users passwords in the clear. This is insane, but it's been like this forever. I've already ripped out the password reminder scripts in the Mailman 2.2 svn, but I hadn't yet gotten rid of cleartext user passwords. Now I have.
There is another RFC that I've looked at; RFC 2307 describes a scheme for specifying password hashes, which I believe originated with LDAP. Essentially, the scheme is prepended to the hash, delimited by curly braces. For example:
This says that what follows is the Base64 encoded salted SHA1 hashed password. To confirm a user's password, we simply perform these on their response:
- Base64 decode the user's hashed password
- Chop off everything after the 20th byte as the salt
- Hash the response and the salt and check it against the hashed user password minus the salt
The other important thing is that because we know the scheme used to hash the user's password, we can easily upgrade this to other hash schemes when the ones we've chosen get cracked. IOW, say we found out that salted-SHA1 hashes are easily cracked. Well, we switch to PBKDF2 or some other scheme and then whenever a user successfully logs in with their old password, we simply rehash it with the new scheme and store that in the database.
I've now committed all the code to support this, and also to use these hashed passwords for user passwords, list owner and moderator passwords, and site and list creator passwords. It really touched a relative small amount of code for a big improvement in security.
I now need to implement password resets since of course, user passwords cannot be recovered anymore. A user (or for that matter, list owner) should be able to request a password reset in a secure manner. Since I have a feeling most of that will be u/i work, and because we will eventually rewrite the current web interface, I'm deferring that for now. The other thing that I think will have an impact here will be a switch to role-based authorization, which is the next thing I think I'm going to work on.
Oh yeah, one other thing. Let's say the scheme were something like:
Now you have the ability to easily authenticate the user against an external web service.
The Summer of Code project has been highly educational, but sadly not as functional as I had hoped. I believe a good foundation exists at this point to deliver a much improved interface for mailman 2.3, and I will continue to work towards this goal.
First, I'll go over the good things that have come out of this, and then I'll talk a good deal about all the things that didn't work.
- WSGI App - as a "full" WSGI app, the new mailman UI will be embeddable in any framework that can handle WSGI, which appears to be the majority of them.
- Pieces for non-python apps - The new UI will allow people using any non-python web environment to embed chunks of the mailman UI into their web sites.
- Extreem accessability - I've tried to make sure that the mailman UI can be used by any user agent there is. At this point it should work fine on just about any device capable of parsing XHTML.
- i18n - While I'm not quite there on building .po files and the like, the approach taken is I think one of the best ways to ensure internationalization. All pages are utf-8, and there are zero strings inside the python code that require translation; if the templates are translated, the application is translated.
I spent a large portion of the middle of the project trying to make an approach work that would allow this UI to be included in the mailman 2.2 release, without success. First I attempted to implement a mod_python only approach, but after being bitten for the umpteenth time with mod_python's peculiarities about the import statement I decided to try other approaches.
Nobody seems to be interested in supporting python 2.3 in web framework land. I tried to use paste; the currently used servelet implementation, Wareweb, uses decorators. I spent a day or so trying to steal everything-but-the-decorators from Wareweb, but after running into problems I decided it wasn't the best use of time. Between this failure and the mod_python problems, I decided 2.3 just wasn't happening and thus I wasn't going to make it into the 2.3 release.
No User Model
This was one of my biggest challenges, but at this point I also think it is a strength. Mailman currently has no particular notion of users. An email address associated with a list has settings and perhaps even a password. Higher level privileges, of which currently there are "list admin" and "moderation" - require a username-less password.
This doesn't jibe with the classical notion of users, and for a while I struggeled with that. Now I think it's perfectly appropriate. Most humans-that-use-mailing-lists have multiple email addresses, and most people that deploy mailman mailing lists are doing so in the context of other web services that have their own sense of what a user is.
Currently under implementation is an approach where I consider an 'agent' to be a set of identifying strings - mostly email addresses, but also usernames and things like session-cookie tokens and even 'passwords'. Usernames, if any, are provided not by mailman, but by whatever site mailman runs under, in the form of a REMOTE_USER token or potentially other tokens as people let me know how they'd like to tell mailman who users are.
As soon as this is vaguely working, I also hope to support OpenID tokens, as a step towards mailman allowing "mailman wide" authentication; i.e. once you've signed up for any mailman list, new lists you subscribe to on other sites can automatically fetch information about you from other the other mailmen.
When mailman is provided sufficient user-tokens, it applies UI changes automatically; when it has been provided enough tokens to accept a user provisionally, it emails the address-of-record with a summary of the changes and an "apply" link. The common case of "provisional" authentication is a user-agent arriving with a visitation cookie that has been associated with an email previously, and the UA provides that email again.
For the Mailman UI, I wanted to leverage the work that has been done to make web programming easier. In pursuit of this, I investigated a number of web frameworks. The current situation in python-land is that all of the frameworks that provide support for kid are half-baked, and I ran into several problems using them.
- Turbogears - Being the only framework with kid as its default templating language, this is the framework I spent the most time on. Unfortunately turbogears breaks kid in some pretty fundamental ways; the most irksome of which is that the import statement doesn't work. I tried working around this a variety of ways before punting.
- Pylons - Pylons got support for other templating languages in the middle of the SoC project, so I gave that a try. Routes is definitely a nice URL mapping strategy, but it turned out the support for kid was provided through a Buffet-like interface which meant there were similar kinds of breakage.
- Python Paste + colubrid + kid - as a frameworkless framework, colubrid seemed like an ok middle ground after my failure to reinvent Wareweb in python 2.3. I confess I can't even recall what broke on this approach, but I moved off of it for some reason.
- Python Paste + Wareweb - this is the current contender; it's what's in CVS and what seems to be working.
Kid seems very nice on first blush, and Ryan Tomyako deserves mad props for inventing it, but it has some unfortunate implementation choices and feature limitations that made it painful enough to work with that eventually I moved on
Templates as python modules
I'm beginning to feel that one of the "problems" with python is that the ease of overriding default behaviour leads people to do so when custom behaviour would be more appropriate. One of the ways this shows up in Kid is that every template is also a python module.
This means that there are (at least) three ways to get a kid template:
- Using the import statement, if the import-statement-hack has been turned on.
- Using the kid import function
- Using a lower-level template-loading function.
None of the frameworks I investigated were happy with willy-nilly imports. Pylons horked on even the kid import function, apparently because it clashed with the pre-existing Myghty re-implementation of import. Neither Kid nor Pylons would let me use the low-level template loading function because it wasn't exposed in the Buffet wrapper.
Even if you ignore this problem, the templates-as-modules approach had other problems. I may be incorrect in this assessment, but part of the reason kid couldn't provide meaningful error messages is because the compiled module had 'line numbers' that differed from those in the templates.
Markup to the rescue
Edgewall's Markup proved to be the solution to my dilemma. Largely a reimplementation of kid, Markup corrects the limitations that had me pulling my hair out with kid.
- XInclude instead of py:extends - Markup implements a subset of the XInclude standard in a way that lets me dynamically specify the templates to be included in another template, as opposed to the hardwired py:extends / py:layout commands in kid.
- XPath for matching - Matching in kid and Markup is basically specifying an element that is to be overriden by the markup in your match block. Kid provides a matching algorithm that relies on ElementTree's interface. It's not bad, but it's way more verbose and code-heavy than XPath. XPath is a nice, compact, well-known way to specify which portion of a document you're interested in, and is much better for my purposes. I'm still having trouble with doing dynamic matching, but variable substitution is coming in the next release of Markup, so this should be addressed soon.
- Templates aren't modules - Since the templates aren't compiled to bytecode, and because Markup does much more work to preserve information about where one is in a template, error messages actually tell you what line and file is causing a problem, making debugging templates much easier.
During this project, I had my production server crash hard enough to require the raid array to be rebuilt, key partitions (e.g. /var) to be lossily recovered, and a complete reinstall of the os to recover the files lost in the partition recovery.
I purchased a new server at the beginning of the summer, because I had seen this particular nightmare coming. I've been trying to use it as the development server, but unfortunately I have been experiencing intermittent segfaults and memory corruption. I have finally (fingers crossed) tracked the problem down to the kernel version I was using, so gods willing my new server should be functional now.
I also discovered that the "macs-don't-need-defragmentation" line is really only true if you don't use up all your disk; once you do, the fact that the swap file is dynamically allocated to the largest available contiguous block means you can rapidly find yourself out of swap, which translates to many delightful crashes due to illegal memory accesses. This has meant that even my workstation has been prone to dropping my IDE on the floor when it feels like it.
Because I had so many problems with my development environment, I tried to implement all the templates in a vaccuum. This means that most of the templates exist in the repository, but they don't actually function yet because they haven't been running in an environment. I expect there to be a fair amount of effort left in getting them all plugged in.
I've got a light schedule for classes this upcoming year, and I'm still very enthusiastic about this project, so I intend to continue working on this throughout the year and beyond.