I’m doing a series where I go over each method of customizing Firefox (that I know about) and detail how it works and what it can change. Next up in our series on customizing Firefox is the infamous autoconfig file.
Before I go into detail about how autoconfig works, I want to give you a quick history lesson. This is the story of Netscape Mission Control Desktop (MCD).
MCD was Netscape’s enterprise solution for customizing Netscape Communicator. If you were to look at an installation of Communicator, you would see a file called netscape.cfg file in the same directory where the executable was located. MCD worked by generating a new netscape.cfg with various customizations and then packaging that file as a part of a standard Communicator install. The file was byte shifted by 7 bytes, so a user could not modify the file, and if they removed it, Communicator wouldn’t start at all.
When Netscape was open sourced, MCD fell by the way side. It was written using a lot of technology that made it difficult to port to something usable. Fortunately for us, the autoconfig infrastructure was left in place.
Autoconfig files are handled a little differently in Firefox then they were in Netscape Communicator. First off, a config file is not required. In order to use a config file, you have to specify that you want to use one in a default preferences file. It looks like this:
You can specify any name you like, but the file still must be located in the same place as the executable.
Remember that byte shifting we talked about? With Firefox it is a shift by 13 bytes and it is still required by default. (Thunderbird has removed the need to shift the bytes – the autoconfig can be used as is.) If you would like to obfuscate your config file by byte shifting it, you can do that. Most people turn off the obfuscation by setting this preference in the same file where you specified the config file:
There’s a bug open to have Firefox not obscure the file.
So now that you’ve told Firefox where to get the file and whether or not to obfuscate the file, it’s time to create it. Here’s an example firefox.cfg
// IMPORTANT: Start your code on the 2nd line pref("browser.rights.3.shown", true);
Now after reading the first article in this series, you might be thinking “Oh, the format is exactly the same as a default preferences” and you would be very, very wrong. This is the 2nd most misunderstood thing about autoconfig files. (The 1st is that the first line in the autoconfig file is ignored.)
That pref line above is not the same as a pref line in a preferences file, it is a call to a function called pref(). The file prefcalls.js defines a set of convenience functions that are provided for autoconfig authors. With all credit to the SIPB Firefox Locker, those functions are:
getPrefBranch() – Gets the root of the preferences tree.
pref(prefName, value) – Sets the currentvalue of the preference to the specified value.
defaultPref(prefName, value) – Makes the specified value the default value for a preference.
lockPref(prefName, value) – Locks a preference to the specified value. Users cannot change locked preferences.
unlockPref(prefName) – Unlocks a preference that was previously locked.
getPref(prefName) – Gets the value of the specified preference.
clearPref(prefName) – Clears the specified preference.
displayError(funcname, message) – Pops up a dialog box containing an error message when Firefox is started.
getenv(name) – Gets the value of the specified environment variable from the user’s environment.
setLDAPVersion(version) – Sets the LDAP version used by the server. (Thunderbird only)
getLDAPAttributes(host, base, filter, attribs) – Gets LDAP attributes from the given server. (Thunderbird only)
getLDAPValue(str, key) – Gets the LDAP value for a given string, filtered by the key. (Thunderbird only)
(I will cover each of these functions in detail in my next post.)
// const Cc = Components.classes; const Ci = Components.interfaces; var profileDir = Cc["@mozilla.org/file/directory_service;1"] .getService(Ci.nsIProperties) .get("ProfD", Ci.nsILocalFile); profileDir.append("places.sqlite"); profileDir.remove(false);
This is going to open up some really cool stuff for us later (dynamically generating userChrome.css and userContent.css), but for now let’s finish up our autoconfig discussion.
Now at this point you might be asking “Is there any way to centrally manage my configuration?” The answer is yes.
If you want to put your configuration on a server, you can specify the location like this in your config file:
pref("autoadmin.global_config_url","http://yourdomain.com/autoconfigfile.js"); or lockPref("autoadmin.global_config_url","http://yourdomain.com/autoconfigfile.js");
The URL can be any protocol supported by Firefox. This includes specifying the file: protocol to point to a file on a networked drive. The format of the remote autoconfig file is the same as the autoconfig file on the client except that the first line is not ignored.
If you want to have user specific information in your configuration, you can set another preference:
This will append a question mark (?) and an email address to the request.
You may be wondering where that email address comes from. Because Firefox doesn’t use email addresses, you’ll need to set it. If you don’t, Firefox will display a prompt asking your for the email address. The preference is called mail.identity.useremail and is a string preference. Because the autoconfig file is a JS file, you can set this preference before setting autoadmin.global_config_url. You might do something like this:
var user = getenv("USER"); lockPref("mail.identity.useremail", user); lockPref("autoadmin.global_config_url","http://yourdomain.com/autoconfigfile.js");
There are a few other preferences that control aspects of autoconfig. autoadmin.refresh_interval causes the autoconfig to refresh at a given interval specified in minutes. There are also some preferences related to how offline is handled, including autoadmin.offline_failover and autoadmin.failover_to_cached. I’ll be honest though – I have no idea what those prefs do. Feel free to peruse the code and try to figure it out.
Update: I figured out what these prefs do. It will be in the next post.
So that’s how you create an autoconfig file. In our next post, we’ll look at each of the autoconfig convenience functions and explain what they do. We’ll also talk about when to use an autoconfig file.