10.3.2 auto proxy configuration


Mac OS X 10.3.2 adds a feature to the Proxies tab of the Network Preferences Pane. This allows you to specify a URL to automatically configure proxies. This URL points to a "PAC" (Proxy Auto Configuration") file. These files are traditionally used Netscape and IE for Windows to configure their proxies. Now that this feature has been added to Mac OS X, Mac OS X applications can take advantage of this feature.

Here's how the configuration option looks:



Currently, it appears that only Safari is aware of this feature, but this was the final hurdle that allowed us to use Safari at Disney. Prior to 10.2.3, Safari had problems navigating our proxies: you could configure Safari to connect to web sites inside our proxy or outside our proxy, but not both simultaneously. Now it is possible to use Safari as a main browser at Disney.

To implement this, we needed not only to update machines to Mac OS X 10.3.2, but also we needed to push out a modification to the Network configurations for each machine so they would use the autoproxy URL.
Network configurations are stored in /Library/Preferences/SystemConfiguration/preferences.plist, or if you've upgraded from Jaguar and have made no changes to your Network configuration, the OS will still reference the "old" location of this data: /private/var/db/SystemConfiguration/preferences.xml.
We do not manage this file with radmind as it varies too much from machine to machine: it contains Network locations and entries for every possible Network interface: Built-in Ethernet, Modem, Airport, even IrDA. So instead this file is part of our standard installed image, but then remains unmanaged. This makes it difficult to update if needed.
The solution was to write a script that edits the file and makes the required changes. This script is then called as part of a custom startup item. The script must parse through the /Library/Preferences/SystemConfiguration/preferences.plist and add the autoproxy configuration info in the correct places. This is no small task. Again, the file can contain multiple network locations and multiple network interfaces. What I decided to do was look for existing proxy information that was Disney-related and make my additions there. That way I could be reasonably certain I was making my additions in the right place. We can be reasonably certain there is existing Disney-related proxy info in the Network configuration or Internet Explorer would not be functional.

Here's the script, though iBlog tends to mangle its formatting, so I've attached a "clean" version as well.

#!/usr/bin/perl

# This script adds the autoProxyConfig information to the Network configuration located at
# /Library/Preferences/SystemConfiguration/preferences.plist
# which is a complicated plist file.
#
# This allows Safari to work in our environment as of OS X 10.3.2.
# If this script did not add the autoProxyConfig info, we'd have to visit each machine one by one.
#
# by Greg Neagle Dec 2003

# change these as needed for your use
$localProxyDomain = ".disney.com";
$autoProxyURL = "http://fawww/auto.proxy";

# if the file /Library/Preferences/SystemConfiguration/.FAautoProxyUpdated exists
# then this script has already done its job and can exit
if (!(-e "/Library/Preferences/SystemConfiguration/.FAautoProxyUpdated")) {

        # if this machine was upgraded from 10.2, it may have the SystemConfiguration preferences in the "old" location
        if (!(-e "/Library/Preferences/SystemConfiguration/preferences.plist")) {
                `cp /private/var/db/SystemConfiguration/preferences.xml /Library/Preferences/SystemConfiguration/preferences.plist` ;
        }

        open SCPREFS, "/Library/Preferences/SystemConfiguration/preferences.plist"
                or die ("Cannot open /Library/Preferences/SystemConfiguration/preferences.plist");

        open SCOUTPUT, ">/Library/Preferences/SystemConfiguration/preferences.new"
                or die ("Cannot open /Library/Preferences/SystemConfiguration/preferences.new for output");

        until (eof SCPREFS) {
                $text = readline(SCPREFS);
                print SCOUTPUT "$text";
                if ($text =~ "<key>Proxies</key>") {
                        # we found a Proxies key
                        $text = readline(SCPREFS);
                        print SCOUTPUT "$text";
                        if ($text =~ "<dict>") {
                                # this line better be the start of a <dict> block
                                $foundLocalProxies = 0;
                                $foundAutoProxies = 0;
                                while (!($text =~ "</dict>")) {
                                        $text = readline(SCPREFS);
                                        if ($text =~ $localProxyDomain) {
                                                $foundLocalProxies = 1;
                                        }
                                        if ($text =~ "<key>ProxyAutoConfigEnable</key>") {
                                                $foundAutoProxies = 1;
                                        }
                                        if ($text =~ "</dict>") {
                                                # we're at the end of the dict block, we should
                                                # write out our additions if needed
                                                if ($foundLocalProxies && !($foundAutoProxies)) {
                                                        print SCOUTPUT "<key>ProxyAutoConfigEnable</key>\n";
                                                        print SCOUTPUT "<integer>1</integer>\n";
                                                        print SCOUTPUT "<key>ProxyAutoConfigURLString</key>\n";
                                                        print SCOUTPUT "<string>$autoProxyURL</string>\n";
                                                }
                                        }
                                        print SCOUTPUT "$text";
                                }
                                # we're at the end of a <dict> block
                        }
                }
        }

        close (SCOUTPUT);
        close (SCPREFS);

        # rename our files
        `mv /Library/Preferences/SystemConfiguration/preferences.plist /Library/Preferences/SystemConfiguration/preferences.old` ;
        `mv /Library/Preferences/SystemConfiguration/preferences.new /Library/Preferences/SystemConfiguration/preferences.plist` ;
        `touch /Library/Preferences/SystemConfiguration/.FAautoProxyUpdated`; #leave our mark

        # reselect the current location so the OS will read our changes
# first we call scutil to get the name of the current location
# then we call scselect and pass it the name of the current location
        # this forces the OS to re-read its Network configuration files
# (because it thinks its changing locations) and thereby picks up
# the changes we wrote to the .plist file
        $currLoc = get_location_from_scutil();
        if ($currLoc ne "") {
                `scselect $currLoc`
        }
}

#END

sub get_location_from_scutil {
    my @scutil = `scutil <<- end_scutil 2> /dev/null
open
show Setup:/
close
end_scutil`;

   my @matches = map { m/UserDefinedName : (.*)/ } @scutil;
    if(@matches == 1) {
        return $matches[0];
    }
    else {
        return "";
    }
}

autoProxyConfig.pl

Posted: Sat - January 17, 2004 at 05:05 PM      


©